1

I'm doing a little localhost socket project in python, I currently only have the thread implementation so multiple clients can connect to the same server. I have a specific message from client to disconnect from server which is DISSCONECT_MESSAGE = b'0' when the server recognize the byte zero it should close the connection between the server and the client who sent it. I handle this by using an if statement to catch the byte zero.

The clients send function always encode the message to send it to the server, so if user input is 0 it pass through encode and now I have b'0', when server recieve this message it decode it so again I have 0, thats why in this if statement I encode it again to know if the message is 0:

if msg.encode() == DISSCONECT_MESSAGE:
connected = False

I tested handle_client by adding a print before the conn.close () function but it never shows that print so it never leaves the while loop and therefore never closes the connection to the client.

Here is my code:

server.py

import socket
import threading

HEADER = 64
PORT = 65500
SERVER = ''
ADDRESS = (SERVER,PORT)
FORMAT = 'utf-8'
DISSCONECT_MESSAGE = b'0'

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDRESS)

def handle_client(conn, addr):
    print(f"[NEW CONNECTION] {addr} connected")

    connected = True

    while connected:
        msg_length = conn.recv(HEADER).decode(FORMAT)
        if msg_length:
            msg_length = int(msg_length)
            msg = conn.recv(msg_length).decode(FORMAT)
            if msg.encode() == DISSCONECT_MESSAGE:
                connected = False

            if msg[:2] == "10":
                conn.send("[CODE 10] Log in request".encode(FORMAT))

            print(f"[{addr}] {msg}")
            conn.send("Message recived".encode(FORMAT))

    
    print(f"[{addr}] DISSCONNECTED")
    conn.close()



def start():
    server.listen()
    print(f"[LISTENING] Server is listening on {SERVER}")
    while True:
        conn, addr = server.accept() # Wait to a new connection
        thread = threading.Thread(target=handle_client, args=(conn, addr))
        thread.start()
        print(f"[ACTIVE CONNECTIONS] {threading.activeCount()-1}")


print("[STARTING] Server is starting...")
start()

client.py

import socket

HEADER = 64
PORT = 65500
FORMAT = 'utf-8'
DISSCONECT_MESSAGE = b'0'
SERVER = 'localhost'
ADDRESS = (SERVER,PORT)

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

client.connect(('localhost', 65500))

def send(msg):
    message = msg.encode(FORMAT)
    msg_length = len(message)
    send_length = str(msg_length).encode(FORMAT)
    send_length += b' ' * (HEADER - len(send_length))
    client.send(send_length)
    client.send(message)
    print(client.recv(1024).decode(FORMAT))

while True:
    msg = input()
    if msg.encode() == DISSCONECT_MESSAGE:
        print("[DISSCONECTED FROM SERVER]")
        client.send(DISSCONECT_MESSAGE)
    else:
        send(msg)

Can anyone tell me what I'm doing wrong?

1

1 Answer 1

1

First, check the return values of send and recv. There is no guarantee all bytes were sent (try sendall) and and recv returns 0 (socket closed) or 1-length bytes requested, not necessarily the total number requested.

As far as your main bug, you've sent the character zero ('0') and your server receives it as the length with:

msg_length = conn.recv(HEADER).decode(FORMAT)

The result is a length of 0. msg then becomes an empty string with:

msg = conn.recv(msg_length).decode(FORMAT)

msg.encode() == b'' (an empty string) not b'0' a length 1 string containing a zero character.

Instead, you could abort when you get a length of 0. Or the normal way to disconnect is to close the connection. Then the server receives b'' (a length zero recv) which indicates a closed connection.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.