Search code examples
pythonsocketsserverclient

How to write a python echo server that doesn't disconnect after first echo?


I want to set up a simple echo server that just echoes back whatever the client sends to it. However, currently the server disconnects (the server socket closes) after it echoes back the first client message. I want to be able to "chat" continuously with the server, where the server just echoes back several consecutive messages I send without disconnecting; e.g.:

"Hi there!"

"Echoing: Hi there!"

"How are you?"

"Echoing: How are you?"

"Cheers!"

"Echoing: Cheers!"

etc.

Currently I have the following code:

server.py:

import socket

HOST = '127.0.0.1' 
PORT = 5000

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen()
    conn, addr = s.accept()
    with conn:
        while True:
            data = conn.recv(1024)
            if not data:
                break
            conn.sendall(data)

client.py:

import socket

HOST = '127.0.0.1'
PORT = 5000

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    s.sendall(b'Hello, world')
    data = s.recv(1024)

print('Echoing: ', repr(data))

The server, however, disconnects after it echoes back the first client message (probably because of the if not data: break statement).

P.S. I'd appreciate any additional explanations which might be necessary - this example has educational purposes, so I'm not (only) after getting the code running.

Thanks!


Solution

  • I will show you the code I created then talk you through it:

    Server:

    import socket
    
    HOST = '127.0.0.1' 
    PORT = 5000
    
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind((HOST, PORT))
        s.listen()
        conn, addr = s.accept()
        with conn:
            while True:
                data = conn.recv(1024)
                conn.sendall(data)
    

    For the server I removed:

    if not data:
       break
    

    It simply wasn't working for me. If you know your message is going to be less than the 1024 bytes( which here it is) it's unnecessary. But if you want a longer message change that value to a bigger number to accommodate. So yes you were right in suspecting it was that line.

    Client:

    import socket
    
    HOST = '127.0.0.1'
    PORT = 5000
    
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((HOST, PORT))
        print("Connected")
        while True:
            print("Sending data")
            s.sendall(b'Hello, world')
            print("Recieving data")
            data = s.recv(1024)
            print('Echoing: ', repr(data))
    

    For the client side I just added the send and receive process into a loop.

    Things to note:

    This only works for me when run through the terminal, I don't know if you know how to do that so sorry if you do, here's a link explaining: https://www.wikihow.com/Use-Windows-Command-Prompt-to-Run-a-Python-File I assumed you use Windows. You will need to follow the process for both your client.py programme and server.py programme. Make sure you run the server.py programme first.

    This will cause an infinite loop of sending and receiving. Press Ctrl+C to terminate.

    I hope this solves your problem and you can edit the code accordingly. Any further problems please do comment and I'll try to get back to you.