一个简单的 Python Socket 编程实例
Python 编写 Server 端的步骤
第一步:创建 socket 对象
调用 socket 构造函数,如:
socket = socket.socket( family, type )
- family 参数代表地址家族,可以为
AF_INET或者AF_UNIX,AF_INET 家族包括 Internet 地址,AF_UNIX 家族则用于同一台机器上的进程间通信 - type 参数代表套接字类型,可以为
SOCK_STREAM(流套接字) 或者SOCK_DGRAM(数据报套接字)。
第二步:将 socket 绑定到指定地址
这是通过 socket 对象的 bind 方法来实现的:
socket.bind( address )
由 AF_INET 创建的套接字, address 必须是一个双元素无组,格式是 ( host, port ),host 代表主机, port 代表端口号,如果端与正在使用,主机名不正确或者商品端口已被保留, bind 方法将引发 socket.error 异常。
第三步:使用 listen 套接字的 listen 方法接收连接请求
socket.listen( backlog )
backlog 指定最多允许多少个客户连接到服务器,它的值至少为 1,收到连接请求后,这些请求需要排队,如果队列已满,就拒绝请求。
第四步:服务器套接字通过 socket 的 accept() 方法等待客户请求一个连接
connection, address = socket.accept()
调用 accept 方法时, socket 会进入 “waiting” 状态,客户请求连接时,方法建立连接并返回服务器, accept 方法返回一个含有两个元素的元组(connection, address),第一个元素 connection 是新的 socket 对象,服务器必须通过它与客户通信;第二个元素 address 是客户的 Internet 地址。
第五步:处理
服务器和客户端通过 send 和 recv 方法通信(传输数据)。服务器调用 send ,并采用字符串形式向客户发送信息,send 方法返回已发送的字符个数,服务器使用 recv 方法从客户端接收信息,调用 recv时,服务器必须指定一个整数,它对应于可通过本次方法调用来接收的最大数据量。 recv 方法在会进入“blocked”状态,最后返回一个字符串,用它表示接收到的数据,如果发送的数据量超过了 recv 所允许的数据会被截取,多余的数据将缓冲于接收端,以后调用 recv 时,多余的数据会从缓冲区删除(以及上次调用 recv 以来,客户可能发送的其它任何数据)。
第六步:传输结束
服务器调用 socket 的 close 方法关闭连接
Python 编写客户端的步骤
第一步:创建一个 socket 以连接服务器
socket = socket.socket( family, type)
第二步:使用 socket 的 connect 方法连接服务器
对于 AF_INET 家族,连接格式如下:
socket.connect(( host, port ))
host 代表服务器的主机名或者 IP, port 代表服务器进程所绑定的端口号,如果连接成功,客户端就可以与服务器进行通信了,如果连接失败,会引发 socket.error异常
第三步:处理阶段
客户和服务器将通过 send 方法和 recv 方法通信
第四步:传输结果
客房端通过 socket 的 close 方法关闭连接
整个示例的完整代码
server.py 文件
#!/usr/bin/env python
# encoding: utf-8
"""
File: server.py
Created by Pan Tao on 2011-09-20.
Copyright (c) 2011 CosTony.Com. All rights reserved.
"""
def main():
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 8000))
sock.listen(5)
while True:
connection, address = sock.accept()
try:
connection.settimeout(5)
buf = connection.recv(1024)
if buf == '1':
print 'Client {} connected to server!'.format(address)
connection.send('Welcome to server!')
else:
connection.send('Please go out!')
except socket.timeout:
print 'Time out!'
connection.close()
if __name__ == '__main__':
main()
client.py 文件
#!/usr/bin/env python
# encoding: utf-8
"""
File: client.py
Created by Pan Tao on 2011-09-20.
Copyright (c) 2011 CosTony.Com. All rights reserved.
"""
def main():
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 8000))
import time
time.sleep(2)
sock.send('1')
print sock.recv(1024)
sock.close()
if __name__ == '__main__':
main()
测试运行
我们先运行 server.py 以开启服务器
python server.py
然后运行 client.py 连接服务器
python client.py
运行结果:
Server 端将打印出:
Client ('127.0.0.1', 56933) connected to server!
客户端将打印出:
Welcome to server!