sttc1998
sttc1998

Reputation: 51

Python P2P 1-to-1 chat programming

I am currently trying to make a Python program where two computers connected to different servers can send messages to each other. Below is my code:

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

When I executed the code by sending a message from server.py, the message was not sent to the client until I try to send a message from the client to the server. Here is the example of the result: enter image description here

Does anyone know what's wrong with my code?

Please let me know if any extra information is needed. Thank you in advance.

Upvotes: 0

Views: 7812

Answers (2)

sttc1998
sttc1998

Reputation: 51

I was able to implement the simple P2P chat program using the code below:

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

Upvotes: 1

ppolet
ppolet

Reputation: 168

In your code, input() is a blocking function, meaning the execution stop until you press Enter.

So you need to send a message to execute the receive part.

To deal with is issue, you can use non-blocking input functions as mentioned in this question.

Or maybe using multi-threaded code: one thread read the use input and send, the other thread receive and print.


Edit:

The server can't send messages if he receive nothing due to this line:

            received = conn.recv(1024)

if the client is still connected and send nothing, the server will wait on this line. So you need to receive one message on server side to access the send part.

You can try to use non-blocking sockets to prevent this behavior.

Upvotes: 0

Related Questions