简体   繁体   English

同时发送/接收消息socket python

[英]Send/Receive messages at the same time socket python

I have been working on a simple python socket chat room where the client and server can send messages to each other. 我一直在一个简单的python套接字聊天室,客户端和服务器可以相互发送消息。 The issue that I came across was that the server and client can only send one message at a time. 我遇到的问题是服务器和客户端一次只能发送一条消息。 I want it to work like any other chat room, where I could receive a message when I am sending a message, any help will help greatly 我希望它像任何其他聊天室一样工作,在我发送消息时我可以收到消息,任何帮助都会有很大帮助

Server.py Server.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("")

Client.py Client.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("")

CaSper has given me the server code where multiple clients can connect to the server but the problem now is that the clients can not talk to each other … CaSper给了我服务器代码,其中多个客户端可以连接到服务器,但现在的问题是客户端无法相互通信...

That's primarily because your client wants s_name = s.recv(1024) , while CaSper's server doesn't send its name. 这主要是因为您的客户端需要s_name = s.recv(1024) ,而CaSper的服务器不会发送其名称。 Here's a variant of your client (expecting host and port as command arguments) which works with CaSper's server and also addresses your original issue ( client can only send one message at a time ) by using separate threads: 这是您的客户端的变体(期望主机端口作为命令参数),它与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("")

Note that CaSper's server has a series of deficiencies: 请注意,CaSper的服务器存在一系列缺陷:

  1. Even now that your clients can send messages at any time, the server waits for a message from one by one client, ie when it waits for client A, client B can send a message, but the server receives and broadcasts it only after client A has sent something. 即使现在您的客户端可以随时发送消息,服务器也会等待来自一个客户端的消息,即当它等待客户端A时,客户端B可以发送消息,但服务器仅在客户端A之后接收并广播它。送了一些东西。
  2. It doesn't handle client disconnects. 它不处理客户端断开连接。
  3. It goes into a busy loop when all clients disconnected. 当所有客户端断开连接时,它会进入忙碌循环。

For a better server example, see the question Handle multiple requests with select . 有关更好的服务器示例,请参阅使用select处理多个请求的问题。

… could you possibly change my server so that it works … ...你可以改变我的服务器,以便工作......

Here's a variant of your server which works with this client, also using separate threads for input and reception: 这是您的服务器的一个变体,它与此客户端一起使用,也使用单独的线程进行输入和接收:

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

您是否尝试过使用线程模块或时间模块。这是因为两个脚本同时发送消息。尝试Ex(来自服务器端口的客户端等待消息,然后客户端向服务器发送消息)。

THIS IS SERVER 这是服务器

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM