C unix socket编程read()问题

pan*_*ter 0 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;
}
Run Code Online (Sandbox Code Playgroud)

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

int byteCount = read(hSocket, pBuffer, BUFFER_SIZE);
printf("Read %d bytes from client", byteCount);
Run Code Online (Sandbox Code Playgroud)

用于代替第一个代码段的上述代码将打印"从客户端读取6个字节"并继续正常工作,但如果仅读取5个字节,则不保证我已收到每个字节.

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

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

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

Ern*_*ill 6

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

阅读下面的评论并查看你的代码,我很困惑,因为是的,这就是你想要做的.但后来我看了非常密切的你的代码:

read(hSocket, pos, BUFFER_SIZE - (pos-pBuffer)>0)){
                                              ^
                                              |
                                THIS ---------|
Run Code Online (Sandbox Code Playgroud)

那个"> 0" 包含read的参数的括号内,而不在外面; 这意味着它是参数的一部分!实际上,你的最后一个论点被解释为

(BUFFER_SIZE - (pos-pBuffer)) > 0
Run Code Online (Sandbox Code Playgroud)

它是1,直到结束,当它变为0.