第八章 socket网络编程(5):客户端与服务端代码bug修复(代码完善)

到上一篇位置我们写的代码虽然可以执行,但是还有很多潜在的bug

  • 各种问题的解决
    • 端口重用:有时候服务端关掉了依然端口被占用,原因是OS回收端口需要时间,这时候有2中解决方法:
      • .setsockopt方法实现端口重用
      • Linux OS的情况下:修改Linux的系统设置
    • 客户端发送空字符串的时候,会卡在客户端的recv步骤上,因为服务端收不到东西所以也不会回复客户端

      原理: 应用程序必须经过OS来发送和收取数据,所以实质上send和recv是把数据和自己的OS内存进行交互数据。然后OS来依照协议处理信息的通信。 当客户端发送数据的时候,空数据经过追加报头发给服务端是做到了,但是服务端应用从OS内存中获取数据的时候却什么也没有 相当于服务端并没有收到东西,所以也不会向客户端发送数据。

      • 需要避免客户端发空数据
    • 当客户端强制终止(即conn双向的连接的套接字对象有一边断开),
      • Linux:服务端就会无限自娱自乐(一直收空字节的死循环)
      • Windows会报错:ConnectionResetError

server.py

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)  

print('starting...')  
conn, client_addr = phone.accept()  

#5 收,发消息(传数据)
while True:
    try:  # windows的情况会报错,所以我们需要异常处理
        data = conn.recv(1024)
        if not data : break  # 避免服务端的死循环:Linux的情况下
        print('客户端的数据',data)
        conn.send(data.upper())
    except ConnectionResetError:
        break
    
conn.close() 
phone.close()  

client.py

import socket

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  

phone.connect(('127.0.0.1',8080))

#3 发,收消息
while True:
    msg = input('>>> : ').strip()
    if not msg : continue  # 避免客户端发空数据(这个写法留意一下)
    phone.send(msg.encode('utf-8'))
    data = phone.recv(1024)
    print(data)

phone.close()

猜你喜欢

转载自www.cnblogs.com/py-xiaoqiang/p/11298981.html