Java Socket技术总结中哪些细节容易混淆或误解?
摘要:1 Socket通信原理 1.1 ISO七层模型 1.2 TCPIP五层模型 应用层相当于OSI中的会话层,表示层,应用层。 1.3 TCP报文 (1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时
1 Socket通信原理
1.1 ISO七层模型
1.2 TCP/IP五层模型
应用层相当于OSI中的会话层,表示层,应用层。
1.3 TCP报文
(1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
(2)确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
(3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
(A)URG:紧急指针(urgent pointer)有效。
(B)ACK:确认序号有效。
(C)PSH:接收方应该尽快将这个报文交给应用层。
(D)RST:重置连接。
(E)SYN:发起一个新连接。
(F)FIN:释放一个连接。
需要注意的是:
(A)不要将确认序号Ack与标志位中的ACK搞混了。
(B)确认方Ack=发起方Req+1,两端配对。
1.4 Socket通信
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
1.5 三次握手
Socket连接建立和关闭,详见:http://www.2cto.com/net/201310/251896.html
2 通信基本概念
2.1 短连接
连接->传输数据->关闭连接
短连接是指SOCKET连接,发送数据,接收数据后,马上断开连接。
比如:
HTTP1.0默认是短连接,无状态的,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。 、
Http1.1默认是长连接
无状态:协议对于事务处理没有记忆能力;
2.2 长连接
连接->传输数据->保持连接 -> 传输数据-> 。。。 ->关闭连接。
建立SOCKET连接后,不管是否使用,一致保持连接。
2.3 半包
接受方没有接受到一个完整的包,只接受了部分;
原因:TCP为提高传输效率,将一个包分配的足够大,导致接受方并不能一次接受完。
影响:长连接和短连接中都会出现
2.4 粘包
发送方发送的多个包数据到接收方接收时粘成一个包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
分类:一种是粘在一起的包都是完整的数据包,另一种情况是粘在一起的包有不完整的包
出现粘包现象的原因是多方面的:
1)发送方粘包:由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。
2)接收方粘包:接收方用户进程不及时接收数据,从而导致粘包现象。这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据。
2.5 分包
分包(1):在出现粘包的时候,我们的接收方要进行分包处理;
分包(2):一个数据包被分成了多次接收;
原因:1. IP分片传输导致的;2.传输过程中丢失部分包导致出现的半包;3.一个包可能被分成了两次传输,在取数据的时候,先取到了一部分(还可能与接收的缓冲区大小有关系)。
影响:粘包和分包在长连接中都会出现
2.6 如何解决半包,粘包问题
出现粘包和半包现象,是因为TCP当中,只有流的概念,没有包的概念。
UDP不会出现半包,粘包情况,原因是UDP是一个完整的数据包,发送时不进行合并,因此接收的时候就不存在粘包情况。
固定长度:每次发送固定长度的数据;
特殊标示:以回车,换行作为特殊标示;获取到指定的标识时,说明包获取完整。
字节长度:包头+包长+包体的协议形式,当服务器端获取到指定的包长时才说明获取完整;
