How to catch a “connection reset by peer” error in C socket?

倖福魔咒の 提交于 2019-12-09 23:14:13

问题


I have a C++ and Qt application which part of it implements a C socket client. Some time ago by app crashed because something happened with the server; the only thing I got from that crash was a message in Qt Creator's Application Output stating

recv_from_client: Connection reset by peer

I did some research on the web about this "connection reset by peer" error and while some threads here in SO and other places did managed to explain what is going on, none of them tells how to handle it - that is, how can I "catch" the error and continue my application without a crash (particularly the method where I read from the server is inside a while loop, so I'ld like to stop the while loop and enter in another place of my code that will try to re-establish the connection).

So how can I catch this error to handle it appropriately? Don't forget that my code is actually C++ with Qt - the C part is a library which calls the socket methods.

EDIT

Btw, the probable method from which the crash originated (given the "recv_from_client" part of the error message above) was:

int hal_socket_read_from_client(socket_t *obj, u_int8_t *buffer, int size)
{
    struct s_socket_private * const socket_obj = (struct s_socket_private *)obj;
    int retval = recv(socket_obj->client_fd, buffer, size, MSG_DONTWAIT); //last = 0

    if (retval < 0)
        perror("recv_from_client");

    return retval;
}

Note: I'm not sure if by the time this error occurred, the recv configuration was with MSG_DONTWAIT or with 0.


回答1:


Just examine errno when read() returns a negative result.

There is normally no crash involved.

while (...) {
    ssize_t amt = read(sock, buf, size);
    if (amt > 0) {
        // success
    } else if (amt == 0) {
        // remote shutdown (EOF)
    } else {
        // error

        // Interrupted by signal, try again
        if (errno == EINTR)
            continue;

        // This is fatal... you have to close the socket and reconnect
        // handle errno == ECONNRESET here

        // If you use non-blocking sockets, you also have to handle
        // EWOULDBLOCK / EAGAIN here

        return;
    }
}



回答2:


It isn't an exception or a signal. You can't catch it. Instead, you get an error which tells you that the connection has been resetted when trying to work on that socket.

int rc = recv(fd, ..., ..., ..., ...);

if (rc == -1)
{ 
  if (errno == ECONNRESET)
    /* handle it; there isn't much to do, though.*/
  else
     perror("Error while reading");
}

As I've written, there isn't much you can do. If you're using some I/O multiplexer, you may want to remove that file descriptor from further monitoring.



来源:https://stackoverflow.com/questions/24916937/how-to-catch-a-connection-reset-by-peer-error-in-c-socket

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!