2020/2/20 端口绑定和域名解析

端口绑定和域名解析

TCP服务器的同一个端口不能够启动、绑定两次;但UDP服务器可以,但客户端连接上以后,信息只能发送给最新绑定的那个服务器端口,相当于端口被重新绑定了。

 

域名解析函数

struct hostent{
    char *h_name;        //主机名
    char **h_aliases;    //别名
    int h_addrtype;      //协议类型
    int h_length;        //网络地址大小
    char **h_addr_list;  //指向网络地址的指针
};

#include <netdb.h>
struct hostent *gethostent(void);
struct hostent* gethostbyname(const char *hostname);
void sethostent(int stayopen);
void endhostent(void);//有get就有end,用于释放内存

查看/etc/hosts文件可以知道本机的IP和域名


利用gethostbyname解析域名

源代码

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <arpa/inet.h>

void out_addr(struct hostent *h)
{
	printf("hostname: %s\n", h->h_name);
	printf("addrtype: %s\n", h->h_addrtype == AF_INET ? "IPV4":"IPV6");
	char ip[16];
	memset(ip, 0, sizeof(ip));
	inet_ntop(h->h_addrtype, h->h_addr_list[0], ip, sizeof(ip));
	
	int i = 0;
	while(h->h_aliases[i] != NULL){
		printf("aliases: %s\n", h->h_aliases[i]);
		i++;
	}
}

int main(int argc, char *argv[])
{
	if(argc < 2){
		printf("usage: %s host\n", argv[0]);//输入域名,可以是主机名也可以是别名
		exit(1);
	}
 	struct hostent *h;
	
	h = gethostbyname(argv[1]);
	if(h != NULL){
		out_addr(h);
	}	
	else{
		printf("no %s exist\n", argv[1]);
	}
	return 0;
}

利用gethostent解析域名

 

源代码

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <arpa/inet.h>

void out_addr(struct hostent *h)
{
	printf("hostname: %s\n", h->h_name);
	printf("addrtype: %s\n", h->h_addrtype == AF_INET ? "IPV4":"IPV6");
	char ip[16];
	memset(ip, 0, sizeof(ip));
	inet_ntop(h->h_addrtype, h->h_addr_list[0], ip, sizeof(ip));
	
	int i = 0;
	while(h->h_aliases[i] != NULL){
		printf("aliases: %s\n", h->h_aliases[i]);
		i++;
	}
}

int main(int argc, char *argv[])
{
	if(argc < 2){
		fprintf(stderr, "usage: %s host\n", argv[0]);//fprintf输出到指定位置,stderr就是指屏幕
		exit(1);
	}
 	struct hostent *h;
	while((h = gethostent()) != NULL){//通过遍历,获取每一组
		if(!strcmp(argv[1], h->h_name)){//查看每一组的主机名是否与输入的一致
			out_addr(h);
			exit(0);
		}
		else{
				int i = 0;
				while(h->h_aliases[i] != NULL){//主机名没有,再遍历别名
					if(!strcmp(argv[1], h->h_aliases[i])){
						out_addr(h);
						exit(0);
					}
					i++;
				}
			}
	}
	endhostent();
	printf("no %s exist\n", argv[1]);

	return 0;
}

运行结果


把域名解析函数运用到UDP协议的客户端中

修改time_udp_client.c,把从argv[1]直接获取ip地址,改为从命令行中获得域名,然后利用域名解析函数获取IP地址

域名解析函数

int is_host(struct hostent *host, char *name)
{
	if(!strcmp(host->h_name, name)) return 1;
		
	int i = 0;
	while(host->h_aliases[i] != NULL)
	{
		if(!strcmp(host->h_aliases[i], name)) return 1;
		i++;
	}
	return 0;
}

unsigned int get_ip_by_name(char *name)
{
	unsigned int ip = 0;
	struct hostent *host;
	while((host = gethostent()) != NULL){
		if(is_host(host, name)){
			memcpy(&ip, host->h_addr_list[0], 4);//ipv4 32bit = 4 byte
			break;
		}
	}
	endhostent();
	return ip;
}

在主函数中调用

//inet_pton(AF_INET, argv[1], &serveraddr.sin_addr.s_addr);//ip 这是先前的代码

//改用从命令行中获得域名,然后利用域名解析函数获取IP地址
unsigned int ip = get_ip_by_name(argv[1]);//可以直接解析成网络字节序的ip
if(ip != 0){
	serveraddr.sin_addr.s_addr = ip;
}
else{
		inet_pton(AF_INET, argv[1], &serveraddr.sin_addr.s_addr);
    //如果不需要域名解析,直接把输入的主机字节序转换为网络字节序
}

运行结果


总结

https://www.cnblogs.com/maybe2030/p/4781555.html#_label3【计算机网络基础知识总结】

 

1. 网络:WAN广域网、MAN城域网、LAN 局域网

2. TCP/IP协议:OSI七层协议、TCP/IP五层/四层协议:物理层-数据链路层-网络层-传输层-【会话层-表示层-应用层】

物理层:RJ45、CLOCK、IEEE802.3    (中继器,集线器,网关)

数据链路:PPP、FR、HDLC、VLAN、MAC  (网桥,交换机)

网络层:IP、ICMP、ARP、RARP、OSPF、IPX、RIP、IGRP、 (路由器)

传输层:TCP、UDP、SPX

会话层:NFS、SQL、NETBIOS、RPC

表示层:JPEG、MPEG、ASCII

应用层:FTP、DNS、Telnet、SMTP、HTTP、WWW、NFS

3. TCP/UDP协议网络基础编程

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值