Программирование чата Python P2P 1-к-1 - PullRequest
0 голосов
/ 28 июня 2019

В настоящее время я пытаюсь создать программу на Python, в которой два компьютера, подключенные к разным серверам, могут отправлять сообщения друг другу.Ниже приведен мой код:

Server.py:

import sys
import socket

def main():

    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind(('', 11111))
        s.listen(1)

        while True:
            (conn, addr) = s.accept() 

            while True:
                received = conn.recv(1024)
                if received == '':
                    break
                else:
                    print(received.decode())

                send_msg = input().replace('b', '').encode()
                if send_msg == ' ':
                    break
                else:
                    conn.sendall(send_msg)
                    print("sent")

if __name__ == '__main__':
    main()

Client.py:

import sys
import socket
import select

def main():
    if len(sys.argv) is not 3:
        print("usage: %s [ip adress][port] " % sys.argv[0] )
        return(-1)
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((sys.argv[1], int(sys.argv[2])))

        while True:
            s_msg = input().replace('b', '').encode('utf-8')
            if s_msg == '':
                break 
            else:
                s.sendall(s_msg)
            r_msg = s.recv(1024)
            if r_msg == '':
                break
            else:
                print(r_msg.decode())

if __name__ == '__main__':
    main()

Когда я выполнил код, отправив сообщение с server.pyсообщение не было отправлено клиенту, пока я не попытаюсь отправить сообщение от клиента на сервер.Вот пример результата: enter image description here

Кто-нибудь знает, что не так с моим кодом?

Пожалуйста, дайте мне знать, если нужна дополнительная информация.Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 29 июня 2019

Мне удалось реализовать простую программу чата P2P с помощью кода ниже:

server.py

import sys
import socket
import threading

#TODO: exit program when client ends the connection
def connect(conn):
    while True:
        received = conn.recv(1024)
        if received ==' ':
            pass
        else:
            print(received.decode())

def sendMsg(conn):
    while True:
        send_msg = input().replace('b', '').encode()
        if send_msg == ' ':
            pass
        else:
            conn.sendall(send_msg)

if __name__ == '__main__':
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(('', 11111))
    s.listen()
    (conn, addr) = s.accept() 
    thread1 = threading.Thread(target = connect, args = ([conn]))
    thread2 = threading.Thread(target = sendMsg, args = ([conn]))
    thread1.start()
    thread2.start()
    thread1.join()
    thread2.join()

client.py

import sys
import socket
import threading

#TODO:end connection with 'exit'
def connect(s):
    while True:
        r_msg = s.recv(1024)
        if not r_msg:
            break
        if r_msg == '':
            pass
        else:
            print(r_msg.decode())

def receive(s):
    while True:
        s_msg = input().replace('b', '').encode('utf-8')
        if s_msg == '':
            pass
        if s_msg.decode() == 'exit':
            print("wan exit")
            break
        else:
            s.sendall(s_msg)

if __name__ == '__main__':
    if len(sys.argv) is not 3:
        print("usage: %s [ip adress][port] " % sys.argv[0] )
        sys.exit(0)

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.connect((sys.argv[1], int(sys.argv[2])))
    thread1 = threading.Thread(target = connect, args = ([s]))
    thread2 = threading.Thread(target = receive, args = ([s]))
    thread1.start()
    thread2.start()
    thread1.join()
    thread2.join()
0 голосов
/ 28 июня 2019

В вашем коде input() является функцией блокировки, то есть выполнение останавливается до тех пор, пока вы не нажмете Enter.

Поэтому вам необходимо отправить сообщение для выполнения принимающей части.

Комуразобраться с проблемой, вы можете использовать неблокирующие функции ввода, как упомянуто в этом вопросе .

Или, возможно, с использованием многопоточного кода: один поток считывает использование ввода и отправки, другойнить получи и распечатай.


Редактировать:

Сервер не может отправлять сообщения, если он ничего не получает из-за этой строки:

            received = conn.recv(1024)

, если клиент все еще подключен и отправляетничего, сервер будет ждать на этой линии.Поэтому вам нужно получить одно сообщение на стороне сервера для доступа к отправляющей части.

Вы можете попробовать использовать неблокирующие сокеты , чтобы предотвратить это поведение.

...