Socket API 总结

总是反反复复在用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:

  1. AF_INET用于IPv4, sockaddr_in, 32bit IPv4 address + 16bit port number
  2. AF_INET6用于IPv6,sockaddr_in6, 128bit IPv6 address + 16bit port number

type:

  1. SOCK_STREAM: TCP相关
  2. 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长度的

持续更新中…