python之socket编程举例

来源:互联网 发布:哈尔滨学院教务网络 编辑:程序博客网 时间:2024/06/14 16:02

本文举例说明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方法关闭连接。

上面的例子建立连接后只发送了一条确认消息后就断开了,下面我们用socket实现一个猜数字的游戏,我们想要达到的预期是这样的:
假设有两个玩家1,2分别为client端和server端。玩家1在client端输入一个在1-100的数字,并规定玩家2最多可以猜多少次;玩家2在server端,输入自己猜的数字,如果猜的数
字不对并且猜的次数没有超出玩家1规定的次数,会收到一条提示信息。如果在规定次数内猜中则赢得比赛,否则玩家2本次游戏尝试失败。

代码如下:
server端:
__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 = 0while 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!')        breakc1.close()