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

couldn't check remote was closed #174

Open
sydnash opened this issue May 11, 2016 · 6 comments
Open

couldn't check remote was closed #174

sydnash opened this issue May 11, 2016 · 6 comments

Comments

@sydnash
Copy link

sydnash commented May 11, 2016

local data, status, partial = self.tcp:receive("_a")
if __status == STATUS_CLOSED or _status == STATUS_NOT_CONNECTED then
--remote was closed.
end
I use code above to check remote socket is closed,but the status is allways timeout because the code at wsocket.c(socket_waitfd):
if (timeout_iszero(tm)) return IO_TIMEOUT; /
optimize timeout == 0 case */
because my socket is non-blocking,so it allways return timeout here。after delete this line,it's return closed。

@diegonehab
Copy link
Contributor

Maybe this could happen on the first call. But on the second call, it should return IO_CLOSED, no?

@diegonehab diegonehab reopened this May 11, 2016
@sydnash
Copy link
Author

sydnash commented May 12, 2016

yes,not fist call,it allways return timeout,
until i comment this line(if (timeout_iszero(tm)) return IO_TIMEOUT; / optimize timeout == 0 case */).

@epajarre
Copy link

Just saying "Me too". Also experiencing this problem with my program, and while searching found this thread. Looks like sydnash is correct.

@darklost
Copy link

darklost commented Jan 6, 2017

/* On UDP, a connreset simply means the previous send failed.
* So we try again.
* On TCP, it means our socket is now useless, so the error passes.
* (We will loop again, exiting because the same error will happen) */

as this in wsocket.c line 256 try again but may it missing continue ? prev still IO_DONE
in if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;

int socket_recv(p_socket ps, char *data, size_t count, size_t *got, 
        p_timeout tm) 
{
    int err, prev = IO_DONE;
    *got = 0;
    if (*ps == SOCKET_INVALID) return IO_CLOSED;
    for ( ;; ) {
        int taken = recv(*ps, data, (int) count, 0);
        if (taken > 0) {
            *got = taken;
            return IO_DONE;
        }
        if (taken == 0) return IO_CLOSED;
        err = WSAGetLastError();
        /* On UDP, a connreset simply means the previous send failed. 
         * So we try again. 
         * On TCP, it means our socket is now useless, so the error passes. 
         * (We will loop again, exiting because the same error will happen) */
        if (err != WSAEWOULDBLOCK) {
                        if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
                        prev = err;
			//change by  2017-1-7 01:59:38 darklost.me
			//settimeout(0) is always return IO_TIMEOUT when remote server is closed!
			//maybe missing continue here?
			continue;
        }
        if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
    }
}

in function int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, SA *addr, socklen_t *len, p_timeout tm) the same as above

may be missing continue ?

@alerque
Copy link
Member

alerque commented Nov 10, 2023

Does #81 help with figuring out if the remote side closed?

@jakitliang
Copy link

I wonder this change would dead loop doing socket the block check.
On Windows, read() is block even though using MSG_*** parameters. Except to setting the non-block flag.
I think the best way is to Select again instead loop it with continue.

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

No branches or pull requests

6 participants