Python TCP socket.recv() returns with nothing as soon as connection is made
Yes, this is expected behavior.
The client does not send anything. And it exit as soon as it connect to the server; cause disconnection.
socket.recv
returns an empty string if the peer performed shutdown (disconnect).
While, in the REPL, the socket is not closed until you issue sys.exit()
or you quit the interactive shell.
Related videos on Youtube
Sonicsmooth
Updated on June 04, 2022Comments
-
Sonicsmooth almost 2 years
I'm trying to implement the most basic python TCP server. Windows 8, Python 2.7, firewall is turned off. Code is from here: https://wiki.python.org/moin/TcpCommunication
If I do the client stuff (
socket(...), connect(...), send(...)
) via python repl, things work fine, ie the server correctly blocks when callingrecv
.However if I run the exact same code via python script (both with and without explicitly calling python.exe at windows command line), the
recv
returns immediately with no data. I read elsewhere on SO this means it's an invalid socket, but I'm not sure what that means or how to check for it. I'm using the socket returned byaccept()
not the one used to initiate the connection.I'm trying to block on
recv
so I can take advantage of the timeout (I don't want to use select module, which BTW also returns immediately) and process some keyboard stuff between attempts torecv
, ie user presses 'q' to quit.In various experiments I've shown that once this occurs,
recv
will always return immediately (as willselect.select(...)
) if I put it in a loop, so it's not like the client is sending a single "bad" packet initially. If the client happens to have sent something, then therecv
returns with that data, but it certainly doesn't block waiting for data when put in a tight loop.Is this behavior expected?
Server code:
import sys import socket TCP_IP = '192.168.1.10' TCP_PORT = 5005 BUFFER_SIZE = 20 # Normally 1024, but we want fast response s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((TCP_IP, TCP_PORT)) s.listen(1) conn, addr = s.accept() print 'Connection address:', addr while 1: data = conn.recv(BUFFER_SIZE) # This returns immediately with no data, when client connection is run from script and doesn't send() anything, just connects. if not data: print "broken" break print "received data:", data conn.send(data) # echo conn.close() sys.exit()
Client code:
import sys import socket TCP_IP = '192.168.1.10' TCP_PORT = 5005 BUFFER_SIZE = 1024 MESSAGE = "Hello, World!" s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((TCP_IP, TCP_PORT)) # Commenting out the following to prove the recv() call on the other #end returns with nothing instead of blocking indefinitely. If I #type the rest of this at the REPL the server behaves correctly, #ie, the recv call blocks forever until socket.send("bla") from client. #s.send(MESSAGE) data = s.recv(BUFFER_SIZE) #s.close() #print "received data:", data sys.exit()
-
Sonicsmooth over 10 yearsThank you. I verified this by a) doing a
while True: pass
loop on the client side script, and the serverrecv
blocked, and then b) connecting from python repl manually line by line, and the server siderecv
unblocked and passed no data when I dids.close()
from client side python repl.