嘘~ 正在从服务器偷取页面 . . .

网络通信编程学习(2)—— 基于SOCKET简单套接字通信的 bug 修复


目前实现的添加了通信循环的套接字通信的一些问题

客户端向服务端发送消息时发现地址已被使用

在我们重启服务端时,可能会遇到这样的问题
在这里插入图片描述
当我们遇到这个问题时,可以在编写服务端代码时加入 一条 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系统解决方案那个代码才解决了问题。

原因至今也没有找到,如果有知道的大佬看到了我的这篇水平不怎么样的文章,希望可以抽出一点点时间帮忙解答,谢谢。


文章作者: New Ass
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 New Ass !
  目录