多个客户端不能同时监听和写入
multiple clients cannot listen and write at the same time
我正在 python 中编写一个非常基本的聊天室。客户端连接并且来自客户端的任何消息都被中继到所有客户端。我遇到的问题是让客户端同时收听和发送消息。它似乎只做任何一个。我已经设置了一个单独的监听客户端并确认消息已收到但监听服务器无法发送任何内容。
目前客户端必须先发送数据才能得到服务器的响应,但我希望客户端能够在发送之前接收到数据——否则聊天室将无法工作。我尝试使用 clientsock.settimeout() 然后使用 recv 但它没有解决问题,因为它没有移过输入部分。
server.py
#!/usr/bin/python
#socket server using threads
import socket, sys, threading
from _thread import *
HOST = 'localhost'
PORT = 2222
lock = threading.Lock()
all_clients = []
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print ("Socket created")
#bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print ("Bind failed. Error code: " + str(msg[0]) + ' Message ' + msg[1])
sys.exit(0)
print ("Socket bind complete")
#Start listening on socket
s.listen(5)
print ("Socket now listening")
#function for handling connections. This will be used to create threads
def clientthread(conn):
#sending message to connected client
conn.send("Welcome to the server. Type something and hit enter\n".encode('utf-8'))
#infinite loop so that function does not terminate and thread does not end
while True:
#receiving data from client
data = conn.recv(1024)
reply = "OK..." + str(data, "utf-8")
if not data:
break
with lock:
for c in all_clients:
c.sendall(reply.encode('utf-8'))
#came out of loop
conn.close()
#keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
with lock:
all_clients.append(conn)
print ("Connected with " + addr[0] + ":" + str(addr[1]))
#start new thread takes 1st argument as a function name to be run, second
#is the tuple of arguments to the function
start_new_thread(clientthread ,(conn,))
s.close()
client.py
#!/usr/bin/python
import socket, sys
#client to transfer data
def main():
#create tcp stocket
clientsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#connect the socket to the server open port
server_address = ('localhost', 2222)
print ("connecting to %s port %s" % server_address)
clientsock.connect(server_address)
#receive data
data = clientsock.recv(1024)
print(str(data, "utf-8"))
while 1:
#send data
message = "sean: " + input()
clientsock.send(message.encode('utf-8'))
#look for the response
amount_received = 0
amount_expected = len(message)
while amount_received < amount_expected:
data = clientsock.recv(1024)
amount_received += len(data)
print ("received %s " % data)
print ("closing socket")
clientsock.close()
main()
new_client.py
#!/usr/bin/python
import socket, sys
from threading import Thread
#client for chat room
def send_msg(sock):
while True:
data = input()
sock.send(data.encode('utf-8'))
def recv_msg(sock):
while True:
stuff = sock.recv(1024)
sock.send(stuff)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 2222)
sock.connect(server_address)
print("Connected to chat")
Thread(target=send_msg, args=(sock,)).start()
Thread(target=recv_msg, args=(sock,)).start()
创建两个线程,一个用于接收,一个用于发送。这是最简单的方法。
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect("address")
def send_msg(sock):
while True:
data = sys.stdin.readline()
sock.send(data)
def recv_msg(sock):
while True:
data, addr = sock.recv(1024)
sys.stdout.write(data)
Thread(target=send_msg, args=(sock,)).start()
Thread(target=recv_msg, args=(sock,)).start()
我正在 python 中编写一个非常基本的聊天室。客户端连接并且来自客户端的任何消息都被中继到所有客户端。我遇到的问题是让客户端同时收听和发送消息。它似乎只做任何一个。我已经设置了一个单独的监听客户端并确认消息已收到但监听服务器无法发送任何内容。
目前客户端必须先发送数据才能得到服务器的响应,但我希望客户端能够在发送之前接收到数据——否则聊天室将无法工作。我尝试使用 clientsock.settimeout() 然后使用 recv 但它没有解决问题,因为它没有移过输入部分。
server.py
#!/usr/bin/python
#socket server using threads
import socket, sys, threading
from _thread import *
HOST = 'localhost'
PORT = 2222
lock = threading.Lock()
all_clients = []
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print ("Socket created")
#bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print ("Bind failed. Error code: " + str(msg[0]) + ' Message ' + msg[1])
sys.exit(0)
print ("Socket bind complete")
#Start listening on socket
s.listen(5)
print ("Socket now listening")
#function for handling connections. This will be used to create threads
def clientthread(conn):
#sending message to connected client
conn.send("Welcome to the server. Type something and hit enter\n".encode('utf-8'))
#infinite loop so that function does not terminate and thread does not end
while True:
#receiving data from client
data = conn.recv(1024)
reply = "OK..." + str(data, "utf-8")
if not data:
break
with lock:
for c in all_clients:
c.sendall(reply.encode('utf-8'))
#came out of loop
conn.close()
#keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
with lock:
all_clients.append(conn)
print ("Connected with " + addr[0] + ":" + str(addr[1]))
#start new thread takes 1st argument as a function name to be run, second
#is the tuple of arguments to the function
start_new_thread(clientthread ,(conn,))
s.close()
client.py
#!/usr/bin/python
import socket, sys
#client to transfer data
def main():
#create tcp stocket
clientsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#connect the socket to the server open port
server_address = ('localhost', 2222)
print ("connecting to %s port %s" % server_address)
clientsock.connect(server_address)
#receive data
data = clientsock.recv(1024)
print(str(data, "utf-8"))
while 1:
#send data
message = "sean: " + input()
clientsock.send(message.encode('utf-8'))
#look for the response
amount_received = 0
amount_expected = len(message)
while amount_received < amount_expected:
data = clientsock.recv(1024)
amount_received += len(data)
print ("received %s " % data)
print ("closing socket")
clientsock.close()
main()
new_client.py
#!/usr/bin/python
import socket, sys
from threading import Thread
#client for chat room
def send_msg(sock):
while True:
data = input()
sock.send(data.encode('utf-8'))
def recv_msg(sock):
while True:
stuff = sock.recv(1024)
sock.send(stuff)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 2222)
sock.connect(server_address)
print("Connected to chat")
Thread(target=send_msg, args=(sock,)).start()
Thread(target=recv_msg, args=(sock,)).start()
创建两个线程,一个用于接收,一个用于发送。这是最简单的方法。
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect("address")
def send_msg(sock):
while True:
data = sys.stdin.readline()
sock.send(data)
def recv_msg(sock):
while True:
data, addr = sock.recv(1024)
sys.stdout.write(data)
Thread(target=send_msg, args=(sock,)).start()
Thread(target=recv_msg, args=(sock,)).start()