0

I am trying to use "vanilla" Python sockets to transmit data from a server to a client, without using any asynchronous programming. My use case is the following: I would like a local Raspberry Pi to connect to my internet exposed server, and the server to send data through the created socket when a given event occurs.

I followed several tutorials on simple socket programming in Python to build the following code:

server.py

import socket
import time

def server():
    PORT = 65432
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(('0.0.0.0', PORT))
    s.listen(1)
    conn,address=s.accept()  # accept an incoming connection using accept() method which will block until a new client connects
    print("address: ", address[0])
    time.sleep(5)
    s.send("hey".encode())
    conn.close()
    return

server()

client.py

import socket
import time

HOST = "my.remote.domain"
PORT = 65432

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    while True :
        print(s.recv(1024))
        time.sleep(1)

When launching the server and the client on their respective machine, I can see that the connexion is correctly made, since the IP address of the client is printed in the logs of the server. However, after few seconds and before sending any data, I get the following error on the server side:

address:  client_ip_address_appears_here
Traceback (most recent call last):
  File "main.py", line 32, in <module>
    receiver()
  File "main.py", line 18, in receiver
    s.send("heeey".encode())
BrokenPipeError: [Errno 32] Broken pipe

Meanwhile on the client side, no data is received:

b''
b''
b''
b''
b''
b''
b''
b''
b''

Is there a conceptual problem in the way I try to handle the socket ?

paupaulaz
  • 937
  • 1
  • 11
  • 20
  • Does this answer your question? [How to handle a broken pipe (SIGPIPE) in python?](https://stackoverflow.com/questions/180095/how-to-handle-a-broken-pipe-sigpipe-in-python) – Jeremy Friesner Jan 23 '21 at 23:18
  • Thanks for your reply ! I actually think that my problem resides in finding the cause of the error, and not just how to handle it. Even though your resource will be very useful when I try to improve the reliability of my architecture, it seems that I am getting the same error virtually every time my server tries to send the data, so I guess there should be a problem in my implementation to tackle first :) – paupaulaz Jan 23 '21 at 23:22
  • The cause of the error is trying to send bytes to a TCP socket when the remote peer has already closed the TCP connection; Unix (by default) handles that situation by raising a SIGPIPE signal, and then your Python interpreter converts that into an EPIPE Python exception. – Jeremy Friesner Jan 23 '21 at 23:31
  • Shouldn't my client code wait for packets after connexion instead of closing ? – paupaulaz Jan 23 '21 at 23:37
  • It should; but perhaps you are closing the client with CTRL-C or similar? – Jeremy Friesner Jan 23 '21 at 23:38
  • Nope, it just keeps on printing empty strings as shown in my post, and the server error occurs before I kill the client .. – paupaulaz Jan 23 '21 at 23:39

1 Answers1

1

After trying out the code, I think the biggest problem you have is that the server is trying to send on the wrong socket. i.e. this line:

s.send("hey".encode())

should be rewritten like this:

conn.send("hey".encode())

As it is, you are trying to send() on the TCP accepting-socket rather than on the TCP connection to the client, which doesn't make sense. On my (MacOS/X) system, the server process prints this error output:

Jeremys-Mac-mini-2:~ jaf$ python server.py
('address: ', '127.0.0.1')
Traceback (most recent call last):
File "server.py", line 18, in <module>
  server()
File "server.py", line 14, in server
  s.send("hey".encode())
socket.error: [Errno 57] Socket is not connected
Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234