write()系统调用是否会阻止进一步操作,直到涉及read(),反之亦然?

时间:2016-10-27 15:11:48

标签: networking system-calls

作为TCP / IP客户端 - 服务器的一部分编写:

服务器:

write(nfds,data1,sizeof(data1));
usleep(1000);
write(nfds,data2,sizeof(data2));

客户端:

read(fds,s,sizeof(s));
printf("%s",s);
read(fds,s,sizeof(s));
printf("%s",s);

usleep(1000)的两次调用之间没有write(),客户端打印data1两次。这是为什么?

背景:

我正在做一个客户端 - 服务器程序,服务器必须通过网络(套接字)在获取后发送两条连续的信息; nfds是我们从accept()获取的文件描述符。 在客户端,我们通过read收到这些信息;这里fds是通过socket()获得的文件描述符。

我的问题是,当我在usleep(1000)函数之间不使用write()时,客户端只打印data1表示的信息两次,而不是打印data1然后再打印data2。当我放入usleep()它没关系。究竟为什么会发生这种情况? write()阻塞操作直到读取缓冲区或read()阻塞操作直到将信息写入缓冲区?还是我完全不在页面上?

1 个答案:

答案 0 :(得分:0)

你做了几个错误的假设。 TCP中没有任何内容可以保证一个发送等于一个接收。在两端都有很多缓冲,并且在发送到合并数据包时会有故意的延迟(Nagle算法)。当您致电read()recv()和朋友时,您需要将结果存储到变量中并针对以下每种情况进行检查:

  • -1:错误:检查/记录/打印errnostrerror(),或致电perror(),并且在大多数情况下关闭套接字并退出读取循环。
  • 0:流结束;业主已关闭连接;关闭套接字并退出读取循环。
  • 正值但低于您的预期:继续阅读并累积数据,直到您拥有所需的一切。
  • 一个超出预期的正值:处理您期望的数据,并保存下一次的其余数据。
  • 正是您的期望:处理数据,丢弃所有数据,然后重复。这不是一个简单的案例,而且很少见,但它是您目前正在编程的唯一案例。

不要将睡眠添加到网络代码中。它不能解决问题,只能延迟它们。