七层网络协议、三次握手、四次分手,这些大家都比较熟知,这里主要是带着一些问题来思考整个TCP/IP流程。
1.三次握手的具体流程是怎么样的?
2.socket编程中int listen(int fd, int backlog); backlog的真正意义是什么?
3.一个TCP server能建立多少个本机连接?能建立多少个非本机连接?
4.如何查看服务器的连接状态?
先来回顾一下TCP的三次握手和四次分手
思考一下,服务器的SYN_RECV状态和ESTABLISHED状态存放在哪里,能存放多少个状态,
这里借用陶大师的一个图,
第一次握手:当客户端SYN到达时,如果服务器SYN队列未满,就会插入到SYN队列,如果SYN队列满了,则请求就会被丢弃
第二次握手:服务器SYN+ACK给客户端,表示服务器收到客户端发的请求了
第三次握手:客户端收到服务器是SYN+ACK时,向服务器发起ACK,表示客户端已经准备完毕,此时服务器将连接从SYN队列移到ACCEPT队列,则三次握手才算真正完成。
考虑以下情形:
一、服务器在第三次握手收到客户端ACK时,将连接从SYN队列取出,并准备向ACCEPT队列插入,此时如果ACCEPT队列满了,服务器通过 /proc/sys/net/ipv4/tcp_abort_on_overflow 来决定如何返回,0 表示直接丢丢弃该 ACK,1 表示发送 RST 通知客户端。
二、listen时设置的套接字设为非阻塞模式(默认为阻塞模式),这两种模式会导致accept方法有不同的行为,
阻塞模式下,accept等待的时间不定,由客户端是否发起请求而定,
非阻塞模式下,accept要么返回成功的连接,要么返回失败。
三、如果主进程listen fd,多个子进程同时accept wait,会发生什么,哪个子进程会抢到该连接?有兴趣的可以搜一下惊群效应。
四、如果客户端连上服务器,这个时候拔掉客户端网线并重启,该连接就会处于异常状态,如何检测这些异常连接?当客户端再次连上服务器并产生数据交互时,服务器就会发送RST至客户端关闭连接,如果不再有数据交互,则TCP的keepalive能检测到该问题。
五、系统保留端口:1-1023,自由端口:1024-65535,启动的服务器不应该bind 1-1023的端口
一个TCP server能建立多少个本机连接?首先我们要明白,一个TCP连接的组成是两对IP和两个端口,那么本机客户端连本机服务器的连接数最大理论值为65535-1,同时受到进程能打开的最大句柄数限制,可通过ulimit -n查看。
六、服务器bind IP和端口时,IP怎么选?
INADDR_ANY表示接收所有IP的连接,
0.0.0.0表示接收所有IP的连接,
localhost/127.0.0.1表示只接收本地连接,
客户端通过127.0.0.1或者localhost连接本机服务器时,数据流只经过内核,不经过网卡,几乎无性能损失,我们经常配置的nginx upstream大都是如此设置
七、如何在服务器查看TCP的连接数和各种状态?应该把netstat、tcpdump、lsof等命令练习得比较熟悉,
比如查看8080端口的各种状态:netstat -natl | grep 8080 | awk '{print $6}' | sort | uniq -c | sort -nr
八、关于connect超时,可参考文章socket超时设置详解(connect/read/write)
参考资料:《tcp/ip详解卷1》
参考文章:http://blog.csdn.net/russell_tao/article/details/9111769
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)