uint32_tntohl(uint32_t __netlong); // network to host long uint16_tntohs(uint16_t __netshort); // network to host short uint32_thtonl(uint32_t __hostlong); uint16_thtons(uint16_t __hostshort);
其中,int32 型函数通常用来转换 IP
地址;int16 型函数通常用来转换端口号。
IP 地址转换函数
1 2 3 4 5 6 7 8 9 10 11 12 13
#include<arpa/inet.h>
/* Convert Internet host address from numbers-and-dots notation in CP into binary data in network byte order. */ in_addr_tinet_addr(constchar *__cp); // 失败时返回 INADDR_NONE
/* Convert Internet host address from numbers-and-dots notation in CP into binary data and store the result in the structure INP. */ intinet_aton(constchar *__cp, struct in_addr *__inp);
/* Convert Internet number in IN to ASCII representation. The return value is a pointer to an internal array containing the string. */ char *inet_ntoa(struct in_addr __in); // 不可重入(如需要记录点分十进制 IP 地址,需拷贝到另外内存地址)
创建 socket
1 2 3 4 5 6 7 8 9 10
#include<sys/types.h> #include<sys/socket.h>
/* Create a new socket of type TYPE in domain DOMAIN, using protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically. Returns a file descriptor for the new socket, or -1 for errors. */ intsocket(int __domain, int __type, int __protocol); // domain 参数可选值: PF_INET 表示 IPv4;PF_INET6 表示 IPv6 // type 参数可选值:SOCK_STREAM 表示 TCP;SOCK_UGRAM 表示 UDP // protocol 一般都设置为 0,表示使用默认协议
命名 socket
服务端需要调用 bind 函数以给 socket 命名地址(IP
地址、端口号等),定义如下:
1 2 3 4 5
#include<sys/types.h> #include<sys/socket.h>
/* Give the socket FD the local address ADDR (which is LEN bytes long). */ intbind(int __fd, conststruct sockaddr* __addr, socklen_t __len);
监听 socket
使用 listen
函数创建监听队列以存放待处理的客户端连接:
1 2 3 4 5 6
#include<sys/socket.h>
/* Prepare to accept connections on socket FD. N connection requests will be queued before further requests are refused. Returns 0 on success, -1 for errors. */ intlisten(int __fd, int __n);
接受连接
1 2 3 4 5 6 7 8 9 10
#include<sys/types.h> #include<sys/socket.h>
/* Await a connection on socket FD. When a connection arrives, open a new socket to communicate with it, set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting peer and *ADDR_LEN to the address's actual length, and return the new socket's descriptor, or -1 for errors. */ intaccept(int __fd, struct sockaddr *__addr, socklen_t *__addr_len);
发起连接
客户端需要通过如下调用主动与服务器建立连接:
1 2 3 4 5 6 7 8
#include<sys/types.h> #include<sys/socket.h>
/* Open a connection on socket FD to peer at ADDR (which LEN bytes long). For connectionless socket types, just set the default address to send to and the only address from which to accept transmissions. Return 0 on success, -1 for errors. */ intconnect(int __fd, conststruct sockaddr *__addr, socklen_t __len);
/* Shut down all or part of the connection open on socket FD. HOW determines what to shut down: SHUT_RD = No more receptions; SHUT_WR = No more transmissions; SHUT_RDWR = No more receptions or transmissions. Returns 0 on success, -1 for errors. */ intshutdown(int __fd, int __how);
TCP 数据读写
1 2 3 4 5 6 7 8 9 10 11
#include<sys/types.h> #include<sys/socket.h>
/* Read N bytes into BUF from socket FD. Returns the number read or -1 for errors. */ ssize_trecv(int __fd, void *__buf, size_t __n, int __flags);
/* Send N bytes of BUF to socket FD. Returns the number sent or -1. */ ssize_tsend(int __fd, constvoid *__buf, size_t __n, int __flags);
/* Read N bytes into BUF through socket FD. If ADDR is not NULL, fill in *ADDR_LEN bytes of it with tha address of the sender, and store the actual size of the address in *ADDR_LEN. Returns the number of bytes read or -1 for errors. */ ssize_trecvfrom(int __fd, void *__buf, size_t __n, int __flags, struct sockaddr* __addr, socklen_t * __addr_len);
/* Send N bytes of BUF on socket FD to peer at address ADDR (which is ADDR_LEN bytes long). Returns the number sent, or -1 for errors. */ ssize_tsendto(int __fd, constvoid *__buf, size_t __n, int __flags, conststruct sockaddr* __addr, socklen_t __addr_len);
/* Receive a message as described by MESSAGE from socket FD. Returns the number of bytes read or -1 for errors. */ ssize_trecvmsg(int __fd, struct msghdr *__message, int __flags);
/* Send a message described MESSAGE on socket FD. Returns the number of bytes sent, or -1 for errors. */ ssize_tsendmsg(int __fd, conststruct msghdr *__message, int __flags);
// msghdr 结构体定义 /* Structure describing messages sent by `sendmsg' and received by `recvmsg'. */ structmsghdr { void *msg_name; /* Address to send to/receive from. */ socklen_t msg_namelen; /* Length of address data. */
structiovec *msg_iov;/* Vector of data to send/receive into. */ size_t msg_iovlen; /* Number of elements in the vector. */
void *msg_control; /* Ancillary data (eg BSD filedesc passing). */ size_t msg_controllen; /* Ancillary data buffer length. !! The type should be socklen_t but the definition of the kernel is incompatible with this. */
int msg_flags; /* Flags on received message. */ };
// iovoc 结构体定义 /* Structure for scatter/gather I/O. */ structiovec { void *iov_base; /* Pointer to data. */ size_t iov_len; /* Length of data. */ };
带外标记
1 2 3 4 5
#include<sys/socket.h>
/* Determine whether socket is at a out-of-band mark. */ intsockatmark(int __fd); // 判断下一个被读取到的数据是否是带外数据
地址信息函数
1 2 3 4 5 6 7 8
#include<sys/socket.h>
/* Put the local address of FD into *ADDR and its length in *LEN. */ intgetsockname(int __fd, struct sockaddr* __addr, socklen_t * __len);
/* Put the address of the peer connected to socket FD into *ADDR (which is *LEN bytes long), and its actual length into *LEN. */ intgetpeername(int __fd, struct sockaddr* __addr, socklen_t * __len);
socket 选项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#include<sys/socket.h>
/* Put the current value for socket FD's option OPTNAME at protocol level LEVEL into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's actual length. Returns 0 on success, -1 for errors. */ intgetsockopt(int __fd, int __level, int __optname, void * __optval, socklen_t * __optlen);
/* Set socket FD's option OPTNAME at protocol level LEVEL to *OPTVAL (which is OPTLEN bytes long). Returns 0 on success, -1 for errors. */ intsetsockopt(int __fd, int __level, int __optname, constvoid *__optval, socklen_t __optlen);
/* Description of data base entry for a single host. */ structhostent { 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. */ };
/* Description of data base entry for a single service. */ structservent { char *s_name; /* Official service name. */ char **s_aliases; /* Alias list. */ int s_port; /* Port number. */ char *s_proto; /* Protocol to use. */ };