同时发送/接收消息套接字python
Posted
技术标签:
【中文标题】同时发送/接收消息套接字python【英文标题】:Send/Receive messages at the same time socket python 【发布时间】:2019-07-04 09:14:11 【问题描述】:我一直在开发一个简单的 python 套接字聊天室,客户端和服务器可以在其中相互发送消息。我遇到的问题是服务器和客户端一次只能发送一条消息。我希望它像任何其他聊天室一样工作,我可以在发送消息时收到消息,任何帮助都会有很大帮助
服务器.py
import socket
import sys
s = socket.socket()
host = socket.gethostname()
print(" server will start on host : ", host)
port = 8080
s.bind((host,port))
name = input(str("Please enter your username: "))
print("")
print("Server is waiting for incoming connections")
print("")
s.listen(1)
conn, addr = s.accept()
print("Recieved connection")
print("")
s_name = conn.recv(1024)
s_name = s_name.decode()
print(s_name, "has joined the chat room")
conn.send(name.encode())
while 1:
message = input(str("Please enter your message: "))
conn.send(message.encode())
print("Sent")
print("")
message = conn.recv(1024)
message = message.decode()
print(s_name, ":" ,message)
print("")
客户端.py
import socket
import sys
s = socket.socket()
host = input(str("Please enter the hostname of the server : "))
port = 8080
s.connect((host,port))
name = input(str("Please enter your username : "))
print(" Connected to chat server")
s.send(name.encode())
s_name = s.recv(1024)
s_name = s_name.decode()
print("")
print(s_name, "has joined the chat room ")
while 1:
message = s.recv(1024)
message = message.decode()
print(s_name, ":" ,message)
print("")
message = input(str("Please enter your message: "))
message = message.encode()
s.send(message)
print("Sent")
print("")
【问题讨论】:
再一次,错误地使用了 tcp 套接字。您不能以这种方式使用消息。 @Daniel 你是什么意思? @Daniel 我该如何解决这个问题? 使用协议。 @Daniel 你说的协议是什么意思? 【参考方案1】:CaSper 为我提供了多个客户端可以连接到服务器的服务器代码,但现在的问题是客户端无法相互通信……
这主要是因为您的客户需要s_name = s.recv(1024)
,而 CaSper 的服务器不发送其名称。这是您的客户端的一种变体(期望 host 和 port 作为命令参数),它与 CaSper 的服务器一起使用,还解决了您的原始问题(客户端只能发送一条消息一次)通过使用单独的线程:
import socket
import sys
s = socket.socket()
s.connect((sys.argv[1], int(sys.argv[2])))
name = input(str("Please enter your username : "))
print(" Connected to chat server")
s.send(name.encode())
def receive_and_print():
for message in iter(lambda: s.recv(1024).decode(), ''):
print(":", message)
print("")
import threading
background_thread = threading.Thread(target=receive_and_print)
background_thread.daemon = True
background_thread.start()
while 1:
s.send(input("Please enter your message: ").encode())
print("Sent")
print("")
注意CaSper的服务器有一系列不足:
-
即使您的客户端可以随时发送消息,服务器也会等待一个一个客户端的消息,即。 e.当它等待客户端A时,客户端B可以发送消息,但是服务器只有在客户端A发送了一些东西后才接收并广播它。
它不处理客户端断开连接。
当所有客户端断开连接时,它会进入繁忙循环。
有关更好的服务器示例,请参阅问题Handle multiple requests with select。
…你能不能改变我的服务器让它工作…
这是与此客户端一起使用的服务器的一个变体,也使用单独的线程进行输入和接收:
import socket
import sys
s = socket.socket()
host = socket.gethostname()
print(" server will start on host : ", host)
port = 8080
s.bind((host,port))
name = input(str("Please enter your username: "))
print("")
print("Server is waiting for incoming connections")
print("")
s.listen(1)
conn, addr = s.accept()
print("Recieved connection")
print("")
s_name = conn.recv(1024)
s_name = s_name.decode()
print(s_name, "has joined the chat room")
def input_and_send():
while 1:
message = name+" : "+input(str("Please enter your message: "))
conn.send(message.encode())
print("Sent")
print("")
import threading
background_thread = threading.Thread(target=input_and_send)
background_thread.daemon = True
background_thread.start()
for message in iter(lambda: conn.recv(1024).decode(), ''):
print(s_name, ":", message)
print("")
【讨论】:
我需要为服务器更改什么吗? @system123456 - 你的意思是哪个服务器 - 你的、CaSper 的还是链接问题中的那个? 当我使用您提供的客户端代码和 CaSper 服务器代码时,它仍然不允许我向其他客户端发送消息 @system123456 - 当我使用它们时,它会。您是否使用正确的主机名和服务器端口启动客户端?您是否考虑到上述缺陷?这意味着 e。 G。其他客户端可能必须在接收和广播一个客户端的消息之前发送消息。当然我不推荐使用 CaSper 的服务器。 使用 CaSper 的服务器可能会导致此问题,所以请您更改我的服务器以使其正常工作【参考方案2】:您是否尝试过使用线程模块或时间模块。发生这种情况是因为两个脚本同时发送消息。试试 Ex(客户端首先从服务器等待消息,然后客户端向服务器发送消息)。
【讨论】:
我已经看过了,但我只是不知道如何在我的代码中实现它,您可以告诉我如何实现吗? 当我运行服务器并运行客户端时,服务器说他们已经连接,但我如何才能让客户端可以一起交谈?【参考方案3】:这是服务器
import socket
import threading as th
def accept_client():
while True:
# ACCEPTING
cli_sock, cli_add = ser_sock.accept()
uname = cli_sock.recv(1024)
CONN_LIST.append((uname, cli_sock))
print('%s is now connected' %uname)
def broadcast_usr():
while True:
for i in range(len(CONN_LIST)):
try:
data = CONN_LIST[i][1].recv(1024)
if data:
b_usr(CONN_LIST[i][1], CONN_LIST[i][0], data)
except Exception as x:
print(x.message)
break
def b_usr(cs_sock, sen_name, msg):
for i in range(len(CONNECTION_LIST)):
if (CONN_LIST[i][1] != cs_sock):
CONN_LIST[i][1].send(sen_name)
CONN_LIST[i][1].send(msg)
if __name__ == "__main__":
CONN_LIST = []
# SOCKET
ser_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# BINDING
host = '192.168.x.x' #LOCAL HOST
port = 4444
ser_sock.bind((host, port))
# LISTENING
ser_sock.listen(1)
print('Chat server started on port : ' + str(port))
thread_ac = th.Thread(target = accept_client)
thread_ac.start()
thread_bs = th.Thread(target = broadcast_usr)
thread_bs.start()
【讨论】:
… in b_usr for i in range(len(CONNECTION_LIST)): NameError: global name 'CONNECTION_LIST' is not defined
以上是关于同时发送/接收消息套接字python的主要内容,如果未能解决你的问题,请参考以下文章