2012-01-17 17 views
0

我使用C来实现客户端服务器应用程序。客户端向服务器发送信息,服务器使用它发回信息。我目前正在编写处理数据接收的代码,以确保它实际上已经收到。C unix套接字编程读取()问题

我遇到的问题表现出一些代码后,最好的解释:

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人读它并不能保证我收到的每个字节例如。

任何人都可以向我解释为什么会发生这种情况和一个可能的解决方案?我猜第一种方法确保所有字节正在交付,但它看起来效率低下一次读取一个字节...

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

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

+0

您的协议还应该包含一些长度或内容分隔符,以便让对方知道应该何时停止接收数据(类似于HTTP中的“Content-Length”或分块编码)。请参阅http://stackoverflow.com/a/6404085/372643 – Bruno 2012-01-17 15:08:17

回答

6

基本上这样做的正确方法是你的两个代码片段的混合。做第一个,但不要一次只读一个字节;请求你所期望的所有字节。但看看bytesRead,如果它比预期的要小,请调整目的地指针,调整预期的读数,然后再次拨打read()。这就是它的工作原理:有时候你期望的数据会被分割成不同的数据包,并不是同时可用。

读下面的评论,看看你的代码,我很困惑,因为是的,那就是你想要做的。但后来我看了密切你的代码:

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

那“> 0”是封闭读的论点,不是外面的括号;这意味着它是参数的一部分!事实上,你的最后一个参数被解释为

(BUFFER_SIZE - (pos-pBuffer)) > 0 

为1,直到最后,当它变为0

+0

是的!这就是我一直在尝试做的事情,但问题是我无法弄清楚如何不一次只请求字节。我假设上面的第一个代码段是要求所有的字节。在第一种情况下,如果我使用read(socket,pos,BUFFER_SIZE - (pos-pBuffer)),它不会尝试读取整个事情,因为(pos-pBuffer)= 0,所以我的第三个参数是整个缓冲区大小? – pandaEater 2012-01-17 04:00:32

+0

看我的编辑。请不要伤害你的额头撞在你的桌子上。 – 2012-01-17 04:08:20

+0

伤害......太浪费时间了。但非常感谢您的帮助! – pandaEater 2012-01-17 04:11:39

0

您的代码是不完全正确。 readwrite可能不会读取或写入您请求的数据总量。相反,您应该在每次调用之后提前读取或写入指针,并计算您在传输中剩下的剩余字节数。

如果您从readwrite中收回负值,则表示您收到错误消息。零表示传输已完成(没有更多字节要发送),而任何大于零的数字表示在最后一次调用readwrite时发送的字节数。

+0

你能告诉我一些正确的代码示例吗?我的第一个代码段试图做你正在解释的内容,但我无法正常工作。 – pandaEater 2012-01-17 04:09:19