所以我有两个进程,一个客户端进程一个服务器进程。用户可以向客户端发出命令,当用户输入命令时,客户端将命令长度发送给服务器,之后它将发送实际命令。
然后服务器首先发回响应的长度,然后发送响应。
我可以完成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位,并且在本地同一台机器上运行。
答案 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
字段的行为也可能需要多次读取才能完成。