内容目录
第八章
IP地址和域名之间的转换
利用域名获取IP地址
#include <netdb.h>
struct hostent * gethostbyname(const char * hostname);
hostent结构体定义如下:
struct hostent
{
char * h_name;
char ** h_aliases;
int h_addrtype;
int h_length;
char ** h_addr_list;
}
各字段定义如下:
- h_name
该变量中存有官方域名。官方域名代表某一主页,但实际上,一些著名公司的域名并未用官方域名注册。 - h_aliases
可以通过多个域名访问同一主页。同一ip可以绑定多个域名,因此,除官方域名外海可指定其他域名。这些信息可以通过h_aliases获得。 - h_addrtype
gethostbyname支持IPv4和IPv6, 该变量保存的是地址族信息,AF_INET。 - h_length
保存IP地址长度。ipv4为4,ipv6为6。 - h_addr_list
通过此变量以整数形式保存域名对应的IP地址。
利用IP地址获取域名
#include <netdb.h>
struct hostent * gethostbyaddr(const char * addr, socklen_t len, int family);
- addr
含有地址信息的in_addr结构体指针。 - len
向第一个参数传递的地址信息的字节数。 - family
传递地址族信息。
套接字的多种可选项
套接字可选项和I/O缓冲大小
套接字多种可选项(部分)
协议层 | 选项名 | 描述 |
---|---|---|
SOL_SOCKET | SO_SNDBUF | 布吉岛 |
SO_RCVBUF | 布吉岛 | |
SO_REUSEADDR | 布吉岛 | |
SO_KEEPALIVE | 布吉岛 | |
SO_BROADCAST | 布吉岛 | |
SO_DONTROUTE | 布吉岛 | |
SO_OOBINLINE | 布吉岛 | |
SO_ERROR | 不可设置 | |
SO_TYPE | 不可设置 | |
SO_SNDBUF | IP_TOS | 布吉岛 |
IP_TTL | 布吉岛 | |
IP_MULTICAST_TTL | 布吉岛 | |
IP_MULTICAST_LLOOP | 布吉岛 | |
IP_MULTICAST_IF | 布吉岛 | |
IPPROTO_TCP | TCP_KEEPALIVE | 布吉岛 |
TCP_NODELAY | 布吉岛 | |
TCP_MAXSEG | 布吉岛 |
getsokopt & setsockopt
可以对表中的所有可选项进行读取和设置。
#include <sys/socket.h>
int getsockopt(int sock, int level, int optname, void *optval, socklen_t *optlen);
- sock
文件描述符 - level
要查看的可选项的协议层 - optname
要查看的可选项名 - optval
保存查看结果的缓冲地址值 - optlen
向第四个参数optval传递的缓冲大小。该变量保存通过第四个参数返回的可选项信息的字节数。
#include <sys/socket.h>
int setsockopt(int sock, int level, int optname, const void *optval, socklen_t *optlen);
- sock
文件描述符 - level
要查看的可选项的协议层 - optname
要查看的可选项名 - optval
保存要更改的选项的缓冲地址值 - optlen
向第四个参数optval传递的缓冲大小。该变量保存通过第四个参数返回的可选项信息的字节数。
// sock_type.cpp
#include <stdio.h>
#include <unistd.h>
#include <cstdlib>
#include <sys/socket.h>
void error_handling(const char * message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
int main(int argc, char *argv[])
{
int tcp_sock, udp_sock;
int sock_type;
socklen_t optlen;
int state;
optlen = sizeof(sock_type);
tcp_sock = socket(PF_INET, SOCK_STREAM, 0);
udp_sock = socket(PF_INET, SOCK_DGRAM, 0);
printf("SOCK_STREAM: %d \n", SOCK_STREAM);
printf("SOCK_DGRAM: %d \n", SOCK_DGRAM);
state = getsockopt(tcp_sock, SOL_SOCKET, SO_TYPE, (void *)&sock_type, &optlen);
if(state)
{
error_handling("eoor!");
}
printf("socket type one: %d \n", sock_type);
state = getsockopt(udp_sock, SOL_SOCKET, SO_TYPE, (void *)&sock_type, &optlen);
if(state)
{
error_handling("eoor!");
}
printf("socket type two: %d \n", sock_type);
return 0;
}
SO_SNDBUF & SO_RCVBUF
SO_SNDBUF是输出缓冲大小相关可选项,SO_RCVBUF是输入缓冲大小相关可选项。