socket相关知识总结
2014-08-02 21:37
344 查看
最近面试的时候老被问到TCP/IP相关的东西,也问了不少socket函数的东西,看样子需要来个总结了:
请求端发送SYN请求到指定的服务器端口,这里相当于调用了 connect()。
服务器端接收到请求之后,发送ACK以及SYN=1的报文信息,这里相当于调用了accept()。
请求端收到服务器端发送的ACK信号, 这里connect()实现了返回。然后发送ACK确认信号,至此三次握手已经完成,然后服务器端收到ACK之后,那么accept()也返回了。
1-2.四次挥手
首先说为什么需要四次挥手了,正是因为是全双工的,所以双方都需要申请关闭,然后双方再确认关闭,这样就有了四次。
请求端发送FIN报文,调用了close(),服务器端调用read()函数将报文信息都出来,发现是申请关闭,那么就返回,然后发送ACK报文。
然后服务器端同理,调用close(),这时申请关闭,然后等待客户端回应ACK。
也就是说close在收到ACK的时候就已经返回了。
状态, 然后发送SYN ACK报文,等待客户端发送 ACK报文。如果等到了,那么就进入了ESTABLISHED 状态,这样就完成了三次握手。
对于客户端而言: 首先默认情况是 CLOSED 状态,主动发起连接请求,发送SYN报文,跳转到 SYN_SENT 状态,然后收到了服务器端发送的SYN 和 ACK报文,最后发送了ACK信号之后,也就进入了 ESTABLISHED状态。 至此,三次握手完成。
继续分析状态变迁:
服务器端: 在进入 ESTABLISHED 之后,收到 FIN 之后发送 ACK 之后,就进入了CLOSE_WAIT 状态(被动关闭) , 然后发送 FIN 报文,进入 LAST_ACK
状态,最后接收到了 ACK之后则进入了CLOSED 状态。
客户端:发送 FIN 报文之后,那么就进入了 FIN_WAIT_1 状态(主动关闭) ,收到 ACK 之后呢,就进入了FIN_WAIT_2 状态。 这样就完成了单方面的断开。 然后收到了服务器发送来的FIN 信号,发送了ACK之后,则进入了TIME_WAIT状态。最后进入了 CLOSED 状态。
其他扩展:
TIME_WAIT状态:
在调PIC项目的时候,采用rtsp协议发送视频,为什么电路断了之后需要更改两台电脑的端口号呢,这就是由于TIME_WAI这个状态搞得鬼。
TIME_WAI也称为2MSL等待状态,每个具体TCP实现都必须选择一个报文段最大生成时间MSL。 它是任何报文被丢弃前在网络内的最长时间,这个时间是2分钟。也就是说,当TCP执行一个主动关闭,并发回最后一个ACK,该链接必须在TIME_WAIT状态停留的时间为2倍的MSL,这样可以让TCP再次发送最后的ACK以防止这个ACK丢失。也就是说,我如果实现了主动关闭,那么这个端口短时间被不能用了,对于客户端还好,因为端口本来就没有绑定,但是服务器就不行了,因为都是熟知的端口号,这也就是为什么我们的PIC电路版发送视频的时候必须得更改端口号了。
1. TCP/IP三次握手和四次挥手
1-1.先从最简单的TCP建立连接开始:请求端发送SYN请求到指定的服务器端口,这里相当于调用了 connect()。
服务器端接收到请求之后,发送ACK以及SYN=1的报文信息,这里相当于调用了accept()。
请求端收到服务器端发送的ACK信号, 这里connect()实现了返回。然后发送ACK确认信号,至此三次握手已经完成,然后服务器端收到ACK之后,那么accept()也返回了。
1-2.四次挥手
首先说为什么需要四次挥手了,正是因为是全双工的,所以双方都需要申请关闭,然后双方再确认关闭,这样就有了四次。
请求端发送FIN报文,调用了close(),服务器端调用read()函数将报文信息都出来,发现是申请关闭,那么就返回,然后发送ACK报文。
然后服务器端同理,调用close(),这时申请关闭,然后等待客户端回应ACK。
也就是说close在收到ACK的时候就已经返回了。
2.TCP的状态迁移图:
对于服务器端而言:首先默认情况是 CLOSED 状态,服务器端调用了socket()、bind()、listen()进入了LISTEN 状态、然后等待接收SYN报文,接收到之后呢,就跳转到SYN_RECV状态, 然后发送SYN ACK报文,等待客户端发送 ACK报文。如果等到了,那么就进入了ESTABLISHED 状态,这样就完成了三次握手。
对于客户端而言: 首先默认情况是 CLOSED 状态,主动发起连接请求,发送SYN报文,跳转到 SYN_SENT 状态,然后收到了服务器端发送的SYN 和 ACK报文,最后发送了ACK信号之后,也就进入了 ESTABLISHED状态。 至此,三次握手完成。
继续分析状态变迁:
服务器端: 在进入 ESTABLISHED 之后,收到 FIN 之后发送 ACK 之后,就进入了CLOSE_WAIT 状态(被动关闭) , 然后发送 FIN 报文,进入 LAST_ACK
状态,最后接收到了 ACK之后则进入了CLOSED 状态。
客户端:发送 FIN 报文之后,那么就进入了 FIN_WAIT_1 状态(主动关闭) ,收到 ACK 之后呢,就进入了FIN_WAIT_2 状态。 这样就完成了单方面的断开。 然后收到了服务器发送来的FIN 信号,发送了ACK之后,则进入了TIME_WAIT状态。最后进入了 CLOSED 状态。
其他扩展:
TIME_WAIT状态:
在调PIC项目的时候,采用rtsp协议发送视频,为什么电路断了之后需要更改两台电脑的端口号呢,这就是由于TIME_WAI这个状态搞得鬼。
TIME_WAI也称为2MSL等待状态,每个具体TCP实现都必须选择一个报文段最大生成时间MSL。 它是任何报文被丢弃前在网络内的最长时间,这个时间是2分钟。也就是说,当TCP执行一个主动关闭,并发回最后一个ACK,该链接必须在TIME_WAIT状态停留的时间为2倍的MSL,这样可以让TCP再次发送最后的ACK以防止这个ACK丢失。也就是说,我如果实现了主动关闭,那么这个端口短时间被不能用了,对于客户端还好,因为端口本来就没有绑定,但是服务器就不行了,因为都是熟知的端口号,这也就是为什么我们的PIC电路版发送视频的时候必须得更改端口号了。
相关文章推荐
- linux socket编程相关知识的总结
- QTcpSocket 相关知识总结
- DataGrid相关知识总结(转的)
- DataGrid相关知识总结(收集自各位老大处)
- JAVA相关基础知识总结(连载)-3
- JAVA相关基础知识总结(连载)-8
- JAVA相关基础知识总结(连载)-7
- DataGrid相关知识总结(收集自各位老大处)
- JAVA相关基础知识总结(连载)-12
- JAVA相关基础知识总结(连载)
- [转]WinForm开发,窗体显示和窗体传值相关知识总结
- JAVA相关基础知识总结(连载)-10
- Unicode相关知识总结
- SOA相关知识总结
- 多进程编程的相关知识总结(三)
- JAVA相关基础知识总结(连载)-2
- DataGrid相关知识总结(转的)
- 多进程编程的相关知识总结(二)
- DataGrid相关知识总结(收集)
- JAVA相关基础知识总结(连载)-5