我已经创建了一个简单的tcp服务器/客户端应用程序,客户端将某些内容写入服务器,然后将其回送给客户端。但是,当我试图阅读服务器在客户端回复的内容时,我遇到了一些问题。
string s;
while((n = read(socketFD[0],readBuf, BUFFER_SIZE)) > 0){
cout<<"\nBytes read: "<<n<<endl;
s.append(readBuf, n);
}
cout<<"\nTest after read\n";
我将16 KB的文本写入服务器。当我在客户端阅读时,我一次读取4 KB。
此代码的输出为:
Bytes read: 4096
Bytes read: 4096
Bytes read: 4096
Bytes read: 4046
读取调用似乎在从套接字读取后阻塞,并且永远不会离开循环。我该如何解决这个问题?
编辑:这是处理连接客户端的服务器中的代码。
if((childpid = fork()) == 0){
close(listenFD);
while ((n = read(connectFD, buf, BUFFSIZE)) > 0){
cout<<"\nBytes read: "<<n<<endl;
write(connectFD, buf, n);
}
cout<<"\nTest after read\n";
exit(0);
}
此输出为:
Bytes read: 4096
Bytes read: 4096
Bytes read: 4096
Bytes read: 4046
Test after read
与客户端中的代码相比,这里有什么不同?为什么读取调用不像客户端那样阻塞?
答案 0 :(得分:0)
答案 1 :(得分:0)
读取调用似乎在从套接字读取后阻塞,并且永远不会离开循环。我该如何解决这个问题?
简短回答,请勿在收到所有数据后致电read
。
编写代码以检测您何时收到了您想要接收的所有数据,如果是,则退出循环。你必须实际实现某种协议。
s+=readBuf;
这不可能是正确的。它如何知道要添加到s
的数据字节数?
答案 2 :(得分:0)
这是Python中对套接字的一个非常好的介绍的摘录。这是Python,是的,但它暴露了C-Socket API,所以在你的上下文中写的也是如此。您可以在此处阅读:http://docs.python.org/dev/howto/sockets.html
关于“使用套接字”的部分可以准确地告诉您正在观察的问题。它讨论了recv
函数,但转换为文件描述符上的read
函数。
但是如果您计划重新使用套接字进行进一步传输,则需要意识到套接字上没有EOT。我再说一遍:如果在处理0字节后套接字send或recv返回,则连接已断开。如果连接没有被破坏,你可以永远等待一个recv,因为套接字不会告诉你没有什么可读的(现在)。现在,如果你仔细考虑一下,你就会发现套接字的一个基本事实:消息必须是固定长度(yuck),或者是分隔(耸肩),或者指示它们有多长(更好),或者通过关闭连接来结束。选择完全属于你,(但有些方式比其他方式更严格)。