"Network Programming" advanced I/O

Source: Internet
Author: User
Tags sendmsg

This section is a premium socket I/O.

Set the socket timeout alarm to use a more convenient data transfer function.

There are three ways to timeout the socket I/O Setup operation:

    1. Transfer alarm performance, when produced, it specifies the time-out SIGALRM signal;
    2. In the Select function, set the timeout blocking wait I/O to replace the direct blockage on the read or write call;
    3. Use the So_rcvtimeo and So_sndtimeo socket options (both options are only part of the implementation support ).

The following uses the SIGALRM signal generated by the alarm to set the timeout for the Connect function, and of course the system sets the timeout limit for the Connect function, where we simply represent the function of the SIGALRM signal in setting the timeout.

#include <signal.h> #include <errno.h> #include <stdio.h> #include <unistd.h> #include <sys/ socket.h>typedef void Sigfunc (int), extern void Err_sys (const char *,...); static Sigfunc *m_signal (int signo, Sigfunc *func), static sigfunc *mysignal (int signo, Sigfunc *func), static void connect_    Alarm (int); int myconnect_timo (int sockfd, const struct SOCKADDR *saptr, socklen_t salen, int nsec) {Sigfunc *sigfunc;    int n; /* SIGALRM signal processing function.    and save the existing signal processing function */Sigfunc = mysignal (SIGALRM, connect_alarm); /* Set Alarm timeout */if (alarm (nsec)! = 0)/* If the timeout has been set, alarm returns the current number of seconds remaining.     Otherwise return 0 */printf ("Alarm was already set\n");/* Hint: Alarm timeout has been set */if ((n = connect (SOCKFD, saptr, Salen) < 0)        {/* The connection failed due to a timeout handler call break, closing the socket and setting the failure caused by the timeout */close (SOCKFD);    if (errno = = eintr) errno = etimedout;    }/* Close alarm */alarm (0);    /* Restore the original processing function */mysignal (SIGALRM, Sigfunc); return (n);} static void Connect_alarm (int signo) {printf ("flag:%d\n ", Signo);    return;/* just interrupt the Connect */}static sigfunc *mysignal (int signo, Sigfunc *func) {Sigfunc *sigfunc;    if (Sigfunc = M_signal (Signo, func)) = = Sig_err) Err_sys ("Signal error"); return (SIGFUNC);}    static Sigfunc *m_signal (int signo, sigfunc *func) {struct Sigaction Act, oact;    /* Set Signal processing function */Act.sa_handler = func;    /* Initialize the signal set */Sigemptyset (&act.sa_mask);    act.sa_flags = 0;    if (Signo = = SIGALRM) {/* If the SIGALRM signal, the system does not voluntarily restart */#ifdef sa_interrupt act.sa_flags |= sa_interrupt; #endif } else {/* The remaining signal is set to the system will voluntarily reboot */#ifdef sa_restart act.sa_flags |= sa_restart; #endif}/* Call Sigaction Letter    Number */if (sigaction (Signo, &act, &oact) < 0) return (SIG_ERR); return (Oact.sa_handler);}

Use the Select function to set the time-out for recvfrom. A commentary on the Select function can refer to the article "I/O multiplexing".

#include <sys/select.h> #include <stdlib.h>extern void Err_sys (const char *,...); * Wait for the descriptive descriptor to become readable */int readable_timeo (int fd, int sec) {fd_setrset;struct TIMEVALTV, within the specified time;    /* Initialize the FD_SET structure and add descriptive descriptor */fd_zero (&rset); Fd_set (FD, &rset);    /* Set timeout time */tv.tv_sec = sec;/* seconds */tv.tv_usec = 0;/* microseconds *    /* Call the Select function to cause the process to block the timeout in select to wait for the descriptive descriptor to become readable */return (select ( Fd+1, &rset, NULL, NULL, &TV));/* 4> 0 if descriptor is readable */}/* end Readable_timeo */intread_timeo (int f D, int sec) {Intn;if ((n = Readable_timeo (fd, sec)) < 0) Err_sys ("Readable_timeo error"); return (n);}

Using the So_rcvtimeo and So_sndtimeo socket options, when you set a descriptive descriptor with these two socket options, its time-out setting is applied to all read or write operations of the descriptive descriptor. The So_rcvtimeo socket option can only be applied to a read operation, while the SO_SNDTIMEO socket option can only be applied to a write operation.

Both support only part of the implementation. For example, the Connect function cannot use these two socket options.


Recv and send functions

/* Transfer Data *//* * Function function: send data; * Return value: Returns the number of bytes sent if successful. Returns 1 if an error occurs; * Function prototype: */#include <sys/socket.h>ssize_t send (int sockfd, void *buff, size_t nbytes, int flags); */* Description * The function is similar to the Write function, except for the identifier flags.  The other is the same; * The value of the flags identifier such as the following: * (1) Msg_dontroute do not route data out of the local network * (2) msg_dontwait agree to non-blocking operation * (3) Msg_eor assumed protocol support, this is the end of the record * (4) Msg_oob hypothesis protocol support. Send out out-of-band data * If send returns successfully, it does not necessarily mean that the connection and one end of the process is receiving data, only to say that the data has been sent to the network without errors. * * For protocols that support message throttling, if the message exceeds the maximum size supported by the protocol, send fails and errno is set to emsgsize; * for byte stream protocol. Send will clog until the entire data is transmitted; *//* * Function: Receive data; * Return value: The length of the message in bytes, or 0 if no message is available or the other party has already ordered the end. Returns 1 if an error occurs; * Function prototype: */#include <sys/socket.h>ssize_t recv (int sockfd, void *buff, size_t nbytes, int flags); */* Description * The function is similar in function to the Read function, except that there is the identifier flags, the other is the same; * The value of the flags identifier such as the following: * (1) Msg_peek returns the message content without actually taking the message. View Readable data * (2) Msg_trunc even if the message is truncated, the actual length of the message is required to return * (3) Msg_waitall wait until all data is available * (4) Msg_oob assuming protocol support, sending out out of band data * ( 5) Msg_dontwait agree to non-clogging operation * */
The following is the function of the flags flag:

    1. Msg_dontroute: This flag tells the kernel. The destination host is on a direct-attached local network, so there is no need to run a routing table lookup.
    2. Msg_dontwait: This flag without opening the corresponding socket non-clogging flag, the single I/O operation is temporarily designated as non-clogging, then run I/O operation, and then close the non-clogging flag;
    3. Msg_oob: If the agreement is supported, the out-of-band data can be sent;
    4. Msg_peek: This flag applies to the recv and recvfrom functions, it agrees to view the data that is already readable, and the system does not discard the data after recv or Recvfrom is returned.
    5. Msg_waitall: Wait for all data to be available.

READV and Writev functions

These two functions are similar to the read and write functions, but they support multiple buffer operations. Its definition is as follows:

/* Read, write multiple non-contiguous buffers *//* * Function function: Read data to multiple discontinuous buffers, or write data from multiple non-contiguous buffers to a file. * Return value: Returns the number of bytes read and written if successful, or 1 if an error occurs. * Function Prototype: */#include <sys/uio.h>ssize_t readv (int filedes, const struct IOVEC *iov, int iovcnt); ssize_t writev (int fil Edes, const struct IOVEC *iov, int iovcnt);/* Description: * IOVEC pointer structure such as the following: */struct iovec{    void *iov_base;     /* Starting address of buffer */    size_t Iov_len;     /* Size of buffer */};


Recvmsg and SENDMSG functions

These two functions are general-purpose I/O functions that can be replaced with the I/O functions described earlier. Its definition is as follows:

ssize_t recvmsg (int sockfd, struct MSGHDR *msg, int flags); ssize_t sendmsg (int sockfd, const struct MSGHDR *msg, int flags );/* * Description * This function can use more than one choice to send data through the socket, can specify the multi-buffer data transfer, similar to READV function; * The MSGHDR structure includes at least the following members: */struct msghdr{    void        *msg_ Name;      /* Optional Address */    socklen_t   Msg_namelen;    /* Address size in bytes */    struct Iovec *msg_iov;      /* Array of IO buffers */    int         Msg_iovlen;     /* Number of elements in array */    void        *msg_control;   /* Ancillary data */    socklen_t   msg_controllen;/* Number of ancillary bytes */    int         msg_flags;      /* Flags for recevied message */};


Resources:

"Unix Network Programming"

Copyright notice: This article Bo Master original articles, blogs, without consent may not be reproduced.

"Network Programming" advanced I/O

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.