UNIX Network Programming1 Chapter 13. Advanced I / O Functions
UNIX Network Programming Introduction Socket Timeouts recv and send Functions readv and writev Functions recvmsg and sendmsg Function Ancillary Data How much Data is Queued? Sockets and Standard I/O T/TCP
UNIX Network Programming Socket Timeouts Three ways to place a timeout on an I/O operation involving a socket –Call alarm, which generates the SIGALRM signal when the specified time has expired. –Block waiting for I/O in select, which has a time limit built in, instead of blocking in a call to read or write. –Use the newer SO_RCVTIMEO and SO_SNDTIMEO socket options.
UNIX Network Programming4 Connect with a Timeout Using SIGALRM (figure 13.1) #include"unp.h" static voidconnect_alarm(int); int connect_timeo(int sockfd, const SA *saptr, socklen_t salen, int nsec) { Sigfunc*sigfunc; intn; sigfunc = Signal(SIGALRM, connect_alarm); if (alarm(nsec) != 0) err_msg("connect_timeo: alarm was already set"); if ( (n = connect(sockfd, (struct sockaddr *) saptr, salen)) < 0) { close(sockfd); if (errno == EINTR) errno = ETIMEDOUT; } alarm(0);/* turn off the alarm */ Signal(SIGALRM, sigfunc);/* restore previous signal handler */ return(n); } static void connect_alarm(int signo) { return;/* just interrupt the connect() */ }
UNIX Network Programming5 recvfrom with a Timeout Using SIGALRM (figure 13.2) #include"unp.h" static voidsig_alrm(int); void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) { intn; charsendline[MAXLINE], recvline[MAXLINE + 1]; Signal(SIGALRM, sig_alrm); while (Fgets(sendline, MAXLINE, fp) != NULL) { Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); alarm(5); if ( (n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL)) < 0) { if (errno == EINTR) fprintf(stderr, "socket timeout\n"); else err_sys("recvfrom error"); } else { alarm(0); recvline[n] = 0;/* null terminate */ Fputs(recvline, stdout); } static void sig_alrm(int signo) { return;/* just interrupt the recvfrom() */ }
UNIX Network Programming6 recvfrom with a Timeout Using select (figure 13.3) #include"unp.h" int readable_timeo(int fd, int sec) { fd_setrset; struct timevaltv; FD_ZERO(&rset); FD_SET(fd, &rset); tv.tv_sec = sec; tv.tv_usec = 0; return(select(fd+1, &rset, NULL, NULL, &tv)); /* 4> 0 if descriptor is readable */ }
UNIX Network Programming7 recvfrom with a Timeout Using the SO_RCVTIMEO Socket Option (figure 13.5) void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) { intn; charsendline[MAXLINE], recvline[MAXLINE + 1]; struct timevaltv; tv.tv_sec = 5; tv.tv_usec = 0; Setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); while (Fgets(sendline, MAXLINE, fp) != NULL) { Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL); if (n < 0) { if (errno == EWOULDBLOCK) { fprintf(stderr, "socket timeout\n"); continue; } else err_sys("recvfrom error"); } recvline[n] = 0;/* null terminate */ Fputs(recvline, stdout); }
UNIX Network Programming recv and send Functions #include ssize_t recv (int sockfd, void *buff, size_t nbytes, int flags); ssize_t send (int sockfd, const void *buff, size_t nbytes, int flags);
UNIX Network Programming readv and writev Functions –readv and writev let us read into or write from one or more buffers with a single function call. are called scatter read and gather write. #include ssize_t readv (int filedes, const struct iovec *iov, int iovcnt); ssize_t writev (int filedes, const struct iovec *iov, int iovcnt); Struct iovec { void*iov_base; /* starting address of buffer */ size_tiov_len; /* size of buffer */ };
UNIX Network Programming recvmsg and sendmsg Functions #include ssize_t recvmsg (int sockfd, struct msghdr *msg, int flags); ssize_t sendmsg (int sockfd, struct msghdr *msg, int flags); Struct msghdr { void *msg_name; /* starting address of buffer */ socklen_tmsg_namelen; /* size of protocol address */ struct iovec*msg_iov; /* scatter/gather array */ size_tmsg_iovlen; /* # elements in msg_iov */ void*msg_control; /* ancillary data; must be aligned for a cmsghdr structure */ socklen_tmsg_controllen; /* length of ancillary data */ intmsg_flags; /* flags returned by recvmsg() */ };
UNIX Network Programming recvmsg and sendmsg Functions (cont.)
UNIX Network Programming recvmsg and sendmsg Functions (cont.)
UNIX Network Programming recvmsg and sendmsg Functions (cont.)
UNIX Network Programming Ancillary Data Ancillary data can be sent and received using the msg_control and msg_controllen members of the msghdr structure with sendmsg and recvmsg functions.
UNIX Network Programming Ancillary Data (cont.)
UNIX Network Programming Ancillary Data (cont.)
UNIX Network Programming How Much Data Is Queued? Three techniques - page 365.
UNIX Network Programming Sockets and Standard I/O The standard I/O stream can be used with sockets, but there are a few items to consider. –A standard I/O stream can be created from any desciptor by calling the fdopen function. Similarly, given a standard I/O stream, we can obtain the corresponding descriptor by calling fileno. –fseek, fsetpos, rewind functions is that they all call lseek, which fails on a socket. –The easiest way to handle this read-write problem is to open two standard I/O streams for a given socket: one for reading, and one for writing.
UNIX Network Programming Sockets and Standard I/O Example : str_echo Function using standard I/O #include"unp.h" void str_echo(int sockfd) { charline[MAXLINE]; FILE*fpin, *fpout; fpin = Fdopen(sockfd, "r"); fpout = Fdopen(sockfd, "w"); for ( ; ; ) { if (Fgets(line, MAXLINE, fpin) == NULL) return; /* connection closed by other end */ Fputs(line, fpout); }
UNIX Network Programming T/TCP: TCP for Transactions T/TCP is a slight modification to TCP that can avoid the three- way handshake between hosts that have communicated with each other recently. Benefit –all the reliability of TCP is retained –maintains TCP’s slow start and congestion avoidance, features that are often missing from UDP applications.
UNIX Network Programming T/TCP: TCP for Transactions (cont.)