socket与socketerver才是我们学习python中网络编程的重中之重在介绍他们两个之前我先介绍一些相关知识

一.socket 概念

咱们现在ois模型中找到socket所承担的角色

网路编程之socket与 socketserver、黏包

socket处于应用层与传输层之间的软件抽象层,是一组接口,在设计模式中,socket其实就是一个门面模式,他把复杂的TCP\IP协议都隐藏在socket接口后门,对于用户来说一组简单的接口就是全部,让socket去组织数据以符合指定的协议,很相似与一个模块的功能

二.套接字(socket)

  套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,即人们所说的 BSD Unix。 因此,有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。这也被称进程间通讯,或 IPC。套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。

我们在网络基础里面举的例子就是TCP协议利用套接字做的简单的网络连接

三 黏包

  黏包的成因

当发送端缓冲区的长度大于网卡的MTU时,TCP会将这次发送的数据拆成几个数据包发送出去,MTU是Maximum Transmission Unit的缩写意思是网络上传送的最大数据包,MTU 的单位是字节,大部分网络设备的MTU都是1500,如果本机的MTU比网关的MTU大,大的数据包就会被拆开来传送,这样会产生很多的数据包碎片,增加丢包率,降低网络速度.网路编程之socket与 socketserver、黏包

基于TCP的套接字客户端往服务端上传文件,发送时文件内容是按照一段一段的字节流发送的,在接收方看了,根本不知道文件的字节流是从何开始,在何处结束

此外,发送方引起的黏包是有TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送,一个TCP段,若连续几次需要send 的数据都很少,通常TCP会根据优化算法把这些数据合成一个TCP段后一次发送出去,这样接收方就收到了黏包的数据,

但是要注意一点是在UDP中就不会发生黏包

因为UDP是无连接的,面向消息的,提供高效服务,说白了它发出去的东西它是不管的,收到也好收不到也好跟他没关系,所以它才效率高

在它的内部块不使用优化算法,由于UDP支持的是一对多的模式,所以接受端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的 UDP包,在每一个TDP包中就有了消息头,这样对于接受端来说就容易进行分区处理了,即面向消息的通道是有消息保护边界的.

对于空消息:TCP是基于数据流的,于是收发消息不能为空,这就需要在客户端和服务端都添加空消息的处理机制,防止程序卡住,而udp是基于数据报的,即便是你输入的是空内容,也可以被发送,udp协议会帮助你封装上消息头发送过去

不可靠不黏包的udp协议:udp的recvfrom是阻塞的,一个recvfrom必须对唯一sendinto接受完字节的数据就算完成所以数据根本不会 黏包只会丢失,不可靠

补充说明

用UDP协议发送时,用sendto函数最大能发送数据的长度为:65535- IP头(20) – UDP头(8)=65507字节。用sendto函数发送数据时,如果发送数据长度大于该值,则函数会返回错误。(丢弃这个包,不进行发送) 

    用TCP协议发送时,由于TCP是数据流协议,因此不存在包大小的限制(暂不考虑缓冲区的大小),这是指在用send函数时,数据长度参数不受限制。而实际上,所指定的这段数据并不一定会一次性发送出去,如果这段数据比较长,会被分段发送,如果比较短,可能会等待和下一次数据一起发送。
View Code

相关文章: