tcp连接过程: 为啥一个socket在connect之后关闭,再复用端口重建socket执行listen此时对方连接不上呢
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tcp连接过程: 为啥一个socket在connect之后关闭,再复用端口重建socket执行listen此时对方连接不上呢相关的知识,希望对你有一定的参考价值。
这里的两个客户端同时可以作为服务器,主要问题在于,当一个客户端需要在本地NAT打洞时,需执行connect一次,此时对方没有监听,所以返回connect超时,此时将其作为服务器,需绑定复用本地端口,listen,之后对方connect本机,显示connect超时,为什么connect会超时呢,这是什么原因?(这里的端口,ip都没错误,测试的NAT环境为完全圆锥形)
参考技术A netstat -an 查看端口是否开启状态,如果开的话说明第一次连接没有关闭成功,再检查代码看看哪里问题。追问看了,不是这个的问题,服务器方端口处于listen状态,代码应该没问题,因为如果不打洞直接监听的话,连接时没有问题的(因为我这里的NAT为完全圆锥形)
TCP及Socket
参考技术A 计算机网络相关的问题,如果想去了解,前提就是深刻理解网络4/7层模型。记住并理解,上面每一层。切记,切记,切记。知道一些就可以开始主题,分两个部分TCP和Socket。
TCP是(Tranfer Control Protocol)的简称,在OSI参考模型第四层,也就是端口,到端口的的通信,它是一个可靠的双向连接,一旦建立连接就可以双向数据传输,双方都可以进行发送或接收操作。
最常听说的就是三次握手。是的它说的就是TCP建立连接的过程。具体的步骤如下:
第一步:Server监听端口,状态为:Listen
第二部:Client发送SNY包,请求连接,并将状态改为:SYN_SEND
第三部:Server发送ACK包,和SNY包,同意,并请求连接,状态改为:SYN_RCVD
第四部:Client发送ACK包,Server收到包后,连接建立。双方状态改为:ESTABLISHED
第一步:Client发起FIN包。状态变为:FNI_WAIT_1
第二步:Server发送ACK包。状态变为:CLOSE_WAIT,Client收包后状态变为:FNI_WAIT_2
第三步:Server发送FIN包,状态变为:LAST_ACK。Client收包后状态变为:TIME_WAIT
第四步:Client发送ACK包。双方状态变为:CLOSED
需要注意的是,Client是在收到Server FIN包后两个最大报文时间(2MSL)后变为CLOSED状态的。双方都可以发起断开请求,上面是已先发起请求的是Client。
如何验证上面讲的这些呢?那就是抓包分析,其实日常的开发中也可以通过抓包来发现问题。在这里我简单贴个图看一下TCP的包,这个工具非常强大感兴趣的朋友可以去深入了解一下。
1.可以在这个过滤,通过协议,通过IP,通过端口都可以。
2.这个就是每个包,例子中的这个是个[SYN,ACK]包,就是建立TCP连接的第二次握手
3.被抓取的包对应的网络层,从上到下分别是:物理层、数据链路层、网络层、传输层。
Socket其实就是TCP协议的实现。也就是说它就是TCP的API,当然其实Socket也支持别的协议如:UDP。既然是API那,上面说的其实就是它的原理。下面说一下它的使用。大概说一下。
1.ServerSocket:是服务端来监听的类。监听方法accept()。
2.客户端:创建Socket对象,设定IP和Port
3.当有新的客户端连接时可以通过ServerSocket类获取Socket。而Socket就是我们的通讯渠道。
4.发送和读取数据分别使用OutputStream和InputStream而这两个类是从Socket获取的。
其实Socket的基本使用就是这么简单,但是在其实项目中这样是无法满足需求的。实际上大多数场景都是需要一对多的提供服务。
使用多线程实现多客户端的通信
实现服务器与多个客户端进行通信, 可以接受多个客户端的请求并进行回复
应用多线程来实现服务器与多客户端之间的通信
1、服务器端创建ServerSocket,循环调用accept()等待客户端连接
2、客户端创建一个Socket并请求和服务器端连接
3、服务器端接受客户端请求,创建socket与该客户建立专线连接
4、建立连接的两个socket在一个单独的线程上对话
5、服务器端继续等待新的连接
以上是关于tcp连接过程: 为啥一个socket在connect之后关闭,再复用端口重建socket执行listen此时对方连接不上呢的主要内容,如果未能解决你的问题,请参考以下文章