Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python sockets: how to only receive one message at a time

Just trying to understand how sockets work. I'm using a modified test select server and client I found. Here's the server:

import socket

host = ''
port = 50000
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
while 1:
    client, address = s.accept()
    running = 1
    while running:
        data = client.recv(size)
        print("received: "+data + "\n")
        if data:
            client.send(data)
            running = 0
        else:
            running = 0
    client.close()

And the client:

import socket
import sys

host = 'localhost'
port = 50000
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
sys.stdout.write('%')

s.send("(Message1)")


while 1:
    s.send("(Message2)")
    data = s.recv(size)
    sys.stdout.write(data)
    sys.stdout.write('%')
s.close() 

I'm expecting the server to print something like:

received: (Message1)
received: (Message2)

since they're different messages sent separately, but instead I get:

received: (Message1)(Message2)

Is this related to the size of the data received, some kind of buffer thing, or is it timeout-related, or something else?

like image 875
Milo P Avatar asked Oct 22 '25 20:10

Milo P


2 Answers

This is a perfectly normal behavior of a stream socket which is a stream of successive bytes, not a stream of messages. You may envisage to format your message by encoding for instance the len of the message followed by the message data. Then you can parse the received buffer with these indications. You can also wait until you find the corresponding ')' to the opening '('.

like image 82
Louis Hugues Avatar answered Oct 24 '25 09:10

Louis Hugues


A socket connection gives you just a single datastream, so the server can't possibly know when one message ends and the next begins.

Your messages have to contain some info about how long they are, so either make them fixed-size, and adjust your buffer length accordingly, or prepend them with a size value, in which case the server has to read that first and then read the exact number of bytes from the socket.

There is no other way.

like image 36
daniel kullmann Avatar answered Oct 24 '25 10:10

daniel kullmann



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!