本文介绍使用Python进行Socket网络编程,假设读者已经具有了基本的网络编程知识和Python的基本语法知识,本文中的代码若是没有说明则都是运行在Python 3.4下。html
Python的socket功能封装在socket库中,要使用socket,记得先import socket
,socket库的详细介绍参见官方文档。
python
首先建立一个socket,使用socket库中得socket函数建立。编程
Pythonimport 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
函数链接到服务器,如下几种参数都是合法的。网络
Pythons.connect(('localhost', 8000)) s.connect(('127.0.0.1', 8000)) s.connect(('www.baidu.com', 80))
发送数据有两个方法send和sendall,send
不能保证全部的数据都发送完了,它会返回已发送数据的长度,程序要循环发送数据直到全部数据都已发送完毕。app
Pythondef 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
可以保证全部的数据都已发送完毕,除非发送过程当中出现了错误,它实际上也是循环发送数据直到全部数据发送完成。socket
这里还要讲一个须要特别注意的地方,从一个例子开始吧:函数
Pythonimport socket s = socket.socket() s.connect(('www.baidu.com', 80)) s.sendall('test')
都是上面讲过的东西,没什么特别的,分别在Python 2和Python 3中执行以上的代码,结果是:code
Python# Python 2.7 >>> import socket >>> s = socket.socket() >>> s.connect(('www.baidu.com', 80)) >>> s.sendall('test')
Python 2中执行成功。server
Python# 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
函数接收数据:
Pythondata = s.recv(4096)
在Python 3中返回的是bytes对象,在Python 2中返回的是string。注意函数返回的数据长度是小于或者等于参数指定的长度的,要接收到指定长度的数据,须要循环接收数据。
Pythondef 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示例:
Pythonimport 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()
客户端程序:
Pythonimport 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
Pythonimport 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)