`sock.recv()` returns empty string when connection is dead on non-blocking socket

2024/10/14 11:13:09

I have a non-blocking socket in Python called sock. According to my understanding the recv() method should raise an exception if the connection has been closed by the peer, but it returns an empty string ('') and I don't know why.

This is the script I test with (from here):

import sys
import socket
import fcntl, os
import errno
from time import sleeps = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1',9999))
fcntl.fcntl(s, fcntl.F_SETFL, os.O_NONBLOCK)while True:try:msg = s.recv(4096)print("got data '{msg}'".format(msg=msg))except socket.error, e:err = e.args[0]if err == errno.EAGAIN or err == errno.EWOULDBLOCK:sleep(1)print 'No data available'continuesys.exit(1)

If the peer closes the connection this socket is supposed to raise socket.error on recv(), but instead it only returns ''.

I test it this way, using two terminals:

# Terminal 1
~$ nc -l -p9999# Terminal 2
~$ python ./test_script.py# Terminal 1
typingsomestring# Terminal 2
No data available
No data available
No data available
got data 'typingsomestring
'
No data available
No data available# Terminal 1
Ctrl+C # (killing nc)# Terminal 2
got data ''
got data ''
got data ''
got data ''
got data ''
got data ''
got data ''
got data ''
got data ''
got data ''
got data ''
got data ''
got data ''
got data ''
got data ''
got data ''
got data ''
got data ''
got data ''
Answer

This is by design in the underlying operating system recv system call: a read on a socket closed on peer, or as soon as the peer used a shutdown(s, SHUT_WR) to indicate it will no send anything more, returns immediately with a length of 0 bytes.

That is the only case when you have a successful read of 0 bytes, because while the peer socket remains open, a successful read returns at least one byte on a blocking socket or a E_AGAIN or E_WOULDBLOCK error on a non blocking socket.

TL/DR: there is no anomaly in observed behaviour

https://en.xdnf.cn/q/69418.html

Related Q&A

Iteration order with pandas groupby on a pre-sorted DataFrame

The SituationIm classifying the rows in a DataFrame using a certain classifier based on the values in a particular column. My goal is to append the results to one new column or another depending on cer…

How do I pass an exception between threads in python

I need to pass exceptions across a thread boundary.Im using python embedded in a non thread safe app which has one thread safe call, post_event(callable), which calls callable from its main thread.I am…

How to check if a docker instance is running?

I am using Python to start docker instances.How can I identify if they are running? I can pretty easily use docker ps from terminal like:docker ps | grep myimagenameand if this returns anything, the i…

Retrieving facets and point from VTK file in python

I have a vtk file containing a 3d model,I would like to extract the point coordinates and the facets.Here is a minimal working example:import vtk import numpy from vtk.util.numpy_support import vtk_to_…

Tensorflow: feed dict error: You must feed a value for placeholder tensor

I have one bug I cannot find out the reason. Here is the code:with tf.Graph().as_default():global_step = tf.Variable(0, trainable=False)images = tf.placeholder(tf.float32, shape = [FLAGS.batch_size,33,…

Pass many pieces of data from Python to C program

I have a Python script and a C program and I need to pass large quantities of data from Python script that call many times the C program. Right now I let the user choose between passing them with an AS…

Parse JavaScript to instrument code

I need to split a JavaScript file into single instructions. For examplea = 2; foo() function bar() {b = 5;print("spam"); }has to be separated into three instructions. (assignment, function ca…

Converting all files (.jpg to .png) from a directory in Python

Im trying to convert all files from a directory from .jpg to .png. The name should remain the same, just the format would change.Ive been doing some researches and came to this:from PIL import Image im…

AssertionError: Gaps in blk ref_locs when unstack() dataframe

I am trying to unstack() data in a Pandas dataframe, but I keep getting this error, and Im not sure why. Here is my code so far with a sample of my data. My attempt to fix it was to remove all rows whe…

Python does not consider distutils.cfg

I have tried everything given and the tutorials all point in the same direction about using mingw as a compiler in python instead of visual c++.I do have visual c++ and mingw both. Problem started comi…