Python socket 基本知识与工作原理

套接字

由于TCP/IP协议族被设计成能够运行在多种操作系统的环境下,TCP/IP标准允许系统设计者能够选择有关API的具体实现细节。

目前,可供应用程序使用TCP/IP的应用编程接口API的最著名的是套接字接口

而套接字不是物理实体,而是一种抽象,套接字是提供应用程序创建和使用的数据结构

Socket通常也称作“套接字”,用于描述IP地址端口,是一个通信链的句柄

1652f12fa6e94275

Socket有两种类型:

image-20181017155606248

  • 流式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 协议 ,转载请注明出处!