Python Socket通信原理与基础实现指南
本文详解Python中Socket网络编程的核心原理与操作步骤。内容涵盖套接字的创建、IP与端口绑定、监听与连接处理、数据收发及关闭流程,并提供服务端与客户端的完整代码示例,帮助开发者快速掌握Python基础网络通信实现。

上图展示了Socket网络编程的整体流程。
关于数据在网络底层的具体传输路径,此处暂不展开,因为涉及过于底层的细节。本文重点在于阐述如何将数据从应用程序界面传输至网络流中。
这一过程并非简单的键盘输入与回车操作,其背后涉及复杂的技术实现与处理机制。
打开一个网络接口:套接字
Socket,中文常称为“套接字”,是应用程序与网络交互的标准接口。它允许主机之间或同一台计算机上的不同进程之间进行通信,应用程序通过套接字向网络发出请求或响应网络请求。
在Python中,我们使用 socket() 函数来创建套接字,其标准语法格式如下:
import socket # 居然是个内置模块
socket.socket([family[, type[, proto]]])
参数释义:
family: 套接字家族可以使 AF_UNIX(本地协议) 或者 AF_INET(产生IPV4)。
type: 套接字类型可以根据是面向连接的还是非连接分为
SOCK_STREAM(这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。这是一个使用最多的socket类型,是用TCP协议来传输的。)
或 SOCK_DGRAM(这个协议是无连接的,固定长度的连接调用。该协议是不可靠的,使用UDP来进行它的连接。)。
protocol: 一般不填默认为 0。
返回值:该函数返回一个通信套接字对象,作为本机与网络通信的接口。
绑定IP与端口:bind
bind() 方法用于将 socket 关联到指定的网络接口(IP 地址)和端口号:
bind(hostname,port)
参数释义:
hostname:主机IP
port:进行网络通信的端口
127.0.0.1 是标准的 IPv4 回环地址,仅允许主机上的进程连接至服务器。若传入空字符串,服务器将接受本机所有可用的 IPv4 地址。
端口号应为 1-65535 之间的整数(0为保留值),该整数用于接收客户端链接的 TCP 端口。若端口号小于 1024,部分操作系统可能要求管理员权限。
监听网络来信:监听套接字
listen(backlog) #开始 TCP 监听。
参数释义:
backlog 参数指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为 1,多数应用程序设置为 5 即可;若需处理高并发,可适当调大,例如设置为 20。
函数listen用来初始化服务器可连接队列。
服务器处理客户端连接时是顺序处理的,同一时间只能处理一个客户端连接。
当多个客户端的连接请求同时到来的时候,服务器将不能处理的客户端连接请求放入到等待队列中,这个队列的长度由listen()函数来指定。
(这里面包括了还没握手的、一次握手的、两次握手的,只要还没握完,通通进去待着)
大多数系统的设置为20,其实真的没必要太多,真的。
根据系统的可承受负载和程序的需求来确定。
系统有一个最大侦听队列数,一般是128(somaxconn),可以调优。
接收网络来访者:允许连接
accept() #被动接受TCP客户端连接,(阻塞式)等待连接的到来
accept() 方法会阻塞并等待传入连接。当有客户端连接时,它将返回一个新的 socket 对象,该对象包含表示当前连接的 conn 以及由主机和端口号组成的 IPv4/v6 连接元组。
我们将使用这个新返回的 socket 对象与客户端进行后续通信。
客户端方面:申请连接
connect((HOST, PORT))
参数无需赘述,该函数返回一个通信套接字。
此方法用于主动初始化 TCP 服务器连接。一般 address 的格式为元组(hostname, port),如果连接出错,将返回 socket.error 错误。
connect_ex() 是 connect() 函数的扩展版本,出错时返回错误码而非抛出异常。
关闭通信套接字:close()
用于关闭对某一个套接字的函数。
公共用途的套接字函数
s.recv() # 接收 TCP 数据,数据以字符串形式返回,bufsize 指定要接收的最大数据量。flag 提供有关消息的其他信息,通常可以忽略。
s.send() # 发送 TCP 数据,将 string 中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于 string 的字节大小。
s.recvfrom() # 接收 UDP 数据,与 recv() 类似,但返回值是(data,address)。其中 data 是包含接收数据的字符串,address 是发送数据的套接字地址。
s.sendto() # 发送 UDP 数据,将数据发送到套接字,address 是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。
这些函数中的每一个单独讲解都足以撰写一篇文章。
服务端/客户端
此处提供一个示例,后续开发者可直接修改使用:
服务端
import socket
# create a socket object
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
host = socket.gethostname()
port = 8088
# bind to the port
serversocket.bind((host, port))
print("Server start at port: 8088")
# queue up to 5 requests
serversocket.listen(5)
while True:
# establish a connection
clientsocket,addr = serversocket.accept()
print("Got a connection from %s" % str(addr))
msg='Thank you for connecting'+ "\r\n"
clientsocket.send(msg.encode('utf-8'))
clientsocket.close()
客户端
import socket
# create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
host = socket.gethostname()
port = 8088
# connection to hostname on the port.
s.connect((host, port))
# Receive no more than 1024 bytes
msg = s.recv(1024)
s.close()
print (msg.decode('ascii'))
结果输出
Server start at port: 8088
Got a connection from ('172.28.47.243', 9599)
Thank you for connecting
本文主要处理单连接场景,但在实际应用中,更多场景需要处理多连接和大并发情况。
后续文章会介绍相关内容,目前我先去调查一下Python是否支持epoll。
因为这篇内容主要是为我六月份的那个项目服务的,所以当前的连接处理方式已足够使用。

到此这篇关于Python基础之Socket通信原理的文章就介绍到这了,更多相关python通信原理内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













