ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

linux高性能服务器编程---第五章Linux网络编程基础API (3)

2022-05-06 16:02:58  阅读:179  来源: 互联网

标签:struct int 编程 sockfd API Linux msg address name


通用读写函数
#inclued <sys/socket.h>
ssize_t recvmsg(int sockfd, struct msghdr* msg, int flags);
ssize_t sendmsg(int sockfd, struct msghdr* msg, int flags);

struct msghdr
{
/* socket address --- 指向socket地址结构变量, 对于TCP连接需要设置为NULL*/
    void* msg_name; 


    socklen_t msg_namelen;
    
    /* 分散的内存块 --- 对于 recvmsg来说数据被读取后将存放在这里的块内存中, 内存的位置和长度由
     * msg_iov指向的数组指定, 称为分散读(scatter read)  ---对于sendmsg而言, msg_iovlen块的分散内存中
     * 的数据将一并发送称为集中写(gather write);
    */
    struct iovec* msg_iov;
    int msg_iovlen; /* 分散内存块的数量*/
    void* msg_control; /* 指向辅助数据的起始位置*/
    socklen_t msg_controllen; /* 辅助数据的大小*/
    int msg_flags; /* 复制函数的flags参数, 并在调用过程中更新*/
};

struct iovec
{
    void* iov_base /* 内存起始地址*/
    size_t iov_len /* 这块内存长度*/
}

其他Api

#include <sys/socket.h>
// 用于判断 sockfd是否处于带外标记, 即下一个被读取到的数据是否是带外数据, 
// 是的话返回1, 不是返回0
// 这样就可以选择带MSG_OOB标志的recv调用来接收带外数据. 
int sockatmark(int sockfd);

// getsockname 获取sockfd对应的本端socket地址, 存入address指定的内存中, 长度存入address_len中 成功返回0失败返回-1
// getpeername 获取远端的信息, 同上
int getsockname(int sockfd, struct sockaddr* address, socklen_t* address_len);
int getpeername(int sockfd, struct sockaddr* address, socklen_t* address_len);

/* 以下函数头文件均相同*/

// sockfd 目标socket, level执行操作协议(IPv4, IPv6, TCP) option_name 参数指定了选项的名字. 后面值和长度
// 成功时返回0 失败返回-1
int getsockopt(int sockfd, int level, int option_name, void* option_value, 
                        socklen_t restrict option_len);
int setsockopt(int sockfd, int level, int option_name, void* option_value, 
                        socklen_t restrict option_len);
SO_REUSEADDR重用本地地址sock被设置此属性后, 即使sock在被bind()后处于TIME_WAIT状态, 此时与他绑定的socket地址依然能够立即重用来绑定新的sock
SO_RCVBUF TCP接收缓冲区大小 最小值为256字节. 设置完后系统会自动加倍你所设定的值. 多出来的一倍将用用作空闲缓冲区处理拥塞
SO_SNDBUF TCP发送缓冲区大小 最小值为2048字节
SO_RCVLOWAT 接收的低水位标记 默认为1字节, 当TCP接收缓冲区中可读数据的总数大于其低水位标记时, IO复用系统调用将通知应用程序可以从对应的socket上读取数据
SO_SNDLOWAT 发送的高水位标记 默认为1字节, 当TCP发送缓冲区中空闲空间大于低水位标记的时候可以写入数据
SO_LINGER  
struct linger
{
    int l_onoff /* 开启非0, 关闭为0*/
    int l_linger; /* 滞留时间*/
    /*
    * 当onoff为0的时候此项不起作用, close调用默认行为关闭socket
    * 当onoff不为0 且linger为0, close将立即返回, TCP将丢弃发送缓冲区的残留数据, 同时发送一个复位报文段
    * 当onoff不为0 且linger大于0 . 当socket阻塞的时候close将会等待TCP模块发送完残留数据并得到确认后关 
    * 闭, 如果是处于非阻塞则立即关闭
    */
};

 

网络信息API

#include <netdb.h>
// 通过主机名查找ip
struct hostent* gethostbyname(const char* name);

// 通过ip获取主机完整信息 
// type为IP地址类型 AF_INET和AF_INET6
struct hostent* gethostbyaddr(const void* addr, size_t len, int type);

struct hostent
{
  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.  */
}

int main(int argc, char* argv[])
{
    if (argc != 2)
    {
        printf("非法输入\n");
        exit(0);
    }
    char* name = argv[1];

    struct hostent *hostptr{};

    hostptr = gethostbyname(name);
    if (hostptr == nullptr)
    {
        printf("输入存在错误 或无法获取\n");
        exit(0);
    }

    printf("Official name of hostptr: %s\n", hostptr->h_name);

    char **pptr;
    char inet_addr[INET_ADDRSTRLEN];

    printf("Alias list:\n");
    for (pptr = hostptr->h_aliases; *pptr != nullptr; ++pptr)
    {
        printf("\t%s\n", *pptr);
    }

    switch (hostptr->h_addrtype)
    {
        case AF_INET:
        {
            printf("List of addresses from name server:\n");
            for (pptr = hostptr->h_addr_list; *pptr != nullptr; ++pptr)
            {
                printf("\t%s\n",
                        inet_ntop(hostptr->h_addrtype, *pptr, inet_addr, sizeof(inet_addr)));
            }
            break;
        }
        default:
        {
            printf("unknow address type\n");
            exit(0);
        }
    }
    return 0;
}

/*
./run baidu.com
Official name of hostptr: baidu.com
Alias list:
List of addresses from name server:
    39.156.69.79
    220.181.38.148
*/

 

标签:struct,int,编程,sockfd,API,Linux,msg,address,name
来源: https://www.cnblogs.com/mjhjl/p/16229087.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有