赞
踩
在socket网络编程中,都是端到端通信,由客户端端口+服务端端口+客户端IP+服务端IP+传输协议组成的五元组可以明确的标识一条连接。在TCP的socket编程中,发送端和接收端都有成对的socket。发送端为了将多个发往接收端的包,更加高效的的发给接收端,于是采用了优化算法(Nagle算法),将多次间隔较小、数据量较小的数据,合并成一个数据量大的数据块,然后进行封包。那么这样一来,接收端就必须使用高效科学的拆包机制来分辨这些数据。
1.Q:什么是TCP粘包问题?
TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包,从接收缓冲区来看,后一包数据的头紧接着前一包数据的尾,出现粘包的原因是多方面的,可能是来自发送方,也可能是来自接收方。
2.Q:造成TCP粘包的原因
(1)发送方原因
TCP默认使用Nagle算法(主要作用:减少网络中报文段的数量),而Nagle算法主要做两件事:
只有上一个分组得到确认,才会发送下一个分组
收集多个小分组,在一个确认到来时一起发送
Nagle算法造成了发送方可能会出现粘包问题
(2)接收方原因
TCP接收到数据包时,并不会马上交到应用层进行处理,或者说应用层并不会立即处理。实际上,TCP将接收到的数据包保存在接收缓存里,然后应用程序主动从缓存读取收到的分组。这样一来,如果TCP接收数据包到缓存的速度大于应用程序从缓存中读取数据包的速度,多个包就会被缓存,应用程序就有可能读取到多个首尾相接粘到一起的包。
3.Q:什么时候需要处理粘包现象?
如果发送方发送的多组数据本来就是同一块数据的不同部分,比如说一个文件被分成多个部分发送,这时当然不需要处理粘包现象
如果多个分组毫不相干,甚至是并列关系,那么这个时候就一定要处理粘包现象了
4.Q:如何处理粘包现象?
(1)发送方
对于发送方造成的粘包问题,可以通过关闭Nagle算法来解决,使用TCP_NODELAY选项来关闭算法。
(2)接收方
接收方没有办法来处理粘包现象,只能将问题交给应用层来处理。
(2)应用层
应用层的解决办法简单可行,不仅能解决接收方的粘包问题,还可以解决发送方的粘包问题。
解决办法:循环处理,应用程序从接收缓存中读取分组时,读完一条数据,就应该循环读取下一条数据,直到所有数据都被处理完成,但是如何判断每条数据的长度呢?
格式化数据:每条数据有固定的格式(开始符,结束符),这种方法简单易行,但是选择开始符和结束符时一定要确保每条数据的内部不包含开始符和结束符。
发送长度:发送每条数据时,将数据的长度一并发送,例如规定数据的前4位是数据的长度,应用层在处理时可以根据长度来判断每个分组的开始和结束位置。
5.Q:UDP会不会产生粘包问题呢?
TCP为了保证可靠传输并减少额外的开销(每次发包都要验证),采用了基于流的传输,基于流的传输不认为消息是一条一条的,是无保护消息边界的(保护消息边界:指传输协议把数据当做一条独立的消息在网上传输,接收端一次只能接受一条独立的消息)。
UDP则是面向消息传输的,是有保护消息边界的,接收方一次只接受一条独立的信息,所以不存在粘包问题。
举个例子:有三个数据包,大小分别为2k、4k、6k,如果采用UDP发送的话,不管接受方的接收缓存有多大,我们必须要进行至少三次以上的发送才能把数据包发送完,但是使用TCP协议发送的话,我们只需要接受方的接收缓存有12k的大小,就可以一次把这3个数据包全部发送完毕。
TCP VS UDP
tcp 是面向连接提供可靠传输;UDP是面向无连接,提供不可靠连接
Tcp 提供流量控制 ; UDP不提供流量控制
Tcp 保证传输数据顺序 ; UDP不保证传输顺序,也就是可能是乱序收包
TCP 面向字节流 ; UDP 面向数据包
设计一个基于udp的可靠连接算法
针对数据完整性 –> 加上一个16或者32位的CRC验证字段
针对乱序 –> 加上一个数据包序列号SEQ
针对丢包 –> 需要确认和重传机制,就是和Tcp类似的Ack机制
针对协议字段 –> protol 字段,标识当前使用协议
http报文结构
【URL】http使用统一资源定位符:协议://主机:端口/路径
【http请求报文】请求行、首部、空行、主体
- (1)请求行:方法,URL 空行 协议的版本(中间空格隔开)
- 请求方法有如下几种:
- GET:从服务器获取一份文档
- HEAD:只从服务器获取文档的首部
- POST:向服务器发送需要处理的数据,常用于表单提交。
- PUT:将请求的主体部分存储在服务器上,从服务器上向客户发送文档
- TRACE:对可能经过代理服务器传送到服务器上去的报文进行追踪
- OPTIONS:决定可以在服务器上执行哪些方法
- DELETE:从服务器上删除一份文档
- GET:当客户端要从服务器中读取某个资源时,使用GET 方法。GET 方法要求服务器将URL 定位
- 的资源放在响应报文的数据部分,回送给客户端,即向服务器请求某个资源。使用GET 方法时,
- 请求参数和对应的值附加在 URL 后面,利用一个问号(“?”)代表URL 的结尾与请求参数的开始,
- 传递参数长度受限制。例如,/index.jsp?id=100&op=bind。
- POST:当客户端给服务器提供信息较多时可以使用POST 方法,POST 方法向服务器提交数据,
- 比如完成表单数据的提交,将数据提交给服务器处理。GET 一般用于获取/查询资源信息,
- POST 会附带用户数据,一般用于更新资源信息。POST 方法将请求参数封装在HTTP 请求数据中,
- 以名称/值的形式出现,可以传输大量数据;
- (2)首部 首部名:(空格)首部值(回车换行)
- ● User-Agent:产生请求的浏览器类型;标志客户程序
- ● Accept:客户端可识别的响应内容类型列表;星号 “ * ” 用于按范围将类型分组,
- 用 “ */* ” 指示可接受全部类型,用“ type/* ”指示可接受 type 类型的所有子类型;
- ● Accept-Language:客户端可接受的自然语言;
- ● Accept-Encoding:客户端可接受的编码压缩格式;
- ● Accept-Charset:可接受的应答的字符集;
- ● Host:请求的主机名,允许多个域名同处一个IP 地址,即虚拟主机;
- ● connection:连接方式(close 或 keepalive);
- ● Cookie:存储于客户端扩展字段,向同一域名的服务端发送属于该域的cookie;
- (3)空行:通知服务器以下不再有请求的头部信息
- (4)主体(请求数据):相关备注信息
【响应报文】状态行、首部、空格、主体
- (1)状态行:协议版本 (空格) 状态码 (空格) 短语
- ● 状态码由三位数字组成,第一位数字表示响应的类型,常用的状态码有五大类如下所示:
- 1xx:表示服务器已接收了客户端请求,客户端可继续发送请求;
- 2xx:表示服务器已成功接收到请求并进行处理;
- 3xx:表示服务器要求客户端重定向;
- 4xx:表示客户端的请求有非法内容;
- 5xx:表示服务器未能正常处理客户端的请求而出现意外错误,服务器差错;
- ● 状态码描述文本有如下取值:
- 200 OK:表示客户端请求成功;
- 400 Bad Request:表示客户端请求有语法错误,不能被服务器所理解;
- 401 Unauthonzed:表示请求未经授权,该状态代码必须与 WWW-Authenticate 报头域
- 一起使用;
- 403 Forbidden:表示服务器收到请求,但是拒绝提供服务,通常会在响应正文中给出不
- 提供服务的原因;
- 404 Not Found:请求的资源不存在,例如,输入了错误的URL;
- 500 Internal Server Error:表示服务器发生不可预期的错误,导致无法完成客户端的请求;
- 503 Service Unavailable:表示服务器当前不能够处理客户端的请求,在一段时间之后,
- 服务器可能会恢复正常;
- (2)响应首部:首部名 :(空格)首部值
- Location:Location响应报头域用于重定向接受者到一个新的位置。例如:客户端所
- 请求的页面已不存在原先的位置,为了让客户端重定向到这个页面新的位置,服务器端可以发回
- Location响应报头后使用重定向语句,让客户端去访问新的域名所对应的服务器上的资源;
- Server:Server 响应报头域包含了服务器用来处理请求的软件信息及其版本。它和
- User-Agent 请求报头域是相对应的,前者发送服务器端软件的信息,后者发送客户端软件
- (浏览器)和操作系统的信息。
- Content-Length 给出文档长度
- Content-type 给出媒体类型
- Vary:指示不可缓存的请求头列表;
- Connection:连接方式;对于请求来说:close(告诉WEB 服务器或者代理服务器,在完成
- 本次请求的响应后,断开连接,不等待本次连接的后续请求了)。keepalive(告诉WEB服务器或者
- 代理服务器,在完成本次请求的响应后,保持连接,等待本次连接的后续请求);对于响应来说:
- close(连接已经关闭); keepalive(连接保持着,在等待本次连接的后续请求);
- Keep-Alive:如果浏览器请求保持连接,则该头部表明希望WEB 服务器保持连接多长时间(秒);
- 例如:Keep-Alive:300;
- WWW-Authenticate:WWW-Authenticate响应报头域必须被包含在401 (未授权的)响应
- 消息中,这个报头域和前面讲到的Authorization 请求报头域是相关的,当客户端收到 401
- 响应消息,就要决定是否请求服务器对其进行验证。如果要求服务器对其进行验证,就可以发送
- 一个包含了Authorization 报头域的请求;
- (3)空行:最后一个响应头部之后是一个空行,发送回车符和换行符,通知服务器以下不再有
- 响应头部。
- (4)响应主体:服务器返回给客户端的文本信息;
浏览器输入Google地址回车,是怎么上网的(dns啥的)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。