1. Chapter 13.
Advanced
I / O Functions
UNIX Network Programming
1
2. 13.1 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
2
3. 13.2 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 Programming
3
4. Connect with a Timeout Using SIGALRM (figure 13.1)
#include "unp.h"
static void connect_alarm(int);
int connect_timeo(int sockfd, const SA *saptr, socklen_t salen, int nsec)
{
Sigfunc *sigfunc;
int n;
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 Programming
4
5. recvfrom with a Timeout Using SIGALRM (figure 13.2)
#include "unp.h"
static void sig_alrm(int);
void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{
int n;
char sendline[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 timeoutn");
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 Programming
5
6. recvfrom with a Timeout Using select (figure 13.3)
#include "unp.h"
int
readable_timeo(int fd, int sec)
{
fd_set rset;
struct timeval tv;
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 Programming
6
7. 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)
{
int n;
char sendline[MAXLINE], recvline[MAXLINE + 1];
struct timeval tv;
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 timeoutn");
continue;
} else
err_sys("recvfrom error");
}
recvline[n] = 0; /* null terminate */
Fputs(recvline, stdout);
}
} UNIX Network Programming
7
8. 13.3 recv and send Functions
#include <sys/socket.h>
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);
Flags Description recv send
MSG_DONTROUTE bypass routing table lookup •
MSG_DONTWAIT only this operation is nonblocking • •
MSG_OOB send or receive out-of-band data • •
MSG_PEEK peek at incoming message •
MSG_WAITALL wait for all the data •
Figure 13.6 flags for I/O functions
UNIX Network Programming
8
9. 13.4 readv and writev Functions
#include <sys/uio.h>
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_t iov_len; /* size of buffer */
};
– 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.
UNIX Network Programming
9
10. 13.5 recvmsg and sendmsg Functions
#include <sys/socket.h>
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_t msg_namelen; /* size of protocol address */
struct iovec *msg_iov; /* scatter/gather array */
size_t msg_iovlen; /* # elements in msg_iov */
void *msg_control; /* ancillary data; must be aligned
for a cmsghdr structure */
socklen_t msg_controllen; /* length of ancillary data */
int msg_flags; /* flags returned by recvmsg() */
};
UNIX Network Programming
10
11. 13.5 recvmsg and sendmsg Functions (cont.)
Examined by: Examined by: Returned by:
Send flags recv flags
Flag
Sendto flags recvfrom flags
Sendmsg flags recvmsg flags Recvmsg msg_flags
MSG_DONTROUTE •
MSG_DONTWAIT • •
MSG_PEEK •
MSG_WAITALL •
MSG_EOR • •
MSG_OOB • • •
MSG_BCAST •
MSG_MCAST •
MSG_TRUNC •
MSG_CTRUNC •
Figure 13.7 Summary of input and output flags by various I/O functions
UNIX Network Programming
11
12. 13.5 recvmsg and sendmsg Functions (cont.)
m s g h d r{ }
m sg_nam e
m s g _ n a m e le n 16 io v e c { }
m s g _ io v io v_base
100
m s g _ io v le n 3 io v _ le n
m s g _ c o n tro l io v_base
60
m s g _ c o n t r o lle n 20 io v _ le n
m s g _ f la g s 0 io v_base
80
io v _ le n
F ig u r e 1 3 . 8 D a t a s t ru c t u r e s w h e n r e c v m s g is c a lle d f o r a U D P s o c k e t .
UNIX Network Programming
12
13. 13.5 recvmsg and sendmsg Functions (cont.)
s o c k a d d r _ in { }
1 6 , A F _ IN E T , 2 0 0 0
1 9 8 .6 9 .1 0 .2
m s g h d r{ }
m sg_nam e
m s g _ n a m e le n 16 io v e c { } [ ]
m s g _ io v io v _ b a s e
100
m s g _ io v le n 3 io v _ le n
m s g _ c o n tro l io v _ b a s e
60
m s g _ c o n t r o lle n 20 io v _ le n
m s g _ f la g s 0 io v _ b a s e
80
io v _ le n
c m s g _ le n 16
c m s g _ le v e l IP P R O T P _ IP
c m s g _ ty p e IP _ R E C V D S T A D D R
2 0 6 .6 2 .2 2 6 .3 5
F ig u re 1 3 . 9 U p d a t e o f F ig u re 1 3 . 8 w h e n re c v m s g re t u rn .
UNIX Network Programming
13
14. 13.6 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.
Protocol cmsg_level Cmsg_type Description
IPv4 IPPROTO_IP IP_RECVDSTADDR receive destination address with UDP datagram
IP_RECVIF receive interface index with UDP datagram
IPv6 IPPROTO_IPV6 IPV6_DSTOPTS specify / receive destination options
IPV6_HOPLIMIT specify / receive hop limit
IPV6_HOPOPTS specify / receive hop-by-hop options
IPV6_NEXTHOP specify next-hop address
IPV6_PKTINFO specify / receive packet information
IPV6_RTHDR specify / receive routing header
Unix domain SOL_SOCKET SCM_RIGHTS send / receive descriptors
SCM_CREDS send / receive user credentials
Figure 13.11 summary of uses for ancillary data.
UNIX Network Programming
14
15. 13.6 Ancillary Data (cont.)
m s g _ c o n tro l
cmsg_len
cmsg_level c m s g h d r{ }
cmsg_type
CMSG_LEN()
cmsg_len pad a c c i lla r y
d a ta o b je c t
C M S G _S PA C E ()
data
msg_controllen
pad
cmsg_len
cmsg_level c m s g h d r{ }
cmsg_type
CMSG_LEN()
a c c i lla r y
cmsg_len
pad d a ta o b je c t
C M S G _S PA C E ()
data
F ig u r e 1 3 . 1 2 A n c illa r y d a t a c o n t a in in g t w o a n c illa r y d a t a o b je c t s .
UNIX Network Programming
15
16. 13.6 Ancillary Data (cont.)
c m s g h d r{ } c m s g h d r{ }
cmsg_len 16 cmsg_len 16
cmsg_level SO L_S O C KET cmsg_level SO L_SO C KET
cmsg_type S C M _ R IG H T S cmsg_type SC M _C RED S
d is c rip to r
fcred{}
F ig u r e 1 3 . 1 3 c m s g h d r s t r u c t u r e w h e n u s e d w it h U n ix d o m a in s o c k e t s .
UNIX Network Programming
16
17. 13.7 How Much Data Is Queued?
• Three techniques - page 365.
UNIX Network Programming
17
18. 13.8 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
18
19. 13.8 Sockets and Standard I/O
• Example : str_echo Function using standard I/O
#include "unp.h"
void
str_echo(int sockfd)
{
char line[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
19
20. 13.9 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
20
21. 13.9 T/TCP: TCP for Transactions (cont.)
c lie n t s e rv e r
socket, bind,
listen
socket accept(blocks)
sendto SYN, FIN
, d a t a ( re
read(blocks) q ue s t )
a c c e p t re tu rn s
re a d re q u e s t
< s e rv e r p ro c e s s e s re q u e s t>
( rep ly)
SYN, F IN, d at a s e n d r e p ly
en t ' s FIN c lo s e
read returns ac k o f c li
ac k o f s e
rver' s FIN
F ig u r e 1 3 . 1 5 T im e lin e o f m in im a l T / T C P t r a n s a c t io n
UNIX Network Programming
21