tcp

tcp三次握手:首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源。Client端接收到ACK报文后也向Server段发送报文,并分配资源
第一次握手:客户端发送一个tcp的syn标志位置1的包指明客户端打算连接的服务器端口,以及初始序号x,保存在包头的序列号字段里。
第二次握手:服务器发回确认包(ack)应答。即syn标志位和ack标志位均为1同时,将序列号设置为客户的isn加1
第三次握手:客户端再次发送确认包(ack)syn标志位为0,ack标志位为1。并且把服务器发来ack的序列号字段+1,放在确定字段中发送给对方。
tcp关闭时四次握手:


粘包问题:
解决方法一:TCP提供了强制数据立即传送的操作指令push,TCP软件收到该操作指令后,就立即将本段数据发送出去,而不必等待发送缓冲区满;
解决方法二:发送固定长度的消息
解决方法三:把消息的尺寸与消息一块发送
解决方法四:双方约定每次传送的大小
解决方法五:双方约定使用特殊标记来区分消息间隔
解决方法六:标准协议按协议规则处理,如Sip协议


二 .什么时候需要考虑粘包问题?
1:如果利用tcp每次发送数据,就与对方建立连接,然后双方发送完一段数据后,就关闭连接,这样就不会出现粘包问题(因为只有一种包结构,类似于http协议)。关闭连接主要要双方都发送close连接(参考tcp关闭协议)。如:A需要发送一段字符串给B,那么A与B建立连接,然后发送双方都默认好的协议字符如"hello give me sth abour yourself",然后B收到报文后,就将缓冲区数据接收,然后关闭连接,这样粘包问题不用考虑到,因为大家都知道是发送一段字符。
2:如果发送数据无结构,如文件传输,这样发送方只管发送,接收方只管接收存储就ok,也不用考虑粘包
3:如果双方建立连接,需要在连接后一段时间内发送不同结构数据,如连接后,有好几种结构:
【tcp】1)"hello give me sth abour yourself"
2)"Don't give me sth abour yourself"
那这样的话,如果发送方连续发送这个两个包出去,接收方一次接收可能会是"hello give me sth abour yourselfDon't give me sth abour yourself" 这样接收方就傻了,到底是要干嘛?不知道,因为协议没有规定这么诡异的字符串,所以要处理把它分包,怎么分也需要双方组织一个比较好的包结构,所以一般可能会在头加一个数据长度之类的包,以确保接收。
三 .粘包出现原因:在流传输中出现,UDP不会出现粘包,因为它有消息边界(参考Windows 网络编程)
1 发送端需要等缓冲区满才发送出去,造成粘包
2 接收方不及时接收缓冲区的包,造成多个包接收

    推荐阅读