C unix socket编程read()问题

时间:2012-01-17 03:48:37

标签: c sockets network-programming

我正在使用C来实现客户端服务器应用程序。客户端将信息发送到服务器,服务器使用它来发回信息。我目前正在编写代码来处理数据接收,以确保所有数据都被接收。

在显示一些代码后,我最好解释了我遇到的问题:

int totalRead = 0;
char *pos = pBuffer;
while(totalRead < 6){
if(int byteCount = read(hSocket, pos, BUFFER_SIZE - (pos-pBuffer)>0)){
    printf("Read %d bytes from client\n", byteCount);
    pos += byteCount;
    totalRead += byteCount;
    }else return -1;
}

上面的代码在服务器端运行,将打印出“从客户端读取1个字节”6次,程序将继续正常工作。我在这里硬编码6知道我从客户端写了6个字节,但我会让我的协议要求发送的第一个字节是缓冲区其余部分的长度。

int byteCount = read(hSocket, pBuffer, BUFFER_SIZE);
printf("Read %d bytes from client", byteCount);

上面用于代替第一个代码段的代码将打印“从客户端读取6个字节”并继续正常工作,但如果只读取了5个字节,则不能保证我已收到每个字节。 / p>

任何人都可以向我解释为什么会发生这种情况并提供可能的解决方案吗?我想第一种方法确保所有字节都被传递,但一次读取一个字节似乎效率低......

哦,这是在一个分叉的子进程中发生的,我正在使用tcp / ip。

注意:我的目标是成功实现第一个代码段,以便确保我正在读取所有字节,但我无法正确实现它。

2 个答案:

答案 0 :(得分:6)

基本上,正确的方法是将两个代码段组合在一起。做第一个,但不要一次只读一个字节;询问你期望的所有字节。但请查看bytesRead,如果它低于预期,请调整目标指针,调整预期的读数,然后再次调用read()。这就是它的工作原理:有时你期望的数据是分组的,并不是同时可用的。

在下面阅读你的评论并查看你的代码,我很困惑,因为是的,这就是你想要做的。但后来我在你的代码中非常仔细地看了

read(hSocket, pos, BUFFER_SIZE - (pos-pBuffer)>0)){
                                              ^
                                              |
                                THIS ---------|

“&gt; 0”是里面括起来读取参数的括号,而不是外部;这意味着它是参数的一部分!实际上,您的最后一个参数被解释为

(BUFFER_SIZE - (pos-pBuffer)) > 0

为1,直到结束,当它变为0时。

答案 1 :(得分:0)

您的代码不太正确。 readwrite可能无法读取或写入您应该要求的数据总量。相反,您应该在每次调用后提前读取或写入指针,并计算您在传输中提交的剩余字节数。

如果您从readwrite获得否定结果,则表示您收到了错误消息。零表示传输已完成(没有更多字节要发送),任何高于零的数字表示最后一次调用readwrite时发送的字节数。