如何退出recv电话

时间:2016-12-03 15:12:03

标签: c sockets

我正在从一个套接字读取,但我不知道有多少元素会到达,所以如果服务器已经编写了struct array的所有元素,那么我的套接字仍然会停留在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));

    }

}

1 个答案:

答案 0 :(得分:1)

  

我不知道会有多少元素到达

你必须知道。您有3个选择:

  1. 发件人为数据添加一个计数前缀,告诉接收者预计会有多少。
  2. 发件人用某种&#34;完成&#34;来结束数据。标记。在您的情况下,0会执行(表示零长度名称)。
  3. 发件人关闭连接,接收者看到EOF
  4. 我会先将协议更改为strlen,然后再输入名称。

    另请注意,TCP没有消息边界。 recv (2)返回 N 个字节,其中 N 是方便内核的任何内容。如果呼叫被信号中断,或者内部缓冲区无法容纳发送方的输出,则 N 将小于发送的内容,下一个recv将得到更多(也许全部)。

    如上所述,您的代码将检索名称,后跟其长度。但无法保证收到的最后字节构成长度;如果有更多数据待处理,它们将只是名称的一部分。