Python Socket实现聊天机器人收发消息失败及输入报NameError问题咨询
问题根因与修复方案
1. NameError 报错修复
- 触发原因:你当前使用Python 2版本运行脚本,Python 2 内置的
input()函数会将用户输入的内容直接作为Python表达式解析执行,你输入普通字符串hi、q时,解释器会将其识别为变量名,找不到对应变量自然抛出NameError。 - 修复方案二选一:
- 将代码中所有的
input()替换为raw_input(),这是Python 2中专门用于获取用户输入字符串的方法 - 改用Python 3运行脚本,Python 3的
input()默认返回字符串,不存在该问题
- 将代码中所有的
你之前观察到的两端消息无法收发的问题,本质也是因为input()报错导致代码提前终止,没有执行到消息发送的逻辑,修复输入函数问题后即可解决。
2. 双向消息收发与终止逻辑修复
你当前的代码除了输入函数的问题外,还存在两处逻辑缺陷,会导致连接断开后报错、终止流程异常:
- 服务端输入
q关闭连接后,没有退出while死循环,会继续执行recv()读取已关闭的连接,触发IO异常 - 未处理对端主动断开连接的场景,一端主动关闭后,另一端执行
recv()会收到空字节,需要做对应判断
修正后的服务端参考代码
from socket import * server_port = 7000 server_socket = socket(AF_INET,SOCK_STREAM) server_socket.bind(('',server_port)) server_socket.listen(10) print ("Welcome: The server is now ready to receive") connection_socket, address = server_socket.accept() while True: sentence = connection_socket.recv(2048).decode() # 对端断开连接时recv会返回空字符串,直接退出 if not sentence: print("Client has disconnected") break print('>> ',sentence) # Python2下用raw_input,Python3下用input message = raw_input(">> ") if(message == "q"): message = "Server Side Termination" print("Server is terminating from this end") connection_socket.send(message.encode()) connection_socket.close() # 关闭连接后退出循环 break else: connection_socket.send(message.encode()) server_socket.close()
修正后的客户端参考代码
from socket import * # 改成你自己服务端的实际IP server_name = '10.1.1.1' server_port = 7000 client_socket = socket(AF_INET, SOCK_STREAM) client_socket.connect((server_name,server_port)) while True: # Python2下用raw_input,Python3下用input sentence = raw_input(">> ") if(sentence == 'q'): sentence = "Client Side Termination" print("Client is terminating from this end") client_socket.send(sentence.encode()) client_socket.close() break else: client_socket.send(sentence.encode()) message = client_socket.recv(2048) # 对端断开连接时recv会返回空字节,直接退出 if not message: print("Server has disconnected") break print (">> ", message.decode()) client_socket.close()
内容的提问来源于stack exchange,提问作者Software Fan
相关产品推荐
相关产品推荐

