iT邦幫忙

0

C語言 Client接收到訊息內容後,修改訊息內容傳回Server

最近學習了C的 QueueMessage 與Socket
對於字串的接收以及回復還不是很熟悉

假如有一個情境,我Client端連到了Server端
而Server端會發給我一串字串訊息
先假設這交易碼為 123456(隨機碼)固定六位數
server這串字串為 0115123456abcd
而client要讀取server字串中其中的交易碼後
將交易碼複製到字串訊息到相同位置並發回給server端
所以client端即將發送字串為0115123456efgi
該怎麼做比較好呢?

以下為簡易的Server Client端互連程式
Server

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

int main(void)
{
    int iSockfd;
    int i,j;
    if((iSockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    {
        perror("Create Socket Error");
        return -1;
    }

    struct sockaddr_in sInfo;
    bzero(&sInfo,sizeof(sInfo));
    sInfo.sin_family=AF_INET;
    sInfo.sin_addr.s_addr=inet_addr("0.0.0.0");
    sInfo.sin_port=htons(2576);

    bind(iSockfd,(struct sockaddr *)&sInfo,sizeof(sInfo));
    listen(iSockfd,1);

    int iClientSockfd;
    struct sockaddr_in sClientInfo;
    int iClientAddrlen = sizeof(sClientInfo);

    //accept connect
    if((iClientSockfd=accept(iSockfd,(struct sockaddr*)&sClientInfo,&iClientAddrlen))==-1)
    {
        perror("Accept Error");
        return -1;
    }
    close(iSockfd);
    u_char cReceivebuf[100];
    u_char cRecvMsgbuf[100];
    u_char cMsgbuf[100];
    u_char cSendbuf[100];
    //int iRecvlen;

    //wait for receive
    int iRet;
    iRet=recv(iClientSockfd,cReceivebuf,sizeof(cReceivebuf),0);
    if(iRet==0)
    {
        printf("Connect Shutdown\n");
        return 0;
    }
    else if(iRet==-1)
    {
        perror("Recv error ");
        return -1;
    }
    //receive
    int iRecvMsglen=(cReceivebuf[0]<<8)+cReceivebuf[1]; //Msg length
    cReceivebuf[0]=cReceivebuf[1]='0';
    //printf("strlen(cReceivebuf) : %d\n",strlen(cReceivebuf));
    //printf("%d %d\n",cReceivebuf[0],cReceivebuf[1]);
    //printf("RecvMsglen : %d\n",iRecvMsglen);
    i=2;
    j=0;
    int iReadlen=0;
    while(1)
    {
        if(cReceivebuf[i]=='\0')
        {
            //printf("i==cReceivebuflen\n");
            iReadlen+=i;
            if(iReadlen==iRecvMsglen+2)
                break;
            else
            {
                iRet=recv(iClientSockfd,cReceivebuf,sizeof(cReceivebuf),0);
                if(iRet==0)
                {
                    printf("Connect Shutdown\n");
                    return 0;
                }
                else if(iRet==-1)
                {
                    perror("Recv error");
                    return -1;
                }
                i=0;
            }
        }
        cRecvMsgbuf[j]=cReceivebuf[i];
        i++;
        j++;
    }
    cRecvMsgbuf[j]='\0';
    printf("Server receive : %s\n", cRecvMsgbuf);

    //send
    sprintf(cMsgbuf, "SERVER Hello 1101201");
    i=strlen(cRecvMsgbuf)-4;
    j=strlen(cMsgbuf);
    while(i<strlen(cRecvMsgbuf))
    {
        cMsgbuf[j]=cRecvMsgbuf[i];
        i++;
        j++;
    }
    cMsgbuf[j]='\0';
    sprintf(cSendbuf,"00%s",cMsgbuf);
    cSendbuf[0]=(strlen(cMsgbuf)>>8&0)&0xff;
    cSendbuf[1]=strlen(cMsgbuf)&0xff;
    //printf("Server Send : %s\n", cSendbuf);
    send(iClientSockfd,cSendbuf, sizeof(cSendbuf),0);

    close(iClientSockfd);

    return 0;
}

Client端

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>

int main(void)
{
    int iSockfd;
    int i,j;
    srand(time(NULL));
    if((iSockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    {
        perror("Create Socket Error");
        return -1;
    }

    struct sockaddr_in sInfo;
    bzero(&sInfo,sizeof(sInfo));
    sInfo.sin_family=AF_INET;
    sInfo.sin_addr.s_addr=inet_addr("0.0.0.0");
    sInfo.sin_port=htons(2576);

    if(connect(iSockfd,(struct sockaddr *)&sInfo,sizeof(sInfo))==-1)
    {
        perror("Connection Error");
        return -1;
    }

    u_char cMsgbuf[100];
    u_char cSendbuf[100];
    u_char cReceivebuf[100];
    u_char cRecvMesgbuf[100];

    sprintf(cMsgbuf,"CLIENT Hello 1101201 ", rand()%1000);
    //sprintf(cSendbuf,"00%s" ,cMsgbuf);
    cSendbuf[0]=(strlen(cMsgbuf)>>8)&0xff;
    cSendbuf[1]=strlen(cMsgbuf)&0xff;
    i=0;
    j=2;
    while(i<10)
    {

        cSendbuf[j]=cMsgbuf[i];
        i++;
        j++;
    }
    send(iSockfd,cSendbuf,sizeof(cSendbuf),0);
    j=0;
    sleep(2);
    while(i<strlen(cMsgbuf))
    {
        
        cSendbuf[j]=cMsgbuf[i];
        i++;
        j++;
    }
    send(iSockfd, cSendbuf,sizeof(cSendbuf),0);

    //wait for receiv
    int iRet;
    iRet=recv(iSockfd,cReceivebuf,sizeof(cReceivebuf),0);
    if(iRet==0)
    {
        printf("Errno : %s\n", strerror(errno));
        close(iSockfd);
        return 0;
    }
    else if(iRet==-1)
    {
        printf("Errno :%s\n" ,strerror(errno));
        close(iSockfd);
        return 0;
    }
    int iRecvMsglen=(cReceivebuf[0]<<8)+cReceivebuf[1]; //Msg length
    i=2;
    j=0;
    int iReadlen=0;
    while(1)
    {
        if(cReceivebuf[i]=='\0')
        {
            iReadlen+=i;
            if(iReadlen==iRecvMsglen+2)
                break;
            else
            {
                iRet=recv(iSockfd,cReceivebuf,sizeof(cReceivebuf),0);
                if(iRet==0)
                {
                    printf("Connect Shutdown\n");
                    break;
                }
                else if(iRet==-1)
                {
                    printf("Errno : %s\n", strerror(errno));
                    break;
                }
                i=0;
            }
        }
        cRecvMesgbuf[j]=cReceivebuf[i];
        i++;
        j++;
    }
    cRecvMesgbuf[j]='\0';
    printf("Client Receive : %s\n" ,cRecvMesgbuf);

    close(iSockfd);

    return 0;
}

大家可以玩玩看,順邊解救一下C語言的菜鳥我

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

0
EN
iT邦好手 1 級 ‧ 2022-01-16 15:23:49

感覺你的問題僅是不熟悉 C 的字串處理而已,這一塊多加練習就好了@@
如果交易碼的位置與長度都是固定的,可以這樣做:
1. 收到 ServerMsg,從固定位置取得交易碼並存放在 buffer。 (for-loop)
2. 回覆 Server 之前,Client 將 buffer 的訊息 copy 到 send buffer 就好了。 (strcpy())

然後推薦幾個不錯的資源:

1
海綿寶寶
iT邦大神 1 級 ‧ 2022-01-17 12:00:42

可以拿這裡的範例去改比較容易

https://ithelp.ithome.com.tw/upload/images/20220117/20001787bC6DixRUEs.png

上圖是我改的結果(左邊是 client, 右邊是 server)
1.發送訊息順序是由 client 先開始
2.加上訊息交易碼設定部份

我要發表回答

立即登入回答