socket网络编程常用C语言api函数(Linux)

参考《Linux高性能服务器编程》


字节序

#include <arpa/inet.h>
//htonl 把unsigned long类型从主机序转换到网络序
uint32_t htonl(uint32_t hostlong);	
	 
//htons 把unsigned short类型从主机序转换到网络序
uint16_t htons(uint16_t hostshort);	
	 
//ntohl 把unsigned long类型从网络序转换到主机序
uint32_t ntohl(uint32_t netlong);
		
//ntohs 把unsigned short类型从网络序转换到主机序
uint16_t ntohs(uint16_t netshort);

ip转换

#include <arpa/inet.h>
//点分十进制转二进制
int inet_pton(int family, const char *strptr, void *addrptr);
	
//二进制转点分十进制
const char * inet_ntop(int family, const void *addrptr, char *strptr, size_t len);	
  • family:AF_INET(ipv4)、AF_INET6(ipv6)
  • strptr:点分十进制字符串
  • addrptr:二进制地址
  • len:strptr需要的大小

地址结构体

  • 通用地址结构

    #inlcude <bits/socket.h>
    struct sockaddr
    {
        sa_family_t sa_family;
        char sa_data[14];
    };
    struct sockaddr_storage
    {
        sa_family_t sa_family;
        unsigned long int __ss_align;
        char __ss_padding[128-sizeof(__ss_align)]; //用于结构体对齐
    };
    
  • 专用地址结构体

    #include <sys/un.h>
     
    // unix域
    struct sockaddr_un
    {
        sa_family_t sun_family;     // 地址族:AF_UNIX
        char sun_path[108];         // 文件路径名
    };
     
    // IPv4
    struct sockaddr_in
    {
        sa_family_t sin_family;     // 地址族:AF_INET
        u_int16_t sin_port;         // 端口号,用网络字节序表示
        struct in_addr sin_addr;    // IPv4地址结构体
    };
    struct in_addr
    {
        u_int32_t s_addr;           // IPv4地址,用网络字节序表示
    };
     
    // IPv6
    struct sockaddr_in6
    {
        sa_family_t sin6_family;    // 地址族:AF_INET6
        u_int16_t sin6_port;        // 端口号,用网络字节序表示
        u_int32_t sin6_flowinfo;    // 流信息,应设置为0
        struct in6_addr sin6_addr;  // IPv6地址结构体
        u_int32_t sin6_scope_id;    // scope ID,尚处于实验阶段
    };
    struct in6_addr
    {
        unsigned char sa_addr[16];  // IPv6地址,用网络字节序表示
    };
    

socket相关函数

  • socket函数 创建socket

    #include <sys/types.h>
    #include <sys/socket.h>	
    int socket(int domain, int type, int protocol);
    
    • protofamily:协议族(family)。AF_INET(IPV4)、AF_INET6(IPV6)、AF_LOCAL、AF_UNIX等。
    • type:指定socket类型。SOCK_STREAM(TCP)、SOCK_DGRAM(UDP)、SOCK_RAW、SOCK_PACKET等。与SOCK_NONBLOCK表示创建非阻塞socket,与SOCK_CLOEXEC表示fork创建的子进程中关闭该socket。
    • protocol:指定协议。IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等。一般填 0 默认和type适配。
  • bind函数 绑定IP地址和端口号

    #include <sys/types.h>
    #include <sys/socket.h>	
    int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
    
    • sockfd: socket描述符

    • addr:前面的地址结构体

    • addrlen: 第二个参数中结构体的大小

  • listen函数 监听

    #include <sys/socket.h>	
    int listen(int sockfd, int backlog);
    
    • sockfd: socket描述符
    • backlog:全连接队列上限
  • connect函数 建立一个连接

    #include <sys/types.h>
    #include <sys/socket.h>	
    int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    
    • sockfd: socket描述符
    • addr:对端地址信息
    • addrlen:addr的大小
  • accept函数 接受一个连接

    #include <sys/types.h>
    #include <sys/socket.h>	
    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 
    
    • sockfd: socket描述符
    • addr:对端地址信息
    • addrlen:addr的大小
  • shutdown函数 关闭套接字的读或写端

    #include <sys/socket.h>	
    int shutdown(int sockfd,int how);
    
    • sockfd: socket描述符
    • how:SHUT_RD 断开输入流;SHUT_WR 断开输出流;SHUT_RDWR 同时断开 I/O 流

数据读写

  • recv和send用于TCP流数据读写

    #include <sys/types.h>
    #include <sys/socket.h>	
    ssize_t recv(int sockfd, void *buf, int len, int flags);
    ssize_t send(int sockfd, const void *buf, size_t len, int flags);
    
    • sockfd: socket描述符
    • buf:数据缓冲区
    • len:buf大小
    • flag:0 阻塞式发送;MSG_NOSIGNAL 当连接断开不产生SIGPIPE信号;MSG_DONTWAIT 非阻塞…
    • 返回:实际发送或接收字节数;<0 出错;recv返回0表示连接断开
  • recvfrom和sendto用于UDP数据报读写

    #include <sys/socket.h>
    ssize_t recvfrom(int sockfd, const void *buf, size_t len, int flags,
    	const struct sockaddr *src_addr, socklen_t *addrlen);
    ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
    	const struct sockaddr *dest_addr, socklen_t addrlen);
    
    • 相比recv和send多出的src_addr和dest_addr为对端的地址信息,addrlen指定其长度。当后两个参数都写NULL等同于recv和send的使用。
  • 通用数据读写sendmsg和recvmsg

    #include <sys/socket.h> 
    ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
    ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
    struct msghdr {
        void          *msg_name;         /* protocol address */
        socklen_t     msg_namelen;       /* size of protocol address */
        struct iovec  *msg_iov;          /* scatter/gatter array */
        int           msg_iovlen         /* elements in msg_iov array */
        void          *msg_control;      /* ancillary data (cmsghdr struct) */
        socklen_t     msg_controllen;    /* length of ancillary data */
        int           msg_flags;         /* flags returned by recvmsg */
    };
    struct iovec {
        ptr_t iov_base; /* Starting address */
        size_t iov_len; /* Length in bytes */
    };
    
    • msg_name、msg_namelen:UDP传输时对端地址结构和其长度,TCP传输时置NULL
    • msg_iov:输入或输出的缓冲区数组,其元素指定了分散的缓冲区的地址和长度,msg_iovlen成员指定了该数组大小
    • msg_control和msg_controllen:辅助数据的位置和大小
    • msg_flags:会复制flag的值,无须设定

获取地址信息

#include <sys/socket.h>
 
 //获取本端socket地址
int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen); 
//获取对端socket地址
int getpeername(int sockfd, struct sockaddr *peeraddr, socklen_t *addrlen);
  • 返回0代表成功,-1代表失败并设置errno

获取或者设置套接字属性

#include <sys/types.h>
#include <sys/socket.h>

int getsockopt(int sock, int level, int optname, void *optval, socklen_t *optlen);
int setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen);
  • sock:套接字描述符

  • level:选项所在的协议层。SOL_SOCKET、IPPROTO_IP、IPPROTO_IPV6、IPPROTO_TCP等

  • optname:需要设置或访问的选项名

  • optval:存放选项值的地址

  • optlen:选项值长度

  • optname:

    选项名称        说明                  数据类型
    ========================================================================
                SOL_SOCKET
    ------------------------------------------------------------------------
    SO_BROADCAST       允许发送广播数据            int
    SO_DEBUG        允许调试                int
    SO_DONTROUTE       不查找路由               int
    SO_ERROR         获得套接字错误             int
    SO_KEEPALIVE      保持连接                int
    SO_LINGER        延迟关闭连接              struct linger
    SO_OOBINLINE      带外数据放入正常数据流         int
    SO_RCVBUF        接收缓冲区大小             int
    SO_SNDBUF        发送缓冲区大小             int
    SO_RCVLOWAT       接收缓冲区下限             int
    SO_SNDLOWAT       发送缓冲区下限             int
    SO_RCVTIMEO       接收超时                struct timeval
    SO_SNDTIMEO       发送超时                struct timeval
    SO_REUSERADDR      允许重用本地地址和端口         int
    SO_TYPE         获得套接字类型             int
    SO_BSDCOMPAT      与BSD系统兼容              int
    ========================================================================
                IPPROTO_IP
    ------------------------------------------------------------------------
    IP_HDRINCL       在数据包中包含IP首部          int
    IP_OPTINOS       IP首部选项               int
    IP_TOS         服务类型
    IP_TTL         生存时间                int
    ========================================================================
                IPPRO_TCP
    ------------------------------------------------------------------------
    TCP_MAXSEG       TCP最大数据段的大小           int
    TCP_NODELAY       不使用Nagle算法             int
    ========================================================================
    

通过域名或地址获取主机信息

#include <netdb.h>
struct hostent *gethostbyname(const char *ghostname);
struct hostent * gethostbyaddr(const char *addr, size_t len , int family);
struct hostent {
    char  *h_name;        /*  official name of host */
    char  **h_aliases;    /*  pointer to array of pointers to alias name */
    int     h_addrtype;   /*  host address type: AF_INET */
    int     h_length;     /*  length of address: 4 */
    char  **h_addr_list;  /*  ptr to array of ptrs with IPv4 addrs */              
}; 
  • h_name:主机规范名
  • h_aliases:主机别名列表
  • h_addrtype:主机ip地址类型
  • h_length :主机ip地址列表长度
  • h_addr_list:主机的ip地址列表(网络字节序)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

money的大雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值