socket实现简单的服务器端和客户端的交互
程序员文章站
2022-07-01 08:02:18
...
基于socket在本机上实现最简单的服务器端和客户端的交互,在实现过程中遇到问题:
服务器端和客户端都在运行的时候,客户端突然停止,服务器端会报错:
Traceback (most recent call last):
File "E:/python_learn/python_cord/day29/服务器.py", line 41, in <module>
data=conn.recv(buffer_size)#收消息
ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。
代码如下:
服务器端
#import socket
#当写import socket时,下面需要写成socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#可以用from socket import *,此时下面可以写成socket(AF_INET,SOCK_STREAM)
from socket import *
ip_port=('127.0.0.1', 8000)
back_log=5
buffer_size=1024
tcp_server=socket(AF_INET, SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)
print('服务端开始运行')
conn,addr=tcp_server.accept()#服务器端阻塞
print('双向连接是',conn)
print('客户端地址是',addr)
while True:
print('服务器开始运行了')
data=conn.recv(buffer_size)#收消息
print('客户端发来的消息',data)
conn.send(data.upper())
conn.close()#socket关闭掉
tcp_server.close()
客户端
import socket
tcp_client=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_client.connect(('127.0.0.1', 8000))
while True:
msg=input('>>:').strip()
tcp_client.send(msg.encode('utf-8'))
data=tcp_client.recv(1024)
print('收到服务器端发来的消息:',data)
产生错误原因分析:
在客户端断掉之后,服务器端的本次conn异常结束,data=conn.recv(buffer_size)接收不到东西。程序抛出异常。
优化(解决办法)
虽然我们设置了接收池back_log为5,但是我们的tcp_server.accept()只有一个。意味着只能接收一次connect。接收完之后就开始跟这一次的connect进行通信,通信完成之后就关闭掉了。此时服务器端只服务一个人。但是服务器端的目的是循环服务很多人。简单来说来一个链接就能接收住。
当本次conn异常结束后,会抛出异常。我们可以用python提供的异常处理来抓住此次异常,并使用break结束此次的循环,让它可以再等待下一个客户端消息得到来。
改进后代码:
#服务器端
from socket import *
ip_port=('127.0.0.1', 8000)
back_log=5
buffer_size=1024
tcp_server=socket(AF_INET, SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)
while True:
conn, addr = tcp_server.accept() # 服务器端阻塞
print('双向连接是', conn)
print('客户端地址是', addr)
while True:
print('服务器开始运行了')
try:
data=conn.recv(buffer_size)#收消息
print('客户端发来的消息',data)
conn.send(data.upper())
except Exception:
print('=====')
break
data=conn.recv(buffer_size)#收消息
print('客户端发来的消息',data)
conn.send(data.upper())
conn.close()#socket关闭掉
tcp_server.close()
外层循环的目的:使服务器可以为多个客户端提供服务
里层循环的目的:使服务器可以完成对同一个客户端发送的多条消息的收发工作