PythonSocketProgramming

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

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

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

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

import socket

# create an INET, STREAM socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

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

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

s.connect(('localhost', 8000))

s.connect(('127.0.0.1', 8000))

s.connect(('www.baidu.com', 80))

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

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

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

import socket

s = socket.socket()

s.connect(('www.baidu.com', 80))

s.sendall('test')

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

# Python 2.7

>>> import socket

>>> s = socket.socket()

>>> s.connect(('www.baidu.com', 80))

>>> s.sendall('test')

Python 2中执行成功。

# Python 3.4

>>> import socket

>>> s = socket.socket()

>>> s.connect(('www.baidu.com', 80))

>>> s.sendall('test')

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

TypeError: 'str' does not support the buffer interface

Python 3中却发生了异常。

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

接收数据使用recv函数接收数据:

data = s.recv(4096)

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

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。

服务端服务端程序执行的步骤:

创建服务端socket

将服务端socket绑定到指定的地址和端口

监听连接

接受客户端连接

处理客户端的数据

关闭客户端连接一个简单的echo server示例:

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()

客户端程序:

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.timeoutimport socket

HOST = None

PORT = 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

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航