总是反反复复在用socket api,但每次都要查询manual,接下来就总结一下这些api吧
基本的Socket API
socket
#incldue <sys/socket.h>
int socket(int domain, int type, int protocal);
Return file descriptor on success, or -1 on error
domain:
- AF_INET用于IPv4, sockaddr_in, 32bit IPv4 address + 16bit port number
- AF_INET6用于IPv6,sockaddr_in6, 128bit IPv6 address + 16bit port number
type:
- SOCK_STREAM: TCP相关
- SOCK_DGRAM: UDP相关
protocal:
基本为0
bind
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr* addr, socklen_t addrlen);
Return 0 on sucess, or -1 on error
关于struct sockaddr,其是一个通用的地址结构,sa_family用于指明是哪种类型(IPv4 or IPv6),sa_data就根据不同的结构进行调整
struct sockaddr {
sa_family_t sa_family; /* Address family (AF_* constant) */
char sa_data[14]; /* Socket address (size varies according to socket domain) */
};
/* IPv4 address */
struct in_addr { /* IPv4 4-byte address */
in_addr_t s_addr; /* Unsigned 32-bit integer */
};
struct sockaddr_in { /* IPv4 socket address */
sa_family_t sin_family; /* Address family (AF_INET) */
in_port_t sin_port; /* Port number */
struct in_addr sin_addr; /* IPv4 address */
unsigned char __pad[X]; /* Pad to size of 'sockaddr' structure (16 bytes) */
};
listen
#include <sys/socket.h>
int listen(int sockfd, int backlog);
Return 0 on success, or -1 on error
关于backlog:简单说就是定义pending队列的长度
accept
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
Return file descriptor on success, or -1 on error
accept的三个参数就比较好理解了,accept后面两个参数是链接过来的ip和port
connect
#include <sys/socket.h>
int connect(int sockfd, struct sockaddr *addr, socklen_t addrlen);
Return 0 on success, or -1 on error
网络格式
网络传输都是大端传输的,所有我们需要对ip和port进行转换(转为大端)。
大端:高位在低地址
小端:高位在高地址
#include <arpa/inet.h>
uint16_t htons(uint16_t host_uint16); /* host to net */
Return host_uint16 converted to network byte order
uint32_t htonl(uint32_t host_uint32); /* host to net */
Return host_uint32 converted to network byte order
uint16_t ntohs(uint16_t net_uint16); /* net to host */
Return net_uint16 coverted to host byte order
uint32_t ntohl(uint32_t net_uint32); /* net to host */
Return net_uint32 converted to host byte order
inet_pton和inet_ntop函数
#include <arpa/inet.h>
int inet_pton(int domain, const char * src_str, void *addrptr);
Return 1 on successful conversion, 0 if src_str is not in
presentation format, or -1 on error
const char *inet_ntop(int domain, const void* addrptr, char *dst_str, size_t len);
Returns pointer to dst_str on success, or NULL on error
inet_pton是将字符串转为in_addr或者in6_addr,因此两个函数的addrptr传入的就是上面这两个addr类型;另外第二个api的len参数是表示dst_str长度的