千家信息网

Python网络编程

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,客户端/服务器架构所谓服务器就是一系列硬件或软件,为一个或多个客户端(服务的用户)提供所需要的'服务'。它存在的唯一目的就是等待客户端的请求,并响应它们(提供服务),然后等待更多的请求。另一方面,客户
千家信息网最后更新 2026年11月01日Python网络编程
  • 客户端/服务器架构

所谓服务器就是一系列硬件或软件,为一个或多个客户端(服务的用户)提供所需要的'服务'。它存在的唯一目的就是等待客户端的请求,并响应它们(提供服务),然后等待更多的请求。另一方面,客户端因特定的请求而联系服务器,并发送必要的数据,然后等待服务器的回应,最后完成请求或给出故障信息。服务器无限地运行下去,并不断地处理请求;而客户端会进行一次性请求,然后接收该服务,最后结束他们之间的事务。

目前最常见的客户端/服务器架构如图所示,其中描绘了多个客户端通过互联网从一台服务器上检索信息。

套接字(socket)是计算机网络数据结构,它体现了'通信端点'的概念。在没有任何类型的通信开始之前,网络应用程序必须创建套接字。可以将它们比作电话插孔,没有它将无法通信。

socket起源于Unix,而Unix/Linux基本哲学之一就是"一切皆文件",对于文件用打开、读写、关闭模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。套接字通常有两种类型:基于文件的和面向网络的。

第一种类型是基于文件的AF_UNIX,其主要用于同一计算机中的两个进程间通信;第二种是面向网络的AF_INET,主要用于互联网上计算机之间的通信。

通常网络套接字分为面向连接的套接字与无连接的套接字。面向连接的通信提供序列化的、可靠的和不重复的数据交付,而没有记录边界。实现这种连接类型的主要协议是传输控制协议(TCP)。为了创建TCP套接字,必须使用SOCK_STREAM作为套接字类型。

与传输控制协议形成对比的是数据报类型的套接字,它是一种无连接的套接字。这意味着,在通信开始之前并不需要建立连接。此时,在数据传输过程并无法保证它的顺序性、可靠性或者重复性。然而,数据报保存了记录边界,这意味着消息是以整体发送的,而并非分成多个片段。实现这种连接类型的主要协议是用户数据报(UDP)。为了创建UDP套接字,必须使用SOCK_DGRAM作为套接字类型。

  • Python中的网络编程

s=socket(family,type, proto=0)

参数一:地址簇

socket.AF_INET IPv4(默认)
socket.AF_INET6 IPv6

socket.AF_UNIX 只能够用于单一的Unix系统进程间通信

参数二:连接类型

socket.SOCK_STREAM 流式socket , for TCP (默认)
socket.SOCK_DGRAM  数据报式socket , for UDP

socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以 ;其次,SOCK_RAW也可以处理特殊的IPv4报文;利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。
socket.SOCK_RDM一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。
socket.SOCK_SEQPACKET 可靠的连续数据包服务

参数三:协议

0 (默认)与特定的地址家族相关的协议,如果是0,则系统就会根据地址格式和套接类别,自动选择一个合适的协议

服务器套接字方法

s.bind(address)将套接字绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组 (host,port)的形式表示地址。
s.listen(backlog)开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。
s.accept()接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。接收TCP客户的连接(阻塞式)等待连接的到来

客户端套接字方法

s.connect(address)

连接到address处的套接字。address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。

s.connect_ex(address)同上,只不过会有返回值,连接成功时返回0,连接失败时候返回编码,而不是抛出一个异常。

普通的套接字方法

s.recv(bufsize[,flag])接收套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。flag提供有关消息的其他信息,通常可以忽略。
s.recv_into()
接收TCP消息到指定的缓存区。
sk.recvfrom(bufsize[.flag])与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
s.send(string[,flag])将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送 。
s.sendall(string[,flag])

将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。内部通过递归调用

send,将所有内容发送出去。

s.sendto(string[,flag],address)将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。该函数主要用于UDP协议。
s.close()关闭套接字
s.getpeername()返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)
s.getsockname()返回套接字自己的地址。通常是一个元组(ipaddr,port)

面向阻塞的套接字方法

s.setblocking(bool)是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错。
s.settimeout(timeout)

设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为

None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如 client 连接最多等待5s)

s.gettimeout()获取阻塞套接字操作的超时时间

面向文件的套接字方法

s.fileno()套接字的文件描述符
s.makefile()
创建套接字关联的文件对象
  • 创建TCP服务器与客户端

服务器端:

# !/usr/bin/env python# -*- coding:utf-8 -*-'''这个脚本创建TCP服务器,它接收来自客户端的消息并打印在终端,返回当前时间戳'''from socket import *from time import ctimeHOST = ''PORT = 12345BUFSIZ = 1024ADDR = (HOST,PORT)tcpSerSock = socket(AF_INET,SOCK_STREAM)tcpSerSock.bind(ADDR)tcpSerSock.listen(5)while True:    print('waiting for connection...')    tcpCliSock,addr=tcpSerSock.accept()    print('...connected from:',addr)    while True:        data=tcpCliSock.recv(BUFSIZ)        print(str(data,'utf-8'))        if not data:            break        tcpCliSock.send(bytes(ctime(),'utf-8'))    tcpCliSock.close()tcpSerSock.close()

客户端:

# !/usr/bin/env python# -*- coding:utf-8 -*-from socket import *HOST = '127.0.0.1'PORT = 12345BUFSIZ = 1024ADDR = (HOST,PORT)tcpCliSock = socket(AF_INET,SOCK_STREAM)tcpCliSock.connect(ADDR)while True:    data = input('> ')    if not data:        break    tcpCliSock.send(bytes(data,'utf-8'))    data = tcpCliSock.recv(BUFSIZ)    if not  data:        break    print(str(data,'utf-8'))tcpCliSock.close()

运行结果:

服务器端:

waiting for connection......connected from: ('127.0.0.1', 62735)1231234345345567

客户端:

> 123Sat May  6 21:31:06 2017> 1234Sat May  6 21:32:44 2017> 3453Sat May  6 21:32:46 2017> 45Sat May  6 21:32:47 2017> 567Sat May  6 21:32:48 2017>
  • 创建UDP客户端与服务器

服务器端:

#!/usr/bin/env python# -*- coding:utf-8 -*-from socket import *from time import ctime'''这个脚本创建UDP服务器,接收来自客户端的消息并打印在终端,返回当前时间戳'''HOST = ''PORT = 12345BUFSIZ = 1024ADDR = (HOST,PORT)udpSerSock = socket(AF_INET,SOCK_DGRAM)udpSerSock.bind(ADDR)while True:    print('waiting for message... ')    data,addr = udpSerSock.recvfrom(BUFSIZ)    print(str(data,'utf-8'))    udpSerSock.sendto(bytes(ctime(),'utf-8'),addr)    print('...received form and return to:',addr)udpSerSock.close()

客户端:

#!/usr/bin/env python# -*- coding:utf-8 -*-from socket import *HOST = 'localhost'PORT = 12345BUFSIZ = 1024ADDR = (HOST,PORT)udpCliSock = socket(AF_INET,SOCK_DGRAM)while True:    data=input('>')    if not data:        break    udpCliSock.sendto(bytes(data,'utf-8'),ADDR)    data,ADDR=udpCliSock.recvfrom(BUFSIZ)    if not data:        break    print(str(data,'utf-8'))udpCliSock.close()

输出结果:

服务器端:

waiting for message... 123...received form and return to: ('127.0.0.1', 58765)waiting for message... 12334...received form and return to: ('127.0.0.1', 58765)waiting for message... 123...received form and return to: ('127.0.0.1', 58765)waiting for message... 14...received form and return to: ('127.0.0.1', 58765)waiting for message... 234...received form and return to: ('127.0.0.1', 58765)waiting for message... 5...received form and return to: ('127.0.0.1', 58765)waiting for message...

客户端:

>123Sun May  7 11:59:46 2017>12334Sun May  7 12:02:32 2017>1231Sun May  7 12:02:33 2017>42Sun May  7 12:02:34 2017>34Sun May  7 12:02:34 2017>5Sun May  7 12:02:35 2017>
  • SocketServer模块

SocketServer是标准库中的一个高级模块,它的目的是简化很多样板代码,它们是创建网络客户端和服务器必须的代码。这个模块中有各种各样的类,这些类帮助程序员隐藏具体的实现细节,除此之外以面相对象的方式处理事务有助于组织数据,以及逻辑性地将功能放在正确的地方。在python3中SocketServer改名为socketserver。

各个类之间的继承关系:

| BaseServer |      |      v| TCPServer |------->| UnixStreamServer |      |      v| UDPServer |------->| UnixDatagramServer |


类描述

BaseServer

包含核心服务器功能和mix-in类的钩子,仅用于推导,这样不会创建这个类的实例:可以用TCPServer或UDPServer创建类的实例
TCPServer/UDPServer基于的网络同步TCP/UDP服务器

UnixStreamServer /

UnixDatagramServer

基于文件的基础同步TCP/UDP服务器


上面四个服务类都是同步处理请求的,即一个请求没处理完不能处理下一个请求。当要想支持异步模型,可以利用多继承让server类继承ForkingMixIn或ThreadingMixIn类。

类描述

ForkingMixIn/

ThreadingMixIn

核心派出或线程功能:只作用mix-in类域一个服务器类配合实现一些异步性;不能直接实例化。

ForkingTCPServer/

ForkingUDPServer

ForkingMixIn和TCPServer/UDPServer的组合,利用多进程实现异步
ThreadingTCPServer/

ThreadingUDPServer

ThreadingMixIn和TCPServer/UDPServer的组合,利用多线程实现异步

在SocketServer模块中,服务器处理请求主要通过BaseRequestHandler类来实现,在这个类中有多个处理函数可以使用。

setup()

在handle()方法之前调用执行请求的初始化动作,默认不执行任何操作。

handle()

此函数必须完成对服务器所有的请求工作,有些实例属性对其可获得,

请求通过self.request函数,

客户端地址通过self.client_address函数,

服务器实例通过self.server函数,

self.request对于流服务self.request是套接字对象,对于数据报文self.request是一系列字符串和套接字。

finish()

在handle()函数后调用此方法,执行请求后的清理操作,默认不执行任何操作,如果setup()出现异常,此函数不会被调用。

服务器端实例:

#!/usr/bin/env python# -*- coding:utf-8 -*-'''通过socketserver类、TCPServer和StreamRequestHandler,该脚本创建时间戳TCP服务器'''from  socketserver import (TCPServer as TCP, StreamRequestHandler as SRH)from time import ctimeHOST = ''PORT = 12345ADDR = (HOST,PORT)class MyRequestHandler(SRH):    def setup(self):        print('处理请求前!!!')    def handle(self):        conn=self.request        print('...connected from:',self.client_address)        print(str(conn.recv(1024),'utf-8'))        conn.send(bytes(ctime(),'utf-8'))    def finish(self):        print('处理请求后!!!')        print('----------------------')tcpServ = TCP(ADDR,MyRequestHandler)print('waiting for connection...')tcpServ.serve_forever()

客户端实例:

#!/usr/bin/env python# -*- coding:utf-8 -*-from socket import *HOST = 'localhost'PORT = 12345BUFSIZ = 1024ADDR = (HOST,PORT)while True:    tcpCliSock = socket(AF_INET,SOCK_STREAM)    tcpCliSock.connect(ADDR)    data=input('>')    if not data:        break    tcpCliSock.send(bytes(data,'utf-8'))    data=tcpCliSock.recv(BUFSIZ)    if not data:        break    print(str(data,'utf-8'))    tcpCliSock.close()

运行结果:

服务器端:

waiting for connection...处理请求前!!!...connected from: ('127.0.0.1', 62042)1223处理请求后!!!----------------------处理请求前!!!...connected from: ('127.0.0.1', 62051)123处理请求后!!!----------------------处理请求前!!!...connected from: ('127.0.0.1', 62052)5435处理请求后!!!----------------------处理请求前!!!...connected from: ('127.0.0.1', 62053)574处理请求后!!!----------------------处理请求前!!!...connected from: ('127.0.0.1', 62054)68处理请求后!!!----------------------

客户端:

>1223Sun May  7 13:01:45 2017>123Sun May  7 13:01:46 2017>5435Sun May  7 13:01:47 2017>574Sun May  7 13:01:48 2017>68Sun May  7 13:01:49 2017>


套接字 服务 服务器 客户 数据 处理 客户端 地址 函数 文件 类型 网络 通信 实例 方法 utf-8 就是 消息 多个 对象 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技工作委员会副主任毛军 互联网巨头反垄断金融科技 长亮科技 互联网金融 成都狮子座互联网科技 互联网科技生活的内容 佩信高科技互联网 开启互联网科技时代小说 云创客互联网科技公司 广州优美互联网科技 互联网教育科技公司vipkid 互联网与医疗科技 消费医药和互联网科技 西安小鹰速贷互联网科技有限公司 皮皮虾互联网科技有限公司 厦门江牛科技互联网 互联网科技数字货币 上海乐五互联网科技有限公司 张家口科技产业互联网平台 互联网科技博主张洲 杭州融税互联网科技有限公司 科技赋能下的互联网金融 圆梦互联网科技 互联网核心科技是什么 科技信息互联网 互联网和高科技公司 玖二柒互联网科技公司待遇 南山科技园互联网公司有哪些 滨湖区互联网智能科技产品有哪些 山东大美朱楼互联网科技有限公司 信承诺互联网科技有限公司
0