IO特性(1): socket相关的几个高级IO函数(Unix网络编程笔记)

来源:互联网 发布:linux dhcp原理 编辑:程序博客网 时间:2024/04/28 22:16

Subject: Advanced I/O Function


1: There are three ways to set timeout(block):
    First,signal driver: relying on the signal handle function of signal SIGALRM to generate a signal SIGINT to the blocked funtion, suck as connect, recv, read etc. Then the blocked function will return and get a EINTR error. For example:


  1. Second, select function, this will make all read or write or except file descriptor blocked at the call of select but not the read or write unless one or more event happens, then select will choose the correct descriptor to process the event.This function can be used with any type descriptors including socket(tcp, udp or sctp),pipe(FIFO), file descriptor and so forth(This illustrates the philosophy of UNIX: everything is a file). This function is also a implementation of multiplex of IO(pselect, poll as the same).

    fuction prototype:        


    There are also four macro two handle the structure of fd_set, they are:
        

    Because the fd_set is a structure of int array, so you can assign a fd_set to another
    The last arguement of select implement the functon of setting the timeout, it can attain to a precision of millisecond.
    The reture value of select: -1 on an error, 0 if a timeout occurs, or a positive value specifying the number of ready descriptors.
    Last, seting the SO_SNDTIMEO and SO_RCVTIMEO option of setsockopt function. Autovividly, this just impact on the socket descriptor. For example:
 

2: The flag of function of send and recv
    These two functions are similar to the standard read and write, other than the last flag argument.
    These flags are:
    MSG_DONTROUTE: tell the kernel not to perform a lookup of the routing table.(only send)
    MSG_DONTWAITE: tell the kernel perform the read or write function once the buffer not empty.
    MSG_OOB:       tell the kernel there are out_of_band data int the datagram(truely one byte,tcp head URG option).
    MSG_PEEK:      (only recv) authenticate the header before receiving the data int the buffer.
    MSG_WAITALL:   tell the kernel not to return from a read function until the requested number of bytes have been read.(I think this flag relates with the SO_RCVLOWAT socket option ).

    MSG_PEEK is not a good flag for tcp since the data size is not specified.
3: Scatter read and gather write: readv and writev


From the structure, we can see these two function are not type-specified. They are operation just on memory.
There is some limit to the number of elements int array of iovec structures. POSIX requires that the constant IOV_MAX be defined and that its value be at least 16.

4: recvmsg and sendmsg functions(#include <sys/socket.h>)
    Various input or output functions could be replaced with calls to these two functions.


The return msg_flags value including MSG_OOB, MSG_EOR, MSG_BCAST, MSG_MCAST, MSG_NOTIFICATION and so forth.
MSG_EOR: at least one error occurs.
MSG_BCAST: broadcast datagram.
MSG_TRUNC: the datagram was truncated, there are more data than iovlen indicated
MSG_CTRUNC: the ancillary data was truncate, there are more data than controllen indicated
MSG_MCAST: multicast datagram.
MSG_NOTIFICATION: only for SCTP, an event notification

Ancillary Data:

 


   Msg_control points to the first ancillary data object, and the total length of the ancillary data is specified by msg_controllen. Each object is preceded by a cmsghdr structure that describe the object. There are paddings surely.
   The ancillary data returned by recvmsg can contain any number of ancillary data objects.
   The macros processing the ancillary data:

 

   These macros would be used in the following pseudocode:
 

5: Sockets and StandardI/O
    We can use fdopen(sockfd, flag) to make a socket become a standart I/O stream, and then use the standard I/O function. But notice: wo should not use fp = fdopen(sockfd, "r/+|w/+"), since we could lose the control of the I/O somehow and eventually lead to unpredictable error. The best way is:


    This is a full-duplex way while the TCP and UDP socket are duplex.
    There is also a buffering problem when we use the standard I/O to communicate with the other side because of standard I/O's buffer. This pushes the input data into the buffer but not write until the buffer is full or enforced to write(fflush(fp) or EOF is encountered(FIN is sent, then exit not _exit is called, the latter will lose all data in the buffer)).
    Ther are three types of buffering performed by the standard I/O library: fully buffered(stdout, stdin), line buffered(stream refer to terminal device) and unbuffered(stderr). We can use the function setvbuf to set these options(see also setbuf, setbuffer, setlinebug). BEST not using the standard I/O for sockets.


原创粉丝点击