posix API与网络协议栈的实现原理
server : 1.socket 2.bind 3.listen 4.accept 5.recv 6.send 7.close
client : 1. socket 2.bind(optional) 3.connect 4.send 5.recv 6.close
首次使用 int fd = socket(),这个fd是等于3的,因为前三个fd被系统占用了,使用命令:
ls -l /dev/std* //查看前三个fd
bind是绑定本地的IP和端口,接收或者发送数据,用来填充本机的ip与端口,保证端口是正确的,比对的时候是比对的端口
5元组:remoteip,remoteport, localip, localport, proto
三次握手发生在那个posix API?
答:由客户端的connect触发,发生在内核协议栈里面
服务器在收到第一次连接请求时,就创建了一个tcb,tcb生命周期的开始,只是没有绑定fd,此时是半连接。第二次收到时,是全连接,此时也没有分配fd,server端调用posix API,accept分配fd。
tcb是通过五元组区分的。
send只是一个copy的作用,将用户的数据copy到send buffer里面,同样地,recv是将recv buffer里面数据copy到应用程序。
send到内核协议栈几次,但内核协议栈不一定按这个次数发送出去,就会产生粘包的问题?
解决办法:1、分隔符,2,定义长度
send有三种:
1.一次发完
2.send多个包,容易粘包,可以定义长度(建议,循环recv,知道recv与长度相等)或者分隔符(这种需要隔断,保留分隔符之后的缓存,并且还要合包)
3.一个包分多个send
循环发与循环收
网线断了:
1.网卡会重启
2.设计:心跳包
3.客户端直接宕机,也是心跳包
延迟ACK:发送1234567 收到124567,从4开始,server恢复3,发送端重传3之后所有的
服务器出现大量close_wait?
原因:从recv到close花费太长时间,业务逻辑问题。解决方法:先调用close,把业务处理放在线程里面(异步)
客户端一直卡在fin_wait_2,有没有办法解决?
设置了一个keep alive,超过一个时间会终止掉
close()回收fd,内核协议栈中closed回收tcb
双方同时调用close?