多个客户端无法同时监听和写入

时间:2015-03-05 14:06:09

标签: python network-programming client-server client

我正在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()

1 个答案:

答案 0 :(得分:3)

创建两个线程,一个用于接收另一个用于发送。这是最简单的方法。

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()