目前实现的添加了通信循环的套接字通信的一些问题
客户端向服务端发送消息时发现地址已被使用
在我们重启服务端时,可能会遇到这样的问题
当我们遇到这个问题时,可以在编写服务端代码时加入 一条 socket 配置,重新使用 IP 和 端口。
phone=socket(AF_INET,SOCK_STREAM)
phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #在bind前加
phone.bind(('127.0.0.1',8080))
发空消息时程序进入死循环
除了地址已被使用的错误,我们发现当客户端发送消息时直接发送,即什么都不输入就敲回车,会导致服务端和客户端直接卡在循环中,即只能看到光标在闪动。如下图:
考虑到是发送了空信息,即" "
的消息,所以我们想到的第一个解决方案是在客户端输入要发送的消息时判断发送的消息是否为空。即:
if not data:
continue
这里要注意的,除了客户端需要判断消息是否为空,服务端也是要判断消息是否为空,否则在运行时我们就会看到这样的运行结果:
所以我们对于服务端的优化代码如下:
while True: # 通信循环
try:
data = conn.recv(1024)
print(data)
if not data: # 若客户端发送的信息为空
break
print("客户端发送的消息:", data)
conn.send(data.upper())
except ConnectionResetError:
break
代码优化
所以我们考虑到这些小 Bug 后优化的服务端和客户端代码如下:
服务端
import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 表示端口可以重复使用
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
conn, client_addr = phone.accept()
while True: # 通信循环
try:
data = conn.recv(1024)
print(data)
if not data: # 若客户端发送的信息为空
break
print("客户端发送的消息:", data)
conn.send(data.upper())
except ConnectionResetError:
break
conn.close()
phone.close()
客户端
import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080))
while True: # 通信循环
msg = input(">>: ").strip()
if not msg: # 防止发送的信息为空
continue
phone.send(msg.encode("utf-8"))
data = phone.recv(1024)
print(data.decode("utf-8"))
phone.close()
运行结果
服务端
客户端
不知道原因的小坑
有一点需要说明,按照我学的课程是讲,windos系统下的服务端这样写就可以解决一直循环的问题
while True: # 通信循环
try:
data = conn.recv(1024)
print(data)
print("客户端发送的消息:", data)
conn.send(data.upper())
except ConnectionResetError:
break
而上述优化后的代码中
if not data: # 若客户端发送的信息为空
break
是linux系统下的解决方案
但不知道为什么我按照Windows系统的解决方案服务端仍然陷入了循环,加上了Linux系统解决方案那个代码才解决了问题。
原因至今也没有找到,如果有知道的大佬看到了我的这篇水平不怎么样的文章,希望可以抽出一点点时间帮忙解答,谢谢。