socket TCP:为什么我使用scanf丢失消息

时间:2017-01-01 10:45:28

标签: c linux sockets tcp scanf

我在Mac OS中用c创建了一个服务器和一个客户端 他们做的很简单:服务器发送消息,客户端接收消息 但是我不知道为什么,但是当我在scanf的帮助下输入多条消息时,我总是丢失一些消息。
这是主要代码:

// client
char msg[200];
while(1)
{
    if(read(sockclient, msg, sizeof(msg)) <= 0)
    {
        break;
    }
    printf("Message recu: %s\n", msg);
    bzero(msg, 200);
}


// server
while(1)
{
    lg=sizeof(coord_client);
    newsockfd=accept(sockserveur,(struct sockaddr*)&coord_client,(socklen_t *)&lg);
    char msg2[100];
    while(1)
    {
        scanf("%s",msg2);
        write(newsockfd,msg2,sizeof(msg2));
        printf("message envoye\n");
        bzero(msg2, sizeof(msg2));
    }
}


问题是:如果我逐个输入消息,例如a<Enter>b<Enter>,一切都很好。但是,如果我一次输入多条消息,我将永远丢失其中的一些消息。例如,如果我输入a b c d<Enter>,表示我要发送四条消息:abcd,则客户端始终可以获取其中三个,c是错过的​​。但服务器确实发送了四次,因为我得到了四个message envoye

修改
我检查了函数read的返回值,得到了一些我不明白的东西。 enter image description here

请注意:当read返回200而不是100时,客户端将丢失以下消息。

1 个答案:

答案 0 :(得分:3)

嗯,你读取200个字节很简单,但你写了100个字节。有时在客户端读取之前有两次写入。所以它连续读了两条消息。

char msg[101];
size_t i = 0;
ssize_t ret;
while (i < 100 && (ret = read(sockclient, msg + i, sizeof msg - i - 1)) <= 0)
{
  i += (size_t)ret;
}
if (i == 100) {
  msg[100] = '\0';
  printf("Message recu: %s\n", msg);
}