2016-12-03 84 views
0

我正在阅读一个套接字,但我不知道有多少元素将到达,因此如果服务器已将所有元素结构数组。如何从recv调用中退出

客户

for(;;){ 
    ... 
    if(strcmp(buf,"!who")==0){ 
     while(recv(sd,name,50,0)>0) 
     { 

      printf("%s\n",name); 

     } 
     continue; 
    } 
} 

服务器

while(recv(sock,msg,1024,0)>0){ 

    if(strcmp(msg,"!who")==0){ 
     if(i==0){ 
       strcpy(msg2,"Nessun giocatore collegato."); 
       write(sock,msg2,strlen(msg2)); 
     } 
     else 
      for(int c=0;c<=i;c++) 
       write(sock,players[c].name,strlen(players[c].name)); 

    } 

} 
+0

让您的服务器首先发送一个(固定长度)指示它计划下一次发送多少字节。客户端可以先读取该指标(因为指标是固定长度,客户端知道recv()需要读取多少字节),然后一旦获得该信息,客户端就会知道要读取多少字节接收数组的所有元素 –

回答

1

我不知道有多少元素将抵达

你必须知道。你有3个选项:

  1. 发件人用数字前缀数据,告诉接收者多少期望。
  2. 发件人用某种“完成”标记结束数据。在你的情况下,一个0会做(表明一个零长度的名字)。
  3. 发送方关闭连接,接收方看到EOF

我会改变协议发送strlen首先,然后名称。

还要注意TCP没有消息边界。 recv(2)返回字节,其中是任何方便的内核。如果呼叫被信号中断,或者内部缓冲区无法容纳发送者的输出,则N将小于发送的值,并且接下来的recv将获得更多(可能全部)。

正如你写的,你的代码检索一个名字,后面跟着它的长度。但是不能保证收到的最后一个字节是长度;如果更多的数据正在等待处理,他们将只是名称的一部分。