Python Socket套接字基础:TCP通信实现与代码解析

拾光
拾光
发布时间:2026-10-15| 5人浏览过
原创

本文详细解析Python中Socket套接字的用法,通过完整的服务器与客户端代码示例,演示基于TCP协议的通信流程。涵盖socket模块创建、bind监听、accept连接、recv接收及send发送等核心API的使用,并深入讲解编码转换与异常处理,帮助开发者掌握Python网络编程基础。

前言

Python语言内置了Socket套接字模块,用于实现底层的网络通信功能。

在Python应用程序中,通常通过Socket“套接字”向网络发起请求或响应网络请求,从而实现主机之间或同一台计算机上不同进程之间的通信。

服务器和客户端的源代码

服务器端


#coding=utf-8
#创建TCP服务器
import socket
import time
from time import ctime

HOST = '127.0.0.1'
PORT = 8080
BUFSIZE=1024
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
sock.bind((HOST, PORT))  
sock.listen(5)
addr=(HOST,PORT)
while True:
    print('waiting for connection...')
    sock,addr =sock.accept()
    print('...connected from:',addr)
    while True:
        data =sock.recv(BUFSIZE).decode()
        print('date=',data)
        if not data:
            break
        sock.send(('[%s] %s' %(ctime(),data)).encode())
sock.close()

客户端


#coding=utf-8
#创建TCP客户端

import socket

HOST = '127.0.0.1'
PORT = 8080
BUFSIZE = 1024
ADDR=(HOST,PORT)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT)) 

while True:
    data = input('> ')
    if not data:
        break
    sock.send(data.encode())
    data = sock.recv(BUFSIZE).decode()
    if not data:
        break
    print(data)

sock.close()

执行结果显示:

首先运行服务器端程序,运行结果如图1所示:

随后运行客户端程序,效果如图2所示。

需要注意的是:服务器端和客户端必须在两个独立的IDLE Shell环境中打开。如果两者在同一个Shell中运行,客户端一旦启动,服务器程序就会中止执行,导致客户端无法连接服务器并报错,具体错误如图3所示。

我们在图2的客户端界面中输入需要传输的信息,然后按回车键。此时,在服务器端可以看到收到了相关信息,具体表现如图4(客户端发送信息)和图5(服务器端接收信息)所示。


源代码解析

我们从服务器端的代码开始分析,首先展示部分核心代码:


import socket
import time
from time import ctime

前三行代码导入了三个模块,分别是socket模块、time模块以及从time模块中导入的ctime函数。

1)socket模块提供了与Socket套接字相关的各项功能,后续代码中大量使用了该模块。这里先介绍一个关键函数,其他功能将在后文介绍: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

功能:创建套接字对象,并将创建好的套接字赋值给变量sock。后续程序中所有与套接字相关的操作都将通过sock变量完成。

格式:socket.socket([family[, type[, proto]]])

参数说明:

family:套接字家族,可以是AF_UNIX或AF_INET。AF_INET指面向网络的因特网通信;AF_UNIX基于文件系统的通信。在本例中,我们使用AF_INET,利用因特网进行通信。

type:套接字类型,根据连接方式可分为SOCK_STREAM(面向连接)或SOCK_DGRAM(无连接)。

SOCK_STREAM:对应TCP协议,提供面向连接、可靠的数据传输服务。数据无差错、无重复发送,并按发送顺序接收。内部设置流量控制,避免数据流淹没慢速接收方。数据被视为字节流,无长度限制。

SOCK_DGRAM:对应UDP协议,提供无连接服务。数据包以独立形式发送,不提供无差错保证,数据可能丢失或重复,顺序发送但可能乱序接收。

本例中选择TCP协议,即使用SOCK_STREAM类型。

protocol:通常不填写,默认为0。

2)time模块用于处理Python中与时间相关的计算,例如time.sleep(5)用于延时5秒,time.time()返回当前时间的时间戳等。 下面的ctime也是其功能之一,该函数将一个时间戳(按秒计算的浮点数)转换为time.asctime()的格式,便于观察。转换后的格式如下:

print “time.ctime() : %s” % time.ctime()

结果:time.ctime() : Tue Feb 17 10:00:18 2013

在我们的示例中,图4圈2处显示的就是转换后的时间字符串。


HOST = '127.0.0.1'
PORT = 8080
BUFSIZE=1024
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
sock.bind((HOST, PORT))  
sock.listen(5)
addr=(HOST,PORT)

看完头部代码后,我们继续分析第二部分。

前三行定义了三个变量:HOST、PORT、BUFSIZE,分别代表服务器的IP地址、端口号以及接收数据的最大缓冲区大小。

第四句sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 定义了Socket套接字对象。

第五句sock.bind((HOST, PORT)),将IP地址和端口绑定到定义的套接字sock上。

第六句sock.listen(5),开始TCP监听。括号中的5表示在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5即可。

第七句addr=(HOST,PORT),定义了一个变量addr,并将地址以元组形式赋值给addr。


while True:
    print('waiting for connection...')
    sock,addr =sock.accept()
    print('...connected from:',addr)
    while True:
        data =sock.recv(BUFSIZE).decode()
        print('date=',data)
        if not data:
            break
        sock.send(('[%s] %s' %(ctime(),data)).encode())
        sock.close()
sock.close()

这是服务器代码的最后一部分,也是通信的主体。首先进入一个while True:的永真循环,进入后执行print(‘waiting for connection…'),这就是图1上蓝色文字所表示的部分。

第三行执行sock,addr =sock.accept()。sock.accept()用于被动接受TCP客户端连接(阻塞式),等待连接到来。当客户机启动并提交请求后,服务器接受请求,并将客户端的IP地址等信息存入变量addr中。

第四行执行print('…connected from:',addr),因此输出字符串…connected from:以及客户端传来的IP地址和端口信息。

至此,服务器和客户端的通信连接已建立。

接下来开始传送数据,再次进入一个永真循环,相关代码如下:


  while True:
        data =sock.recv(BUFSIZE).decode()
        print('date=',data)
        if not data:
            break
        sock.send(('[%s] %s' %(ctime(),data)).encode())
        sock.close()

第二行:data =sock.recv(BUFSIZE).decode()。

sock.recv()表示接收TCP数据,数据以字符串形式返回,BUFSIZE指定要接收的最大数据量。

decode() 将其他编码的字符串解码成unicode格式。

这里需要特别说明,参考上图:

字符串在Python内部是用unicode编码来表示,而在硬盘存储时是utf-8格式。因此在存储和使用时需要进行格式转换,转换方式如下:

decode 将其他编码的字符串(例如utf-8)解码成unicode格式。

encode 将unicode编码成另一种编码格式(例如utf-8)。

当然decode和encode不仅可以转换utf-8类型,转换的类型可以通过encoding参数指定,不过我们常用的是默认设置。

总结一下,data =sock.recv(BUFSIZE).decode()执行结束后,表示已将客户端的数据接收过来并存放到了data变量中。

下面进行第三行print(‘date=',data),打印数据,结果就是图5中的圈3所表示的内容。

第四行及第五行:如果没有接收到数据,则跳出循环,继续监听。

if not data: break

第六行 sock.send(('[%s] %s' %(ctime(),data)).encode()),向客户端发送转换格式(encode)后的数据。

数据包括两部分,第一部分是ctime(),表示以字符串形式表示的时间;data表示变量中存储的信息。前面还有一部分'[%s] %s'中的%s格式化字符串,用于形成所需的输出格式。

最后一句sock.close(),关闭套接字。

这样服务器端代码就完成了。我们再来看客户端代码。


import socket

HOST = '127.0.0.1'
PORT = 8080
BUFSIZE = 1024
ADDR=(HOST,PORT)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT)) 

这里只解释几句,HOST = ‘127.0.0.1' 和 PORT = 8080,这两句分别指定了服务器端的IP地址和端口号。

sock.connect((HOST, PORT)) 这一句是利用创建好的socket套接字主动初始化TCP服务器连接,即向服务器提出申请,服务器端用sock.accept()接受请求。

这一句执行完之后,通信就建立起来了,在服务器端会执行print('…connected from:',addr),结果如图5圈2所示。


while True:
    data = input('> ')
    if not data:
        break
    sock.send(data.encode())
    data = sock.recv(BUFSIZE).decode()
    if not data:
        break
    print(data)
sock.close()

接下来进入永真循环,先是input函数,输出> 后等待输入,如图2所示。例如输入hi,server,如图4的圈1,然后后两句是

if not data: break

如果没有输入,则跳出循环。

第五行sock.send(data.encode()),将输入的数据转换格式后将数据发送给服务器端。这时把hi,server发送给服务器端,服务器用data =sock.recv(BUFSIZE).decode()来接收,同时用print(‘date=',data)打印出来,结果如5的圈3所示。

这时,服务器会继续执行sock.send(('[%s] %s' %(ctime(),data)).encode()),把当前的时间和数据发送给客户端。

而在客户端,执行data = sock.recv(BUFSIZ).decode(),所以客户端会接收到相应的数据,并且打印出来,结果如图4的圈2所示。

以上就是Socket套接字的TCP通信过程。

到此这篇关于python基础之Socket套接字详解的文章就介绍到这了,更多相关python Socket详解内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。