最近學習了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語言的菜鳥我
感覺你的問題僅是不熟悉 C 的字串處理而已,這一塊多加練習就好了@@
如果交易碼的位置與長度都是固定的,可以這樣做:
1. 收到 ServerMsg,從固定位置取得交易碼並存放在 buffer。 (for-loop)
2. 回覆 Server 之前,Client 將 buffer 的訊息 copy 到 send buffer 就好了。 (strcpy()
)
然後推薦幾個不錯的資源:
可以拿這裡的範例去改比較容易
上圖是我改的結果(左邊是 client, 右邊是 server)
1.發送訊息順序是由 client 先開始
2.加上訊息交易碼設定部份