最近我通过尝试制作客户端/服务器程序来搞乱一些套接字。到目前为止,我已经取得了成功,但似乎我遇到了障碍。对于一些快速的背景信息,我创建了一个可以接受连接的服务器,一旦完成所有设置并建立了与客户端的连接,这段代码就开始了:
while(1){
read(newsockfd, &inbuffer, 256);
std::cout << "Message from client " << inet_ntoa(cli_addr.sin_addr) << " : ";
for(int i = 0; i < sizeof(inbuffer); i++){
std::cout << inbuffer[i];
}
std::cout << std::endl;
}
现在客户端在执行时只是连接到服务器并写入套接字,然后退出。因此,由于发送了一条消息,此循环应该只运行一次,然后等待另一条消息,如果我读的是正确的。
但最终发生的事情是这个循环一遍又一遍地重复打印相同的消息。从我(在这个网站和其他网站上)读到的关于read()函数的内容是,在调用一次后,它等待收到另一条消息。我可能在这里犯了一个愚蠢的错误,但有没有办法我可以让这个read()函数等待一条新消息,而不是一遍又一遍地使用相同的旧消息?或者是否有另一个函数可以替换read()来执行我想要的操作?
感谢您的帮助。
答案 0 :(得分:1)
您无法检查read
的返回值。因此,如果另一端关闭连接或出现错误,您只需循环输出发生在缓冲区中的任何内容。你可能想要:
while(1){
int msglen = read(newsockfd, &inbuffer, 256);
if (msglen <= 0) break;
std::cout << "Data from client " << inet_ntoa(cli_addr.sin_addr) << " : ";
for(int i = 0; i < msglen; i++){
std::cout << inbuffer[i];
}
std::cout << std::endl;
}
请注意,我更改了单词&#34; message&#34;到&#34;数据&#34;。这就是原因:
因此,由于发送了一条消息,因此该循环应该只运行一次,然后等待另一条消息,如果我读的是正确的。
这是不正确的。上面的代码没有任何&#34;消息&#34;的概念,并且TCP不保留应用程序消息边界。所以这不仅是错误的,因为“#34; message&#34;”这个词并不是正确的。没有任何意义可能适用于这种情况。 TCP没有&#34;粘在一起&#34;发生在一次调用中传递给发送函数的字节。