Linux编程-实录七

Linux编程-回忆录七

====网络通信====
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
创建套接字,domain的值如下:
AF_UNIX     unix域套接字,本地使用
AF_INET     IPV4套接字
AF_INET6    IPV6套接字

type有两种: SOCK_STREAM(TCP流), SOCK_DGRAM(UDP流)
protocol基本恒为0,极少数会去设置它
返回0成功创建,-1失败

#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
绑定套接字到addr地址,返回0成功,-1失败

#include <sys/socket.h>
int listen(int sockfd, int backlog);
监听套接字链接,成功返回0,-1失败

#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
接受客户的链接,返回一个文件描述符,出错返回-1值

#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
建立到addr地址的链接,成功返回0,失败返回-1值

#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buffer, size_t length, int flags,
    struct sockaddr *src_addr, socklen_t *addrlen);
接受UDP数据,成功返回接受的字节数,返回0表示接受完成,-1出错
ssize_t sendto(int sockfd, const void *buffer, size_t length,
    int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
发送UDP数据,成功返回实际发送的字节数,返回-1出错

UNIX套接字地址结构
struct sockaddr_un {
    sa_family_t sun_family; /* 永远等于AF_UNIX */
    char sun_path[108];     /* 域路径名称,以'\0'结束 */
};

#include <sys/socket.h>
int socketpair(int domain, int type, int protocol, int sockfd[2]);
用于进程之间,创建unix域套接字,成功返回0,-1失败

#include <arpa/inet.h>
uint16_t htons(uint16_t host_uint16);
uint16主机字节序转换为网络字节序

uint32_t htonl(uint32_t host_uint32);
uint32主机字节序转换为网络字节序

uint16_t ntohs(uint16_t net_uint16);
uint16网络字节序转换位主机字节序

uint32_t ntohl(uint32_t net_uint32);
uint32网络字节序转换位主机字节序

struct in_addr {
    in_addr_t s_addr    /*无符号的32位整数 */
};

struct sockaddr_in {
    sa_family_t     sin_family; /* 永远标为AF_INET */
    in_port_t       sin_port    /* 端口 */
    struct in_addr  sin_addr;   /* IP地址 */
    unsinged char   __pad[X];   /* 仅用于结构对齐 */
};
sin_port,sin_addr是网络字节序

struct in6_addr {
    uint8_t s6_addr[16];    /* IP6地址 */
};

struct sockaddr_in6 {
    sa_family_t     sin6_family;    /*永远标为AF_INET6 */
    in_port_t       sin6_port;      /* 端口 */
    uint32_t        sin6_flowinfo;  /* IPV6 FLOW INFO */
    struct in6_addr sin6_addr;      /* IPV6地址 */
    uint32_t        sin6_scope_id;  /* 新增的(kernel2.4以上) */
};
全部结构都是网络字节序

#include <arpa/inet.h>
int inet_pton(int domain, const char *src_str, void *addrptr);
转换字符串格式的IP地址为对应的结构体, 返回0成功,-1出错

const char *inet_ntop(int domain, const void *addrptr,
    char *dst_str, size_t len);
转换地址结构体为对应的字符串格式,返回0成功,-1出错

#include <sys/socket.h>
#include <netdb.h>
int getaddrinfo(const char *host, const char *service,
    const struct addrinfo *hints, struct addrinfo **result);
得到hostname,或是service name的IP地址信息,返回0成功,-1失败

#include <sys/socket.h>
#include <netdb.h>
void freeaddrinfo(struct addrinfo *result);
释放上面函数获得IP地址信息,分配的内存

#include <sys/socket.h>
int shutdown(int sockfd, int how);
关闭套接字,方式如下:
1.SHUT_RD   关闭读
2.SHUT_WR   关闭写
返回0表示成功,-1出错

#include <sys/socket.h>
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
返回本地/对端的套接字地址信息,返回0成功,-1失败

#include <sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
通过套接字传输一个文件的内容,返回传输的字节数,返回-1出错

include <sys/socket.h>
int getsockopt(int sockfd, int level, int optname,
    void *optval, socklen_t *optlen);
int setsockopt(int sockfd, int level, int optname,
    const void *optval, socklen_t optlen);
获取/设置套接字的属性,返回0成功,-1失败