Python socket 基本知识与工作原理
套接字
由于TCP/IP协议族被设计成能够运行在多种操作系统的环境下,TCP/IP标准允许系统设计者能够选择有关API的具体实现细节。
目前,可供应用程序使用TCP/IP的应用编程接口API的最著名的是套接字接口
而套接字不是物理实体,而是一种抽象,套接字是提供应用程序创建和使用的数据结构
Socket
通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄
Socket有两种类型:
- 流式
Socket(STREAM)
:是一种面向连接的Socekt
,针对面向连接的TCP服务应用,可靠,但是效率低; - 数据报式
Socket(DATAGAM)
:是一种无连接的Socket,对应于无连接的UDP服务应用。不可靠(丢失,顺序混乱,在接受端要分析重排及要求重发),但效率高。
Socket通信协议分析
UDP协议
UDP协议是一种无连接的协议,也称为数据报协议。每次发送数据报时,需要同时发送本机的socket描述符(就是上面所说的套接字描述符)和接收端的socket描述符。所以,每次通信都要发送额外的数据。
TCP协议
TCP协议是一种有连接的协议,使用应用程序之前,必须先建立TCP连接。所以每次在进行通信之前那,我们需要先建立Socket连接,一个socket作为服务端监听请求,一个socket作为客户端进行连接请求。只有双方建立连接好以后,双方才可以通信。
两种协议区别及选择
简单分析两者的区别:
- 在UDP中,每次发送数据报,需要附上本机的socket描述符和接收端的socket描述符.而TCP是基于连接的协议,在通信的socket之间需要在通信之前建立连接,即TCP的三次握手,,因此建立连接会有一定耗时
- 在UDP中,数据报数据在大小有64KB的限制。而TCP不存在这样的限制,一旦TCP通信的socket对建立连接,他们通信类似IO流。
- UDP是不可靠的协议,发送的数据报不一定会按照其发送顺序被接收端的socket接收。而TCP是一种可靠的协议。接收端收到的包的顺序和包在发送端的顺序大体一致(这里不讨论丢包的情况)
说到这,至于选择哪种协议,还是取决于你的使用场景,当然目前见得比较多就是基于TCP协议的Socket通信。当然一些实时性较高的一些服务,局域网的一些服务用UDP的多一些。
基于TCP协议的 Socket编程基本流程图
Socket的通信过程
服务端:
申请一个Socket
绑定到一个IP地址和一个端口
开启侦听,等待接受连接
客户端:
申请一个Socket
连接服务器(指明IP地址和端口号)
服务器端接到连接请求后,产生一个新的Socket
(端口大于1024
)与客户端建立连接并进行通讯,原侦听Socket
继续侦听。
粘包现象是如何产生的???
黏包现象并不是一个bug
而是各种tcp协议的特点和算法导致了现在的问题
合包机制 Nagle
拆包机制
流式传输无边界
黏包一定是坏现象么
但是从程序的传递过程中的角度:
解决了大量短数据大量回执的问题
长数据由于网络限制的拆包在我们的接收端可以自动拼接
对于应用层 你的程序来说 大部分时候都不是好事儿
所以我们才要解决它
解决在应用层程序中的黏包现象
解决在应用层程序中的黏包现象
如何解决粘包
- 自定义协议
先发送即将发送 数据的长度,然后再 发送数据
先接受 数据的长度,在根据接受的长度接受数据
用到了struct
模块, 来控制第一次发送数据长度的这条信息的长度
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!