Socket with unix socket, `recv` block?

Hi,

I followed more or less this code echo server/client

I’ve adapted it for unix socket.

#server
from socket import socket, AF_UNIX, SOCK_STREAM
from os import unlink
from os.path import exists

socket_path = '/tmp/something'

try:
	unlink(socket_path)
except OSError:
	if exists(socket_path):
		raise

with socket(AF_UNIX, SOCK_STREAM) as server:

    server.bind(socket_path)
	server.listen(1)
    
    conn, client_address = server.accept()

    with conn:

        DataCombined = bytes()
		loop = 0

        while True:
            data = conn.recv(8)

            if data:
				print(data.decode())
				DataCombined += data
				loop += 1
			else:
				print('data dont exist')
				break

		print('message received:', DataCombined.decode())
		print('loops:', loop)

		DataCombined = DataCombined.decode() + ' Process'

		conn.sendall(DataCombined.encode())     

from socket import socket, AF_UNIX, SOCK_STREAM

socket_path = '/tmp/something'

ToBeSend = '''
insert something long. 
'''

with socket(AF_UNIX, SOCK_STREAM) as client:

    client.connect(socket_path)

	client.sendall( ToBeSend.encode() )


	DataCombined = bytes()
	loop = 0

	while True:

		data = client.recv(8) #bytes

		if data:
			DataCombined += data
			loop += 1
		else:
			break


print('message received:', DataCombined.decode())
print('loops:', loop)

So I launch the server and the client

The server is waiting for a connection server.listen(1)
The client is connecting to the server and send everything, but it seem that the server wait for more ! :confused:

it’s seem it’s blocking on data = conn.recv(8)

any ideas ?

Thanks.

I’ve found the cause.

The data send by the client was not a multiple of 8 Bytes… and therefore the last “packet” was 5 bytes long and recv was waiting the remain 3 bytes.

So I adapted the code

if len(data) < 8: break

:slight_smile:

1 Like

It will still block if the message length is a multiple of 8. You need to create a simple protocol using CRLF or something similar to break out of the while loop.

That would be 7 bytes.

Did you mean len(data) < 9 or len(data) <= 8 ?

1 Like

Thanks @onePythonUser ,
is there another method than len that will allow me to count the real bytes ?

never-mind I found

len('aString'.encode())

Actually I don’t even need this ! len return the correct bytes of a bytes object !

(the server is the receiver and the client is the sender)

if you’re receiving the raw data, it should actually already be in bytes and not in str string format (systems don’t send and receive strings … they send/receive binary data in bytes).

As an fyi, if you’re receiving binary data, you wouldn’t .encode it as it would already be encoded, you would .decode it. If you’re sending the data, then yes, you would .encode it.