Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 51 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
51
Dung lượng
869,93 KB
Nội dung
See protocols(5) or the include file <netinet/in.h> for macro entries such as IPPROTO_TCP. Some programmers prefer, however, to explicitly describe the protocol argument value. This might be important for certain applications in which a specific protocol is required, and no substitution is permitted. This allows you to choose the final protocol used rather than rely on today's "kernel of the month." The downside of this is that when networks and protocols evolve, someone might have to go back and revisit your source code to make it work. In this book, you'll learn about the only four combinations you'll need to use. Using PF_LOCAL and SOCK_STREAM You will use a zero for the protocol argument in the socket(2) or socketpair(2) functions for PF_LOCAL sockets. This is the only supported value for that argument. A valid socket(2) call using PF_LOCAL and SOCK_STREAM is shown as follows: int s; s = socket(PF_LOCAL,SOCK_STREAM,0); if ( s == -1 ) perror("socket()"); This creates a stream socket to allow one process to communicate with another process within the same host. The steps are 1. Integer s is declared to receive the socket number (it is treated the same as a file descriptor). 2. The socket(2) function is called. The domain argument is set to PF_LOCAL, and the socket type argument is set to SOCK_STREAM to request a stream socket. The protocol argument is set to zero, which is the only valid value for PF_LOCAL sockets. 3. The value s is tested to see whether it is the value -1. If it is, then an error has occurred, and errno has the reason for it. Function perror(3) is used in this example to report what the errno code indicates. Linux Socket Programming by Example - Warren W. Gay 104 4. If s is not -1, then it represents a valid socket. It can be used in most places in which a file descriptor is valid (in read(2) and write(2) function calls, for example). Note At the present time, zero is the only valid value for the protocol argument of the socket(2) or socketpair(2) function calls, when the domain argument is PF_LOCAL (or PF_UNIX). Using PF_LOCAL and SOCK_DGRAM You will use SOCK_DGRAM on a local socket when you want to preserve message boundaries. Again, no specific protocol type is permitted for PF_LOCAL domain sockets at this time. Take a look at the following example: int s; s = socket(PF_LOCAL,SOCK_DGRAM,0); if ( s == -1 ) perror("socket()"); The steps used to create this local datagram socket are 1. Integer s is declared to receive the socket number (it is treated the same as a file descriptor). 2. The socket(2) function is called. The domain argument is set to PF_LOCAL, and the socket type argument is set to SOCK_DGRAM to request a datagram socket. The protocol argument is set to zero, which is the only valid value for PF_LOCAL sockets. 3. The value s is tested to see whether it is the value -1. If it is, then an error has occurred, and errno has the reason for it. Function perror(3) is used in this example to report what the errno code indicates. 4. If s is not -1, then it represents a valid socket. Datagram sockets are attractive to use for PF_LOCAL sockets because they are mostly reliable and they preserve message boundaries. They don't get lost in network transmission errors as PF_INET datagrams can, because they remain internal to the local host. However, you should assume that kernel buffer Linux Socket Programming by Example - Warren W. Gay 105 shortages might cause PF_LOCAL packets to be lost, even if this rarely occurs. Note When a socket is created, it is nameless (without an address). A valid socket address must be set up and the function bind(2) called to give the socket an address. Using PF_INET and SOCK_STREAM At the present time, a zero in the protocol argument of the socket(2) function for the domain PF_INET will cause the kernel to choose IPPROTO_TCP. This causes the socket to use the TCP/IP protocol. The TCP part of the TCP/IP designation is the transport level protocol that is built on top of the IP layer. This provides the data packet sequencing, error control, and recovery. In short, TCP makes it possible to provide a stream socket using the Internet protocol. As you see in the following example, most application programmers will choose to simply specify the protocol argument as zero, allowing the kernel to correctly choose the protocol: int s; s = socket(PF_INET,SOCK_STREAM,0); if ( s == -1 ) perror("socket()"); The steps used to create Internet stream sockets are 1. Integer s is declared to receive the socket number. 2. The socket(2) function is called. The domain argument is set to PF_INET to choose the Internet family of protocols. The socket type argument is set to SOCK_STREAM to request a stream socket. The protocol argument is set to zero, which allows the kernel to choose the correct protocol for the combination of PF_INET and SOCK_STREAM. 3. The value s is tested to see whether it is the value -1. If it is, then an error has occurred, and errno has the reason for Linux Socket Programming by Example - Warren W. Gay 106 it. Function perror(3) is used in this example to report what the errno code indicates. 4. If s is not -1, then it represents a valid socket. It can be used in most places where a file descriptor is valid (in read(2) and write(2) function calls, for example). Specifying zero for the protocol argument of socket(2) will imply the use of TCP/IP. However, if you like having full control, or worry that future kernel defaults might be unsuitable, you can explicitly choose the protocol as follows: int s; s = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); if ( s == -1 ) perror("socket()"); Looking only at the socket(2) function call, the arguments can be explained as follows: 1. The domain argument is specified as PF_INET as before, to indicate that the Internet family of protocols is required. 2. The socket type argument is specified as SOCK_STREAM to request a stream I/O socket, as before. 3. The protocol argument, however, has been explicitly specified as IPPROTO_TCP in this case. This chooses the use of the TCP/IP protocol for this socket. The IPPROTO_TCP macro is defined by the include file: #include <netinet/in.h> Using PF_INET and SOCK_DGRAM This section describes the last socket combination that you will use in the applications within this book. The combination of PF_INET and SOCK_DGRAM causes the kernel to choose the UDP protocol. UDP is short for User Datagram Protocol. A datagram is a standalone packet of information. This protocol allows the application to send datagrams from your socket to the remote socket, to which you have addressed it. Note again that this service is not reliable, but it is suitable for many types of services in which efficiency is highly desirable. For example, the Network Time Protocol (NTP) uses Linux Socket Programming by Example - Warren W. Gay 107 UDP because it is efficient and message-oriented, and lost messages can be tolerated. The impact of a lost message is that the time synchronization might take longer to achieve or that some accuracy is lost when expecting replies from multiple NTP servers. To create a UDP socket, you can use zero for the protocol argument. The following shows an example: int s; s = socket(PF_INET,SOCK_DGRAM,0); if ( s == -1 ) perror("socket()"); The procedure used is the same general procedure that has been used in the preceding sections. However, the arguments used in the socket(2) function require explanation: 1. The domain argument is specified as PF_INET, as before, to indicate that the Internet family of protocols is required. 2. The socket type argument is specified as SOCK_DGRAM to request a datagram socket. 3. The protocol argument is specified as zero to allow the kernel to choose the correct protocol for the PF_INET and SOCK_DGRAM combination. However, if you prefer to specify UDP explicitly, you might do it like this instead: int s; s = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP); if ( s == -1 ) perror("socket()"); The arguments for this socket(2) call are described as follows: 1. The domain argument is specified as PF_INET, as before, to indicate that the Internet family of protocols is required. 2. The socket type argument is specified as SOCK_DGRAM to request a datagram socket. 3. The protocol argument is specified as IPPROTO_UDP to explicitly indicate that only the UDP protocol is permitted for this socket. Linux Socket Programming by Example - Warren W. Gay 108 There is a number of other socket combinations that can be created, but these are too advanced to be considered here. You will be happy to know that most of the time you will use only the four socket(2) parameter combinations that have just been described and are summarized in Table 4.1. Table 4.1. Table of Commonly Used Socket Argument Values Domain Socket Type Protocol Description PF_LOCAL SOCK_STREAM 0 Local stream socket PF_LOCAL SOCK_DGRAM 0 Local datagram socket PF_INET SOCK_STREAM IPPROTO_TCP TCP/IP stream socket PF_INET SOCK_DGRAM IPPROTO_UDP UDP datagram socket Note that the last two entries (domain PF_INET) shown in Table 4.1 may have zero specified instead for the protocol argument. This decision is left to the discretion of the programmer. Socket Domain and Type Summary This section has been provided to allow you to review in summary form what you have learned in this chapter. Figure 4.1 illustrates the relationship that exists between the three socket(2) function arguments. You'll notice that the domain argument appears on the left of Figure 4.1. The domain argument is the first argument of the socket(2) and socketpair(2) functions. It is also the least specific of the three values. The domain argument chooses a family of protocols that you want to work with. The second argument defines the socket type. Choosing the socket type eliminates a number of variations within the specified protocol family. Looking at Figure 4.1, you can see that choosing SOCK_DGRAM excludes protocols that stem from SOCK_STREAM above it. Figure 4.1. This diagram summarizes socket(2) parameter relationships. Linux Socket Programming by Example - Warren W. Gay 109 Finally, on the very right, Figure 4.1 provides a sampling of the protocol choices that are available in the socket(2) function call. This parameter finalizes the protocol to be used. Note The remainder of this book will focus on the use of the PF_LOCAL and PF_INET protocol families from the socket interface. This is done in part to keep you focused on the important socket concepts that you need to master. Additionally, these will be the protocol families that you will use most of the time. Other Linux-Supported Protocols Linux is collecting new protocols within the kernel, almost with each new release. Each protocol has its use. For example, the PF_APPLETALK protocol family might be just what you need to make that dusty old Mac more useful to you. With the knowledge of sockets that you will gain in this book, you'll be able to write programs using these and other exotic protocols. Table 4.2 summarizes some of this chapter's information about the local and Internet protocols. Linux Socket Programming by Example - Warren W. Gay 110 Table 4.2. Table of Local and Internet socket(2) Parameters Domain Socket Type Description/Notes PF_LOCAL SOCK_STREAM Provides a stream-oriented socket within the local host. This is a connection-oriented service—reliable and sequenced. Note that PF_UNIX is equivalent to PF_LOCAL. PF_LOCAL SOCK_DGRAM Provides datagram services within the local host. Note that this service is connectionless, but reliable, with the possible exception that packets might be lost if kernel buffers should become exhausted. PF_INET SOCK_STREAM Stream I/O services for Internet connected sockets. Implies the TCP/IP protocol—reliable and sequenced. PF_INET SOCK_DGRAM Datagram I/O services for Internet connectionless sockets. This combination implies UDP (User Datagram Protocol). This service is unreliable. PF_INET6 SOCK_STREAM Stream I/O services for Internet IPv6 connected sockets. Implies the TCP/IP protocol, reliable, and sequenced. PF_INET6 SOCK_SEQPACKET Stream I/O services for Internet IPv6 connected sockets. Implies the use of the TCP/IP protocol. This service is reliable, message boundaries are preserved, and sequence of data is preserved. PF_INET6 SOCK_DGRAM Datagram I/O services for Internet IPv6 connectionless sockets. This combination implies UDP (User Datagram Protocol). This service is unreliable. Table 4.3 includes references to a few exotic protocol families that will not be explored in this book. However, look at this summary as a reference for you to use someday when you go to create that exotic socket. Linux Socket Programming by Example - Warren W. Gay 111 Table 4.3. Table of Exotic socket(2) Parameters Domain Socket Type Description/Notes PF_X25 SOCK_SEQPACKET Stream I/O services for the X.25 protocol. This service is connection-oriented and reliable, message boundaries are preserved, and data sequence is preserved. PF_AX25 SOCK_SEQPACKET Stream I/O services for the amateur radio protocol AX.25. This service is connection- oriented and reliable, message boundaries are preserved, and data sequence is preserved. PF_AX25 SOCK_DGRAM Datagram service for the amateur radio protocol AX.25. This provides for unreliable connectionless communications. PF_APPLETALK SOCK_STREAM Stream I/O services for the AppleTalk-connected sockets. This connection-oriented service is reliable and data sequence is preserved. PF_APPLETALK SOCK_DGRAM This has been provided in Linux as an extension. See kernel documentation or sources for more details. PF_ECONET SOCK_DGRAM An implementation of the Acorn Econet and AUN protocols. PF_IPX SOCK_STREAM IPX protocol, stream socket. PF_IPX SOCK_DGRAM IPX protocol, datagram socket. PF_IPX SOCK_SEQPACKET IPX protocol, sequential packet socket. PF_IRDA SOCK_STREAM IrDA subsystem support, using a stream socket (infrared communications). PF_IRDA SOCK_SEQPACKET IrDA subsystem support, using a stream socket that preserves Linux Socket Programming by Example - Warren W. Gay 112 Table 4.3. Table of Exotic socket(2) Parameters Domain Socket Type Description/Notes message boundaries (infrared communications). PF_NETROM SOCK_SEQPACKET Amateur radio NetROM protocol. PF_ROSE SOCK_SEQPACKET Amateur radio X.25 PLP 1protocol. Researching Other Protocols Many of the protocols listed in Table 4.3 are still undergoing development. Consequently, documentation is sparse in some areas. Nevertheless, here are some ideas regarding where you can scare up more information: • Linux HOWTO and MINI-HOWTO documents. • Linux FAQ documents. • The /usr/src/linux/Documentation/networking Linux source directory. If you use a different source directory, then substitute that for the directory /usr/src/linux. • The Linux source directory /usr/src/linux/net. There, you will find other subdirectories of source code, many of which have to do with specific protocols. There are many HOWTO and MINI-HOWTO documents on the Internet that you can search out. FAQ is short for Frequently Asked Questions. Sometimes these files can be very helpful. Discovering Protocol Families Most of the time, the undocumented features will require that you look at some kernel source code and include files. Do not be daunted by this prospect. Many useful bits of information can be determined by looking at this code, without getting too intimate with the details. The protocol family macros are defined by including the file: #include <sys/socket.h> However, this include file actually includes another file, which then defines the protocol macro constants. The file of interest is the pathname: Linux Socket Programming by Example - Warren W. Gay 113 [...]... inet_aton (3) and bind(2) function calls Linux Socket Programming by Example - Warren W Gay 119 Listing 5.1 bind.c—The bind(2) Function 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30 : 31 : 32 : 33 : 34 : 35 : 36 : 37 : 38 : 39 : 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: /* af_inet.c: * * Demonstrating the bind(2) function * by establishing... Function Call 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30 : 31 : 32 : 33 : 34 : 35 : 36 : 37 : 38 : 39 : 40: 41: 42: 43: 44: /* sckname.c: * * Demonstrate getsockname(2): */ #include #include #include #include #include #include #include #include #include... Function 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30 : 31 : 32 : 33 : 34 : 35 : 36 : 37 : 38 : 39 : 40: 41: 42: 43: 44: 45: 46: /* getpeer.c: * * Demonstrate getpeername(2): */ #include #include #include #include #include #include #include #include #include... the program are 1 Variable sck_inet will receive the socket when it is created (line 31 ) 2 Variable adr_inet will hold the sockets address that will be bound to it (line 32 ) 3 Variable len_inet will hold the length of the socket address in bytes (line 33 ) 4 The socket is created by socket( 2) in line 36 5 Step 4 is checked for errors in lines 38 and 39 If an error is detected, the function bail() is called... for sock_addr() starts in line 33 It accepts as input the socket s for which the function must determine the address The printable socket address is returned in the supplied buffer buf, which is a maximum size of bufsiz bytes Linux Socket Programming by Example - Warren W Gay 126 2 Declarations for temporary values adr_inet and len_inet are declared in lines 36 and 37 3 The maximum length is established... that are supported by the protocol family that you have selected This can usually be done using the following simple procedure: Linux Socket Programming by Example - Warren W Gay 115 1 Change to the Linux kernel source directory (you might need to install it first) For example, this might require you to do cd /usr /linux/ src 2 Change to the Linux network source code subdirectory For example, you would... put sockets to work in the next chapter The Purpose of the bind(2) Function When your socket is created by the socket( 2) function, it is nameless You saw in Chapter 1, "Introducing Sockets," that sockets could be used without addresses when the socketpair(2) function was illustrated However, this worked only because those sockets were created this way, within one Linux kernel This cannot be done for sockets... the address of the socket: */ len_inet = sizeof adr_inet; z = getsockname(s, Linux Socket Programming by Example - Warren W Gay 124 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: (struct sockaddr *)&adr_inet, &len_inet); if ( z ==... #include Linux Socket Programming by Example - Warren W Gay 122 int getsockname(int s, struct sockaddr *name, socklen_t *namelen) This function takes the following three input arguments: 1 The socket s to query for the socket address 2 The pointer to the receiving buffer (argument name) 3 Pointer to the maximum length variable This variable provides the maximum length in bytes that can... variable errno Linux Socket Programming by Example - Warren W Gay 1 23 Writing a sock_addr() Function To illustrate the use of getsockaddr(2), a small function has been presented in Listing 5.2, which accepts as input a socket descriptor The function obtains the socket' s address by calling getsockaddr(2), and then formats a string to be returned to the caller which can be used in a printf (3) call Listing . Socket */ 32 : struct sockaddr_in adr_inet;/* AF_INET */ 33 : int len_inet; /* length */ 34 : 35 : /* Create an IPv4 Internet Socket */ 36 : sck_inet = socket( AF_INET,SOCK_STREAM,0); 37 : 38 : if ( sck_inet. subsystem support, using a stream socket that preserves Linux Socket Programming by Example - Warren W. Gay 112 Table 4 .3. Table of Exotic socket( 2) Parameters Domain Socket Type Description/Notes message. someday when you go to create that exotic socket. Linux Socket Programming by Example - Warren W. Gay 111 Table 4 .3. Table of Exotic socket( 2) Parameters Domain Socket Type Description/Notes PF_X25