Отправлять / получать сообщения одновременно сокет Python - PullRequest
0 голосов
/ 11 февраля 2019

Я работал над простой комнатой чата с python-сокетом, где клиент и сервер могут отправлять сообщения друг другу.Проблема, с которой я столкнулся, заключалась в том, что сервер и клиент могут отправлять только одно сообщение за раз.Я хочу, чтобы он работал как любая другая чат-комната, где я мог бы получить сообщение при отправке сообщения, и любая помощь очень поможет

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

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

Ответы [ 3 ]

0 голосов
/ 11 февраля 2019

ЭТО СЕРВЕР

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()
0 голосов
/ 12 февраля 2019

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 есть ряд недостатков:

  1. Даже сейчас, когда ваши клиенты могут отправлять сообщения в любое время,сервер ожидает сообщения от одного клиента, то есть, когда он ожидает клиента A, клиент B может отправить сообщение, но сервер получает и передает его только после того, как клиент A отправил что-то.
  2. Это нене обрабатывает отсоединения клиентов.
  3. Когда все клиенты отключаются, он входит в цикл занятости.

Для лучшего примера сервера см. вопрос Обработка нескольких запросов с помощью 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("")
0 голосов
/ 11 февраля 2019

Возможно, вы пытались использовать модуль Threading или модуль времени. Это происходит из-за того, что оба сценария отправляют сообщения в одно и то же время. Попробуйте Ex (клиент ожидал сообщения с сервера, затем клиент отправил сообщение на сервер).

...