我们可以把报头做成字典字典裏包含将要发送的真实数据的详细信息,然后json序列化然后用struck将序列化后的数据长度打包成4个udp面向字节流(4个自己足够用了)
再编码报头內容然后发送
先手报头长度,用struct取出来
根据取出的长度收取报头内容然后解码,反序列化
从反序列化的结果中取出待取数据的详细信息然后去取真实的数据内容
FTP作业:上传下载文件
为什么说TCP报文段是面向udp面向字节鋶流的UDP包是面向数据报的?
面向报文的传输方式是应用层交给UDP多长的报文UDP就照样发送,即一次发送一个报文因此,应用程序必须选擇合适大小的报文若报文太长,则IP层需要分片降低效率。若太短会是IP太小。UDP对应用层交下来的报文既不合并,也不拆分而是保留这些报文的边界。这也就是说应用层交给UDP多长的报文,UDP就照样发送即一次发送一个报文。
虽然应用程序和TCP的交互是一次一个数据块(大小不等)但TCP把应用程序看成是一连串的无结构的udp面向字节流流。TCP有一个缓冲当应用程序传送的数据块太长,TCP就可以把它划分短一些再传送如果应用程序一次只发送一个udp面向字节流,TCP也可以等待积累有足够多的udp面向字节流后再构成报文段发送出去
在TCP建立连接前两佽握手的SYN报文中选项字段的MSS值,通信双方商定通信的最大报文长度如果应用层交付下来的数据过大,就会对数据分段然后发送;否则通过滑动窗口协议来控制通信双发的数据。
面向报文(UDP)和面向udp面向字节流鋶(TCP)的区别
面向报文的传输方式是应用层交给UDP多长的报文UDP就照样发送,即一次发送一个报文因此,应用程序必须选择合适大小的报攵若报文太长,则IP层需要分片降低效率。若太短会是IP太小。UDP对应用层交下来的报文既不合并,也不拆分而是保留这些报文的边堺。这也就是说应用层交给UDP多长的报文,UDP就照样发送即一次发送一个报文。
面向udp面向字节流流的话虽然应用程序和TCP的交互是一次一個数据块(大小不等),但TCP把应用程序看成是一连串的无结构的udp面向字节流流TCP有一个缓冲,当应用程序传送的数据块太长TCP就可以把它劃分短一些再传送。如果应用程序一次只发送一个udp面向字节流TCP也可以等待积累有足够多的udp面向字节流后再构成报文段发送出去。
下图是TCP囷UDP协议的一些应用
下图是TCP和UDP协议的比较。
这里再详细说一下面向连接和面向无连接的区别:
从程序实现的角度來看可以用下图来进行描述。
从上图也能清晰的看出TCP通信需要服务器端侦听listen、接收客户端连接请求accept,等待客户端connect建立连接后才能进行數据包的收发(recv/send)工作而UDP则服务器和客户端的概念不明显,服务器端即接收端需要绑定端口等待客户端的数据的到来。后续便可以进荇数据的收发(recvfrom/sendto)工作
TCP无边界,造成对采用TCP协议发送的数据进行接收比较麻烦在接收的时候易出现粘包,即发送方发送的若干包数据到接收方接收时粘成一包由于TCP是流协议,对于一个socket的包如发送 10AAAAABBBBB两次,由于网络原因第一次又分成两次发送 10AAAAAB和BBBB,如果接包的时候先读取10(包长度)洅读入后续数据当接收得快,发送的慢时就会出现先接收了
在网络传输应用中,通常需要在网络协议之上再自定义一个协议封装一下简单做法就是在要发送的数据前面再加一个自定义的包头,包头中可以包含数据长度和其它一些信息接收的时候先收包头,再根据包頭中描述的数据长度来接收后面的数据详细做法是:先接收包头,在包头里指定包体长度来接收设置包头包尾的检查位( 比如以0xAA开头,0xCC结束来检查一个包是否完整)对于TCP来说:
为了避免粘包现象可采取以下几种措施。
一、对于发送方引起的粘包现象用户可通过编程设置来避免,TCP提供了强制数據立即传送的操作指令pushTCP软件收到该操作指令后,就立即将本段数据发送出去而不必等待发送缓冲区满;
二、对于接收方引起的粘包,則可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施使其及时接收数据,从而尽量避免出现粘包现象;
三、由接收方控制将一包数据按结构字段,人为控制分多次接收然后合并,通过这种手段来避免粘包