【网络编程】网络编程的坑

阻塞IO的echo服务

  假设这样一个简单的echo场景:客户端向服务端发送20M的数据,发送完之后接收数据,而服务端每次接收4k数据,接受完全部数据之后进行回显。这样的客户端和服务端程序启动之后,会意外的阻塞。阻塞的点在哪里呢
  因为客户端发送完数据之后才会进行接收数据,而服务端接收到了4k数据之后就会进行回显,这时服务端发送到客户端的内核缓冲区中,注意这时客户端并没有读取数据,所以客户端的接收缓冲区中的数据一直积累,直到积累到某个阈值,此时服务端的tcp advertised window大小为0,tcp不能发送数据,结果就是服务端阻塞在发送。此时客户端仍然在一直的发送数据,但这个时候服务端是没有进行读取数据的,直到服务端的缓冲区也满,最后客户端也阻塞在发送。导致双方都阻塞在发送数据。
  那么怎样解决这个问题呢。其实只要服务端每次把数据全部读取进来,然后进行发送即可。全部读取之后,客户就开始接收数据,此时服务端发送数据就不会造成客户端的缓冲区满,服务端也就不会阻塞在发送数据。

tcp的自连接

  首先,自连接只会发生在本机。如果本机向localhost 10023端口发起一个连接,而发起连接时随机得到的端口号和正好就是10023端口,那么此时就会形成一个自连接。自连接形成的原因是当发起连接的ip:port被选定时,内核中就会保存这个ip:port,当接收连接时,内核会发现已经有这个ip:port的记录,那么就会连接成功,在不同的主机上的表现其实是一个同时打开连接的场景。
  如何避免自连接呢,只需要在连接成功后判断一下local地址(getsockname)和对端地址(getpeername)是否相同即可。

SIGPIPE信号

SIGPIPE默认结束进程
如何忽略SIGPIPE:
见这篇文章
忽略掉SIGPIPE信号后,需要检查printf的返回值。

TCP不可靠?

关于TCP_NODELAY

  对于wrie->write->read场景来说,nagle算法会把第二个write的时间延迟1个RTT,解决方法是应用层准备一个buffer,把所有的数据写入buffer后,再一次发送,变为write->read。
  但即使准备了应用层缓冲,也没有完全解决问题。如果一个连接上有多个请求,你需要把多个请求一次性计算完存入buffer,才能做到write->read,但这样对于第一个请求的延迟就会增大。
  最好的解决方法是禁用nagle算法,在tcp选项中设置TCP_NODELAY。

为什么IO mutiplexing要搭配非阻塞IO

  man select中讲到,select可读可能会有虚假唤醒的情况,因为如果可能有数据到来,但是checksum检查失败,内核就会丢弃数据,这时就不会真正有数据可读。

非阻塞IO和short write

非阻塞IO和高低水位

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值