4

Network Programming: What happens if the network disconnects after selecting and...

 3 years ago
source link: https://www.codesd.com/item/network-programming-what-happens-if-the-network-disconnects-after-selecting-and-before-sending.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Network Programming: What happens if the network disconnects after selecting and before sending

advertisements

I need to implement an timeout socket which the send()/recv() system calls should return after a timeout. And I think the standard method should be, call select()/pool() before send()/recv(). Below is the example code I copy from ffmpeg source code:

    int ff_network_wait_fd(int fd, int write)
    {
        int ev = write ? POLLOUT : POLLIN;
        struct pollfd p = { .fd = fd, .events = ev, .revents = 0 };
        int ret;
        ret = poll(&p, 1, 100);                                                      

        return ret < 0 ? ff_neterrno() : p.revents &
               (ev | POLLERR | POLLHUP) ? 0 :     AVERROR(EAGAIN);
    }                                                                                

    int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb)
    {
        int ret;
        int64_t wait_start = 0;                                                 

        while (1) {
            if (ff_check_interrupt(int_cb))
                return AVERROR_EXIT;
            ret = ff_network_wait_fd(fd, write);
            if (ret != AVERROR(EAGAIN))
                return ret;
            if (timeout > 0) {
                if (!wait_start)
                    wait_start = av_gettime();
                else if (av_gettime() - wait_start > timeout)
                    return AVERROR(ETIMEDOUT);
            }
        }
    }

    static int tcp_write(URLContext *h, const uint8_t *buf, int size)
    {
        TCPContext *s = h->priv_data;
        int ret;                                                                

        if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
            ret = ff_network_wait_fd_timeout(s->fd, 1, h->rw_timeout, &h->interrupt_callback);
            if (ret)
                return ret;
        }
        ret = send(s->fd, buf, size, 0);
        return ret < 0 ? ff_neterrno() : ret;
    }

Seems that tcp_write() call ff_network_wait_fd_timeout() to prepare the environment. But it makes me so confusion that, if network cable unplugged after ff_network_wait_fd()(this should call poll() system call), should send() return -1, or still blocked? Thanks very much.


  1. You don't need poll() to implement a timeout for recv(). Just call setsockopt() with the option SO_RCVTIMEO and deal with the EWOULDBLOCK errno as a timeout.

  2. You do need to use poll() for a send() timeout.

  3. A broken TCP connection can only be detected by trying to write to it. There is no network event that triggers a poll() event.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK