C - 大约30次读取后无法读取套接字

时间:2015-03-06 21:33:19

标签: c sockets

所以我有两个进程,一个客户端进程一个服务器进程。用户可以向客户端发出命令,当用户输入命令时,客户端将命令长度发送给服务器,之后它将发送实际命令。

然后服务器首先发回响应的长度,然后发送响应。

我可以完成5-30个命令,但没有任何问题,但是在某些时候它无法读取足够的字节,尽管收到了正确的响应大小。

服务器按以下方式发送响应:

 str[0] = '\0';
 unsigned long int totalSize = 0;
 while ((fgets(outBuf, MAXOUTPUT, myFile)) != NULL)
 {
    strcat(str, outBuf);
 }
uint32_t *un = 0;
totalSize = strlen(str);
*un = htonl(totalSize); 
result= send(clientFD, un, sizeof(uint32_t), 0);
if(result < 1)
{
    printf("Failed sending message size to client");
    exit(-1);
}
while(token != NULL)
{
    size_t length = strlen(token);
    token[length] = '\n';
    write(clientFD, token, length + 1);
    token = strtok(NULL, "\n");
}

客户端已正确收到消息长度(通过打印验证)并以这种方式读取响应:

result = read(socketFD, recvBuf, bufferlen); //bufferlen is response size
if(result < bufferlen)
{
      perror("read()");
      exit(-1);
}

我已经验证客户端每次都会收到正确的消息长度,包括最后一个无法读取的消息长度。

所以我的问题是:我的阅读有时可能无法检索到完整的回复?它通常在执行大约5-30个命令之后发生,并且返回的perror是错误0(也就是没有找到错误)。

作为补充说明,测试的命令是

ls -la,ls -l,ls。 我没有找到一个命令导致崩溃的模式,但我已将它们组合在一起。

另外:客户端和服务器都是32位,并且在本地同一台机器上运行。

2 个答案:

答案 0 :(得分:1)

read()(特别是在套接字上)只要某些数据可用就会返回,它可能总是返回 less 字节而不是您要求的字节。在这种情况下,您需要重复读取,直到您已经读取了足够的数据:

size_t bytes_read = 0;
while (bytes_read < bufferlen) {
    result = read(socketFD, recvBuf + bytes_read, bufferlen - bytes_read);
    if (result < 0) {
        perror("read()");
        exit(-1);
    }
    bytes_read += result;    
}

答案 1 :(得分:0)

TCP套接字适用于字节流概念。服务器正在向字节流添加字节,客户端正在使用它们。套接字不需要一次发送所有字节;它最终将发送给他们,他们将在另一端按顺序阅读。邮件不保证是完整的。当您可以阅读bufferlen字段但是尚未到达整个相应的消息时,您会遇到问题。

您的客户端需要继续读取套接字,直到读取bufferlen个字节为止。

另请注意,阅读bufferlen字段的行为也可能需要多次读取才能完成。