我问了一个有关服务器到客户端代码的问题,因为我遇到了很多问题,有人告诉我,解决我遇到的问题的方法是进行对等聊天,现在已经完成了。
import socket, threading
host = "127.0.0.1"
port = 4000
s = socket.socket()
s.bind((host,port))
s.listen(5)
client_sockets = []
users = []
print("Listening")
def handle_client(conn):
while True:
try:
data = conn.recv(512)
for x in client_sockets:
try:
x.send(data)
except Exception as e:
print(e)
except:
pass
while True:
conn,addr = s.accept()
client_sockets.append(conn)
print("Connections from", addr[0], "on port",addr[1])
threading.Thread(target = handle_client,args = (conn,)).start()
import socket,threading
host = "127.0.0.1"
port = 4000
s = socket.socket()
s.connect((host,port))
def echo_data(sock):
while True:
try:
data = sock.recv(512)
print(data)
except:
pass
while True:
threading.Thread(target=echo_data,args=(s,)).start()
msg = input("Enter your message : ")
s.send(msg.encode())
问题是,当我运行客户端并尝试与另一个客户端通信时,除非另一个客户端按下回车键,否则不会发送消息,这也使我遇到第二个问题,即当客户端彼此发送消息时,以这种格式接收:
b'hi'Enter your message :
答案 0 :(得分:1)
我将从与该问题不直接相关的一般问题入手:
except: pass
通常不是一个好主意,尤其是在出现问题时,因为它会隐藏潜在有用的消息。该语言允许使用,但绝对不能存在于真实代码中中,每条消息启动一个接收线程,而整个客户端只需要一个。您应该在循环外启动线程:
threading.Thread(target=echo_data,args=(s,)).start()
while True:
msg = input("Enter your message : ")
s.send(msg.encode())
现在开始提问:
除非其他客户端点击回车,否则不会发送消息
它可能是由IDE引起的。具体来说,已知IDLE在多线程脚本中表现不佳。如果您正确使用一个接收线程并从命令行(python client.py
)启动脚本,则脚本应该正常工作
消息以以下格式接收:b'hi'Enter your message
sock.recv(sz)
返回一个字节字符串。您需要对其进行解码以将其转换为Python 3 unicode字符串:
data = sock.recv(512)
print(data.decode())
但这还不是全部。可以进行测试,但是您至少应允许客户端与服务器断开连接,并在断开连接后将其从client_sockets
中删除。而且通常不将消息发送回发件人。因此,您可以改善server.py循环:
while True:
try:
data = conn.recv(512)
for x in client_sockets:
if x != conn: # do not echo to sender
x.send(data)
except Exception as e: # problem in connection: exit the loop
print(e)
break
# clear the connection
conn.close()
client_sockets.remove(conn)