本文举例说明socket模块的应用,使用python3。
首先举一个简单的例子实现socket_server端与socket_client端的连接。
socket_server端:
__author__ = "Allen Liu"
__time__ = "2017/8/9"
'''This is a socket_serer used by socket module. '''
import socket #导入socket模块
# 首先创建一个socket对象
s1 = socket.socket()
# 将该socket对象绑定到指定地址
s1.bind(('127.0.0.1',9999))# 127.0.0.1为本机地址,用于本机测试
# 使用listen方法监听连接请求
s1.listen(2)#默认为阻塞状态,就是说在监听到连接之后才向后执行。
# 利用accept方法与请求客户端建立连接
q, v = s1.accept()# 返回q为一个套接字,通过这个套接字与客户端通信
# 向客户端发送一个确认信息
q.send(b'The connection was established!')# python3中只能以byte格式传输
# 传输结束,用close方法关闭连接
s1.close()
socket_client端:
__author__ = "Allen Liu"
__time__ = "2017/8/9"
'''This is a socket_client used by socket module '''
import socket # 导入socket模块
# 创建一个socket对象
s1 = socket.socket()
# 使用connect方法尝试连接服务器
s1.connect(('127.0.0.1',9999))
# 建立连接后使用recv方法接收来自server的确认信息
receive = s1.recv(1024)# 1024为最大的可接受消息长度
# 打印出接收到的确认信息
print(receive)
# 结束时关闭连接
s1.close()
下面将创建一个简单的server端的步骤进行归纳:
1. 第一步是创建socket对象。调用socket构造函数。如:
s1 = socket.socket( family, type )
family参数代表地址家族,可为AF_INET或AF_UNIX。AF_INET家族包括Internet地址,AF_UNIX家族只能够用于单一的Unix系统进程间通信。type参数代表套接字类型,可为SOCK_STREAM(流套接字)和SOCK_DGRAM(数据报套接字)。
2. 第二步是通过bind方法将socket绑定到指定地址:
s1.bind( address )
address地址必须是一个双元素元组,格式是(host,port)。host代表主机名或者IP地址,port代表端口号。端口数值的取值范围是0~65535。端口数小于1024的都是为众所周知的网络服务所保留的 (例如Web服务使用的80端口),建议使用大于1024的端口号进行测试,如果端口号正在使用、主机名不正确或端口已被保留,bind方法将引发socket.error异常。
3. 第三步是使用socket套接字的listen方法接收连接请求。
s1.listen( backlog )
backlog是一个正整数,指定最多允许多少个客户连接到服务器,默认为1。收到连接请求后,这些请求需要排队,如果队列满,就拒绝请求。
4. 第四步是服务器套接字通过socket的accept方法与请求客户端建立一个连接。
connection, address = socket.accept()
客户端请求连接时,方法建立连接并返回服务器。accept方法返回一个含有两个元素的元组(connection,address)。第一个元素connection是新的socket对象,服务器必须通过它与客户通信;第二个元素 address是客户的Internet地址。
5. 第五步是处理阶段,服务器调用send方法向客户端发送一个确认效益,python3只能发送byte型数据,注意数据格式的转换。send方法返回已发送的字符个数。服务器使用recv方法从客户接收信息。调用recv 时,服务器可以指定一个整数,它对应于可通过本次方法调用来接收的最大数据量。recv方法在接收数据时会进入“blocked”状态,最后返回一个byte型数据,用它表示收到的数据。
6. 传输结束,服务器调用socket的close方法关闭连接。
创建client端的步骤:
1. 创建一个socket以连接服务器:
s1 = socket.socket( family, type )
2.使用socket的connect方法连接服务器:
socket.connect( (host,port) )、
host代表服务器主机名或IP,port代表服务器进程所绑定的端口号。如连接成功,客户就可通过套接字与服务器通信,如果连接失败,会引发socket.error异常。
3. 处理阶段,客户和服务器将通过send方法和recv方法通信。
4. 传输结束,客户通过调用socket的close方法关闭连接。
__author__ = "Allen Liu"
__time__ = "2017/8/9"
'''This is a socket_serer used by socket module. '''
import socket #导入socket模块
s1 = socket.socket()
s1.bind(('127.0.0.1',9999))
s1.listen()
q, v = s1.accept()
receive = q.recv(1024)
print('You have %s times to guess the answer!' % receive.decode())
try:
while True:
ans = input('Please input your answer:')
q.send(ans.encode())
receive = q.recv(1024).decode()
if receive == 'You got it!':
print('You win the game!')
break
elif receive == 'You loss the game!':
print('You loss the game!')
else:
print(receive)
except ConnectionAbortedError:
print('You loss the game!')
s1.close()
client端:
__author__ = "Allen Liu"
__time__ = "2017/8/9"
'''This is a socket_client used by socket module '''
import socket # 导入socket模块
answer = int(input('Please input the answer (1-100):'))
times = input('How many times you want she/he to guess:')
reply = ['The answer is a smaller one...', 'The answer is a bigger one... ',\
'You got it!']
c1 = socket.socket()
c1.connect(('127.0.0.1',9999))
c1.send(times.encode())
guess_time = 0
while True:
guess_time += 1
receive = int((c1.recv(1024).decode()))
if receive == answer:
c1.send(reply[2].encode())
print('He/She wins the game!')
break
elif receive > answer and guess_time < int(times):
c1.send(reply[0].encode())
elif receive < answer and guess_time < int(times):
c1.send(reply[1].encode())
else:
c1.send(b'You loss the game!')
print('He/She losses the game!')
break
c1.close()