linux高性能服务器编程---第五章Linux网络编程基础API (3)
作者:互联网
通用读写函数
#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