Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

receive() returns nil, "closed" on peer's shutdown('send') #225

Open
ghost opened this issue Sep 7, 2017 · 5 comments
Open

receive() returns nil, "closed" on peer's shutdown('send') #225

ghost opened this issue Sep 7, 2017 · 5 comments
Labels

Comments

@ghost
Copy link

ghost commented Sep 7, 2017

I've encountered unusual behavior in streaming sockets (both tcp and unix) in 3.0-rc1. If client:receive('*a') encounters EOF right after :accept(), i.e. no data is sent by peer and it calls :shutdown('send') on its side, then this fact is interpreted as error. While it is unusual for client to not send anything, zero read count is usually not considered an error in byte streams.

As it seems from sources, C-side socket_recv(...) routines intentionally do this, so it's not a bug. Why it is implemented this way and shouldn't luasocket allow empty transmissions in both ways, returning '' instead of nil, 'closed'?

As a workaround, I can check for 'closed' status after :receive('*a'), but I'm not sure if that will hide network issues from my code, as:

In case of error, the method returns nil followed by an error message, followed by a (possibly empty) string containing the partial that was received. The error message can be the string 'closed' in case the connection was closed before the transmission was completed ...

this is actually very misleading, since connect() to a socket and succesful shutdown(SHUT_WR) is NOT a "close before transmission completed", it is not an error at all, because the transmission of EOF went fine, and only one side of duplex connection was shut, and the peer receiving EOF is able to send back any amount of data he has to.


My guess, it was needed to distinguish empty lines and EOF in :receive('*l'), so more likely the simplest solution is to make documentation more clear on this case. Something along the lines of:

The 'closed' status from receive() call isn't actually an error in a sense, because the nature of full-duplex streaming connections allows to close either sending or receiving half of socket without affecting the other. Once you get 'closed' it means that your peer finished sending its request and waits for a response to arrive.

@ghost
Copy link
Author

ghost commented Sep 7, 2017

Also, documentation is pretty wordy and hard to grasp, because it lacks formality and example blocks. If I'll spend few time on the html-example of one function improvement, would you like to accept a PR with all functions then described like that? Original texts will remain intact of course.

@evepoe
Copy link

evepoe commented Jun 19, 2021

I'm facing a similar issue the 'closed' error is emitted after large amount of data received.
Strangely enough, when I set the timeout to 0.01 for receive the error doesn't happen (settimeout(0.01)
Or If I reduce the amount of packets send by server per heartbeat, the error doesn't happen as well.

Anyone faced/ solved the same problem?

@alerque alerque added the bug label Mar 19, 2022
@jakitliang
Copy link

That is the same problem I mentioned in

#411 (comment)

@alerque
Copy link
Member

alerque commented Nov 10, 2023

Does #81's merge have any effect on this issue?

c.f. #410.

@jakitliang
Copy link

Does #81's merge have any effect on this issue?

c.f. #410.

I think it doesn't help but have side-effect.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

3 participants