《APUE》chapter 16 Network IPC: Sockets 学习笔记(加上自己的代码)
Network IPC: Sockets
Socket Descriptors
#include <sys/socket.h>
int socket(int domain,int type ,int protocol);
Returns: file (socket) descriptor if OK, ?1 on error
The domain argument determines the nature of the communication, including the address format /* Protocol families. */ #define PF_UNSPEC 0 /* Unspecified. */ #define PF_LOCAL 1 /* Local to host (pipes and file-domain). */ #define PF_UNIX PF_LOCAL /* POSIX name for PF_LOCAL. */ #define PF_FILE PF_LOCAL /* Another non-standard name for PF_LOCAL. */ #define PF_INET 2 /* IP protocol family. */ #define PF_AX25 3 /* Amateur Radio AX.25. */ #define PF_IPX 4 /* Novell Internet Protocol. */ #define PF_APPLETALK 5 /* Appletalk DDP. */ #define PF_NETROM 6 /* Amateur radio NetROM. */ #define PF_BRIDGE 7 /* Multiprotocol bridge. */ #define PF_ATMPVC 8 /* ATM PVCs. */ #define PF_X25 9 /* Reserved for X.25 project. */ #define PF_INET6 10 /* IP version 6. */ #define PF_ROSE 11 /* Amateur Radio X.25 PLP. */ #define PF_DECnet 12 /* Reserved for DECnet project. */ #define PF_NETBEUI 13 /* Reserved for 802.2LLC project. */ #define PF_SECURITY 14 /* Security callback pseudo AF. */ #define PF_KEY 15 /* PF_KEY key management API. */ #define PF_NETLINK 16 #define PF_ROUTE PF_NETLINK /* Alias to emulate 4.4BSD. */ #define PF_PACKET 17 /* Packet family. */ #define PF_ASH 18 /* Ash. */ #define PF_ECONET 19 /* Acorn Econet. */ #define PF_ATMSVC 20 /* ATM SVCs. */ #define PF_RDS 21 /* RDS sockets. */ #define PF_SNA 22 /* Linux SNA Project */ #define PF_IRDA 23 /* IRDA sockets. */ #define PF_PPPOX 24 /* PPPoX sockets. */ #define PF_WANPIPE 25 /* Wanpipe API sockets. */ #define PF_LLC 26 /* Linux LLC. */ #define PF_CAN 29 /* Controller Area Network. */ #define PF_TIPC 30 /* TIPC sockets. */ #define PF_BLUETOOTH 31 /* Bluetooth sockets. */ #define PF_IUCV 32 /* IUCV sockets. */ #define PF_RXRPC 33 /* RxRPC sockets. */ #define PF_ISDN 34 /* mISDN sockets. */ #define PF_PHONET 35 /* Phonet sockets. */ #define PF_IEEE802154 36 /* IEEE 802.15.4 sockets. */ #define PF_CAIF 37 /* CAIF sockets. */ #define PF_ALG 38 /* Algorithm sockets. */ #define PF_NFC 39 /* NFC sockets. */ #define PF_MAX 40 /* For now.. */ /* Address families. */ #define AF_UNSPEC PF_UNSPEC #define AF_LOCAL PF_LOCAL #define AF_UNIX PF_UNIX #define AF_FILE PF_FILE #define AF_INET PF_INET #define AF_AX25 PF_AX25 #define AF_IPX PF_IPX #define AF_APPLETALK PF_APPLETALK #define AF_NETROM PF_NETROM #define AF_BRIDGE PF_BRIDGE #define AF_ATMPVC PF_ATMPVC #define AF_X25 PF_X25 #define AF_INET6 PF_INET6 #define AF_ROSE PF_ROSE #define AF_DECnet PF_DECnet 。。。。。 省略,类似 #define AF_ALG PF_ALG #define AF_NFC PF_NFC #define AF_MAX PF_MAX
socket type
enum __socket_type { SOCK_STREAM = 1, /* Sequenced, reliable, connection-based byte streams. */ #define SOCK_STREAM SOCK_STREAM SOCK_DGRAM = 2, /* Connectionless, unreliable datagrams of fixed maximum length. */ #define SOCK_DGRAM SOCK_DGRAM SOCK_RAW = 3, /* Raw protocol interface. */ #define SOCK_RAW SOCK_RAW SOCK_RDM = 4, /* Reliably-delivered messages. */ #define SOCK_RDM SOCK_RDM SOCK_SEQPACKET = 5, /* Sequenced, reliable, connection-based, datagrams of fixed maximum length. */ #define SOCK_SEQPACKET SOCK_SEQPACKET SOCK_DCCP = 6, /* Datagram Congestion Control Protocol. */ #define SOCK_DCCP SOCK_DCCP SOCK_PACKET = 10, /* Linux specific way of getting packets at the dev level. For writing rarp and other similar things on the user level. */ #define SOCK_PACKET SOCK_PACKET /* Flags to be ORed into the type parameter of socket and socketpair and used for the flags parameter of paccept. */ SOCK_CLOEXEC = 02000000, /* Atomically set close-on-exec flag for the new descriptor(s). */ #define SOCK_CLOEXEC SOCK_CLOEXEC SOCK_NONBLOCK = 00004000 /* Atomically mark descriptor(s) as non-blocking. */ #define SOCK_NONBLOCK SOCK_NONBLOCK };
With a datagram ( SOCK_DGRAM)interface, no logical connection needs to exist between peers for them to communicate. All you need to do is send a message addressed to the socket being used by the peer process.
#include <sys/socket.h> int shutdown(int sockfd ,int how ); Returns: 0 if OK,?1 on error
If how is SHUT_RD,then reading from the socket is disabled. If how is SHUT_WR,then we can’t use the socket for transmitting data. We can use SHUT_RDWR to disable both data transmission and reception.
Addressing
Byte Ordering
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostint32 );
Returns: 32-bit integer in network byte order
uint16_t htons(uint16_t hostint16 );
Returns: 16-bit integer in network byte order
uint32_t ntohl(uint32_t netint32);
Returns: 32-bit integer in host byte order
uint16_t ntohs(uint16_t netint16);
Returns: 16-bit integer in host byte order
The h is for ‘‘host’’byte order,and the n is for ‘‘network’’byte order.The l is for ‘‘long’’ (i.e., 4-byte) integer ,and the s is for ‘‘short’ ’( i.e., 2-byte) integer
Address Formats
/* Structure describing a generic socket address. */ struct sockaddr { __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */ char sa_data[14]; /* Address data. */ };
#include <arpa/inet.h> const char *inet_ntop(intdomain,const void *restrict addr , char *restrict str,socklen_t size ); Returns: pointer to address string on success, NULL on error int inet_pton(int domain,const char *restrict str, void *restrict addr ); Returns: 1 on success, 0 if the format is invalid, or ?1 on error
Address Lookup
/* Description of data base entry for a single host. */
struct hostent
{
char *h_name; /* Official name of host. */
char **h_aliases; /* Alias list. */
int h_addrtype; /* Host address type. */
int h_length; /* Length of address. */
char **h_addr_list; /* List of addresses from name server. */
#if defined __USE_MISC || defined __USE_GNU
# define h_addr h_addr_list[0] /* Address, for backward compatibility.*/
#endif
};
#include <netdb.h> struct hostent *gethostent(void); Returns: pointer if OK,NULL on error void sethostent(int stayopen ); void endhostent(void);
If the host database file isn’t already open, gethostent will open it. The gethostent function returns the next entry in the file. The sethostent function will open the file or rewind it if it is already open. When the stay open argument is set to a nonzero value, the file remains open after calling gethostent.The endhostent function can be used to close the file.
struct netent { char *n_name; /* Official name of network. */ char **n_aliases; /* Alias list. */ int n_addrtype; /* Net address type. */ uint32_t n_net; /* Network number. */ }; #include <netdb.h> struct netent *getnetbyaddr(uint32_t net,int type ); struct netent *getnetbyname(const char *name); struct netent *getnetent(void); All return: pointer if OK, NULL on error void setnetent(int stayopen ); void endnetent(void);
/* Description of data base entry for a single service. */ struct protoent { char *p_name; /* Official protocol name. */ char **p_aliases; /* Alias list. */ int p_proto; /* Protocol number. */ }; #include <netdb.h> struct protoent *getprotobyname(const char *name); struct protoent *getprotobynumber(int proto); struct protoent *getprotoent(void); All return: pointer if OK, NULL on error void setprotoent(intstayopen ); void endprotoent(void);
servent:
/* Description of data base entry for a single service. */ struct servent { char *s_name; /* Official service name. */ char **s_aliases; /* Alias list. */ int s_port; /* Port number. */ char *s_proto; /* Protocol to use. */ }; #include <netdb.h> struct servent *getservbyname(const char *name,const char *proto); struct servent *getservbyport(int port ,const char *proto); struct servent *getservent(void); All return: pointer if OK, NULL on error void setservent(int stayopen ); void endservent(void);
/* Structure to contain information about address of a service provider. */ struct addrinfo { int ai_flags; /* Input flags. */ int ai_family; /* Protocol family for socket. */ int ai_socktype; /* Socket type. */ int ai_protocol; /* Protocol for socket. */ socklen_t ai_addrlen; /* Length of socket address. */ struct sockaddr *ai_addr; /* Socket address for socket. */ char *ai_canonname; /* Canonical name for service location. */ struct addrinfo *ai_next; /* Pointer to next in list. */ };
#include <sys/socket.h>
#include <netdb.h>
int getaddrinfo(const char *restrict host ,const char *restrictservice ,
const struct addrinfo *restrict hint ,struct addrinfo **restrict re s);
Returns: 0 if OK, nonzer oerror code on error
void freeaddrinfo(struct addrinfo *ai );
#include <stdio.h> #include <netdb.h> #include <arpa/inet.h> #if defined (BSD) || defined (MACOS) #include <sys/socket.h> #include <netinet/in.h> #endif void print_family(struct addrinfo *aip) { printf("family"); switch(aip->ai_family) { case AF_INET: printf("inet"); break; case AF_INET6: printf("inet6"); break; case AF_UNIX: printf("unix"); break; case AF_UNSPEC: printf("unspecified"); break; default: printf("unknowm"); } } void print_type(struct addrinfo *aip) { printf(" type "); switch (aip->ai_socktype) { case SOCK_STREAM : printf("stream"); break; case SOCK_DGRAM: printf("datagram"); break; case SOCK_SEQPACKET: printf("seqpacket"); break; case SOCK_RAW: printf("raw"); break; default: printf("unknown (%d)",aip->ai_socktype); } } void print_protocol(struct addrinfo *aip) { printf(" protocol "); switch (aip->ai_protocol) { case 0: printf("default"); break; case IPPROTO_TCP: printf("TCP"); break; case IPPROTO_UDP: printf("UDP"); break; case IPPROTO_RAW: printf("RAW"); break; default: printf("unknown (%d)",aip->ai_protocol); } } void print_flags(struct addrinfo* aip) { printf(" flags "); if(aip->ai_flags == 0) { printf(" 0"); } else { if(aip->ai_flags & AI_PASSIVE) { printf("passive"); } if(aip->ai_flags & AI_CANONNAME) { printf(" canon"); } if(aip->ai_flags & AI_NUMERICHOST) { printf(" numhost"); } #if defined (AI_NUMERICSERV) if(aip->ai_flags & AI_NUMERICSERV) { printf(" numserv"); } #endif #if defined (AI_V4MAPPED) if(aip->ai_flags & AI_V4MAPPED) { printf(" v4mapped"); } #endif #if defined (AI_ALL) if(aip->ai_flags & AI_ALL) { printf(" all"); } #endif } } int main(int argc,char* argv[]) { struct addrinfo *aip,*ailist; struct addrinfo hint; struct sockaddr_in *sinp; const char* add; int err; char abuf[INET_ADDRSTRLEN]; if(argc != 3) { printf("usage : %s nodename service\n",argv[0]); return 0; } hint.ai_flags = AI_CANONNAME; hint.ai_family = 0; hint.ai_socktype = 0; hint.ai_protocol = 0; hint.ai_addrlen = 0; hint.ai_canonname = NULL; hint.ai_addr = NULL; hint.ai_next = NULL; if((err = getaddrinfo(argv[1],argv[2],&hint,&ailist)) != 0) { printf(" getaddrinfo error\n"); return 0; } for(aip = ailist; aip != NULL;aip = aip->ai_next) { print_flags(aip); print_family(aip); print_type(aip); print_protocol(aip); printf("\n\thost %s",aip->ai_canonname ? aip->ai_canonname:"-"); if(aip->ai_family == AF_INET) { sinp = (struct sockaddr_in*)aip->ai_addr; add = inet_ntop(AF_INET,&sinp->sin_addr,abuf,INET_ADDRSTRLEN); printf(" address %s",add ? add : "unknown"); printf(" port %d",ntohs(sinp->sin_port)); } printf("\n"); } return 0; }
flags canonfamilyinet type stream protocol TCP
host ubuntu address 127.0.1.1 port 2049
flags canonfamilyinet type datagram protocol UDP
host - address 127.0.1.1 port 2049
Associating Addresses with Sockets
#include <sys/socket.h> int bind(int sockfd ,const struct sockaddr *addr ,socklen_t len); Returns: 0 if OK,?1 on error
There are s everal restrictions on the address we can use:
?The address we specify must be valid for the machine on which the process is running; we can’t specify an address belonging to some other machine.
?The address must match the format supported by the address family we used to create the socket
?The port number in the address cannot be less than 1,024 unless the process has the appropriate privilege (i.e., is the superuser).
?Usually ,only one socket endpoint can be bound to a given address, although some protocols allow duplicate bindings.
#include <sys/socket.h> int getsockname(int sockfd ,struct sockaddr *restrict addr , socklen_t *restrict alenp); Returns: 0 if OK,?1 on error
#include <sys/socket.h> int getpeername(int sockfd ,struct sockaddr *restrict addr , socklen_t *restrict alenp); Returns: 0 if OK,?1 on error
Connection Establishment
#include <sys/socket.h> int connect(intsockfd ,const struct sockaddr *addr ,socklen_t len); Returns: 0 if OK,?1 on error
If sockfd is not bound to an address, connect will bind a default address for the caller
#include <sys/socket.h> int listen(int sockfd ,int backlog ); Returns: 0 if OK,?1 on error
Once a server has called listen,t he socket used can receive connect requests. We use the accept function to retrieve a connect request and convert it into a connection.
#include <sys/socket.h> int accept(int sockfd ,struct sockaddr *restrict addr , socklen_t *restrict len); Returns: file (socket) descriptor if OK, ?1 on error
《APUE》chapter 16 Network IPC: Sockets 学习笔记(加上自己的代码),古老的榕树,5-wow.com
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。