Python Socket Programming
admin
2023-07-31 00:45:46
0

本文介绍使用Python进行Socket网络编程,假设读者已经具备了基本的网络编程知识和Python的基本语法知识,本文中的代码如果没有说明则都是运行在Python 3.4下。

Python的socket功能封装在socket库中,要使用socket,记得先import socket,socket库的详细介绍参见官方文档。

创建Socket

首先创建一个socket,使用socket库中得socket函数创建。

12345 import socket # create an INET, STREAM sockets = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

例子中创建了一个TCP socket,socket.socket函数的前两个参数的默认值是socket.AF_INETsocket.SOCK_STREAM,创建TCP socket时可以直接写成socket.socket()

连接服务器

使用socket的connect函数连接到服务器,以下几种参数都是合法的。

1234 s.connect((\’localhost\’, 8000))s.connect((\’127.0.0.1\’, 8000))s.connect((\’www.baidu.com\’, 80)) 

发送数据

发送数据有两个方法send和sendall,send不能保证所有的数据都发送完了,它会返回已发送数据的长度,程序要循环发送数据直到所有数据都已发送完毕。

12345678 def mysend(s, msg):    total_len = len(msg)    total_sent = 0    while total_sent < total_len:        sent = s.send(msg[total_sent:])        if sent == 0:            raise RuntimeError(\”socket connection broken\”)        total_sent += sent

sendall能够保证所有的数据都已发送完毕,除非发送过程中出现了错误,它实际上也是循环发送数据直到所有数据发送完成。

这里还要讲一个需要特别注意的地方,从一个例子开始吧:

12345 import sockets = socket.socket()s.connect((\’www.baidu.com\’, 80))s.sendall(\’test\’) 

都是上面讲过的东西,没什么特别的,分别在Python 2和Python 3中执行以上的代码,结果是:

123456 # Python 2.7>>> import socket>>> s = socket.socket()>>> s.connect((\’www.baidu.com\’, 80))>>> s.sendall(\’test\’) 

Python 2中执行成功。

12345678 # Python 3.4>>> import socket>>> s = socket.socket()>>> s.connect((\’www.baidu.com\’, 80))>>> s.sendall(\’test\’)Traceback (most recent call last):  File \”\”, line 1, in <module>TypeError: \’str\’ does not support the buffer interface

Python 3中却发生了异常。

同样的代码换个环境却不能执行了,我没有写错呀,怒砸电脑。好吧,你确实没写错,是环境变了,导致这个结果的变化请移步官方的说明。

接收数据

使用recv函数接收数据:

12 data = s.recv(4096) 

在Python 3中返回的是bytes对象,在Python 2中返回的是string。注意函数返回的数据长度是小于或者等于参数指定的长度的,要接收到指定长度的数据,需要循环接收数据。

12345678910 def myreceive(s, msglen):    chunks = []    bytes_recd = 0    while bytes_recd < msglen:        chunk = s.recv(min(msglen bytes_recd, 2048))        if chunk == b\’\’:            raise RuntimeError(\”socket connection broken\”)        chunks.append(chunk)        bytes_recd = bytes_recd + len(chunk)    return b\’\’.join(chunks)

关闭连接

当连接不再需要时可以使用close关闭socket连接,关闭后的连接不能再进行任何操作。当一个socket被回收时会自动关闭,但是不要依赖这种机制,不需要socket时就主动的close。

服务端

服务端程序执行的步骤:
1. 创建服务端socket
1. 将服务端socket绑定到指定的地址和端口
1. 监听连接
1. 接受客户端连接
1. 处理客户端的数据
1. 关闭客户端连接

一个简单的echo server示例:

12345678910111213141516 import socket HOST = \’\’PORT = 10022 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.bind((HOST, PORT))s.listen(10)conn, addr = s.accept()while True:    data = conn.recv(1024)    if not data:        break    conn.sendall(data)conn.close() 

客户端程序:

123456789101112 import socket HOST = \’localhost\’PORT = 10022 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect((HOST, PORT))s.sendall(b\’hello socket\’)data = s.recv(1024)print(\’Received\’, repr(data))s.close() 

错误处理

socket处理过程中发生错误会抛出异常,socket相关的异常有:
– socket.error
– socket.herror
– socket.gaierror
– socket.timeout

123456789101112 Python</code><code>import socket HOST = NonePORT = 10022 try:    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    s.bind((HOST, PORT))    s.listen(10)except: socket.error as msg:    print(msg) 

参考资料

  • Socket Programming HOWTO
  • Porting Python 2 Code to Python 3

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
python清除字符串里非数字... 本文实例讲述了python清除字符串里非数字字符的方法。分享给大家供大家参考。具体如下: impor...