第一次网络编程实践——从调试Dev C++到查询主机名与ip地址

这是我的第一次网络编程实践,是在疫情期间的家中进行。相比于在学校,在家的缺点就是有问题无法详细的向老师和同学求助,在同学们的帮助下,借助网络查询,成功完成了本次实验。想来,可能会有人与我有相同的困难,因此,我将详细介绍从调试Dev C++到实现编写的每一步过程。

调试DEV C++

起初,我是想用VS的,但是之前没接触过VS,并且在运行中出现各种奇奇怪怪的错误,于是改为了用DEV C++,这款软件也可以实现网络编程,而且体积更小,现将调试方法介绍如下。
先新建一个project(工程),点击“File”,下拉菜单点击“New”,单击“project”
选择console application选项
在这里插入图片描述
对左侧project右键单击,打开“project options”
在Parameters(参数)一栏,打开右下角的Add
在这里插入图片描述
在里面通过文件目录找到libws2_32.a添加进去
详细目录是:
Dev-Cpp——MinGW32——lib,lib文件夹中就是各种动态库了
在这里插入图片描述
添加完毕后,再打开主菜单的Tools中的compiler options(编译选项),在General选项卡中,添加“-lwsock32”,点击确定,即可完成编译

在这里插入图片描述

编程过程

初始化动态链接库

一开始做实验时,我是懵圈状态,完全不知道从哪里下手,也不知道如何去做。再又看了一遍课程视频后才有了大概的思路。
我明白了一个(伪)真理——编程不决,先初始化链接库
初始化动态链接库是要在调用套接字(socket)函数之前的,所以先初始化一般是没有问题的。由于网络比较复杂,所以要时刻注意函数返回值,若返回错误值,要及时退出程序,并有相应警告或者提示

WSAData data;
	if (WSAStartup(MAKEWORD(1, 1), &data) != 0)//初始化winsocket的动态链接库,并且进行检测查询,看是否存在启动错误 
	{
		cout << "初始化错误endl";
		return 0;//一旦有错直接返回结果,退出程序  
	}
获取主机名

获取主机名我们要用到gethostname函数,我们先看一下函数调用值和返回值。摘自百度百科
在这里插入图片描述
这个函数还是比较简单的,我们只需要定义一个char数组,然后把数组名以及长度放进去即可进行调用

char zhuji[255];
	if (gethostname(zhuji, sizeof(zhuji)) == SOCKET_ERROR)//利用gethostname查询主机名,正确会返回0,错误会返回SOCKET_ERROR 
	{
		cout << "无法获取主机名" << endl;
		return 0;
	}
	else
	{
		cout << "本机名为:" << zhuji << endl;
	}

这样就可以返回主机名

查询主机ip地址

gethostbyname函数即可实现查询ip地址
在这里插入图片描述
gethostbyname返回值是结构体hostent的指针,参数只需要一个char数组的名字即可。因此,在调用该函数之前, 我们需要先定义一个hostent结构的指针。
同时要注意,ip地址是存放在h_addr_list中,该变量存放了多个ip地址,我们要用for循环将其逐个输出。
在输出时,为了美观,方便观看,我们用inet_ntoa函数将其转化为点分十进制IP地址

struct hostent *p = gethostbyname(zhuji);//hostent是一种数据结构,定义该数据结构的指针,并将函数返回值赋在该指针上 
	if (p == 0)//gethostbyname用于查询该主机中的所有ip 
	{
		cout << "查询不到主机名和IP" << endl;
		return 0;
	}
	else
	{
		//本机IP:利用循环,输出本机所有IP  
		for (int i = 0; p->h_addr_list[i] != 0; i++)//h_addr_list是存放ip地址的指针,通过它可以一个个地调出ip值 
		{
			struct in_addr in;//in_addr可表示一个32位的ipv4地址 
			memcpy(&in, p->h_addr_list[i], sizeof(struct in_addr));//复制函数,将h_addr_list所指向的地址复制到in的值中 
			cout << "第" << i + 1 << "块网卡的IP为:" << inet_ntoa(in) << endl;//利用inet_ntoa()函数,转化为点分十进制ip地址 
		}

	}
查询域名对应的ip

这个就比较简单了,把上面的代码一改就可以了,同样是用gethostbyname函数。

char yuming[255];
	cout<<endl<<"请输入要查询的域名:";
	cin>>yuming; 
	struct hostent *q=gethostbyname(yuming);//与上面相同,根据域名查ip 
	if(!q)
	{
		cout<<"域名错误!"<<endl;
		return 0; 
	}
	else
	{
		for(int i=0;q->h_addr_list[i];i++)//把上面的代码稍微一改就可以了 
		{
			struct in_addr inad;
			memcpy(&inad,q->h_addr_list[i],sizeof(struct in_addr));
			cout<<"IP 地址是:"<<i+1<<inet_ntoa(inad)<<endl; 
		}
	}
最后不要忘记关闭动态链接库
整体代码
#include <iostream>
#pragma comment(lib, "WS2_32")
#include <iostream>
#include <Winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#include<bits/stdc++.h>//我习惯性加入万能头文件,也是为了保险起见 
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char** argv) 
{
	WSAData data;
	if (WSAStartup(MAKEWORD(1, 1), &data) != 0)//初始化winsocket的动态链接库,并且进行检测查询,看是否存在启动错误 
	{
		cout << "初始化错误endl";
		return 0;//一旦有错直接返回结果,退出程序  
	}

	char zhuji[255];
	if (gethostname(zhuji, sizeof(zhuji)) == SOCKET_ERROR)//利用gethostname查询主机名,正确会返回0,错误会返回SOCKET_ERROR 
	{
		cout << "无法获取主机名" << endl;
		return 0;
	}
	else
	{
		cout << "本机名为:" << zhuji << endl;
	}

	struct hostent *p = gethostbyname(zhuji);//hostent是一种数据结构,定义该数据结构的指针,并将函数返回值赋在该指针上 
	if (p == 0)//gethostbyname用于查询该主机中的所有ip 
	{
		cout << "查询不到主机名和IP" << endl;
		return 0;
	}
	else
	{
		//本机IP:利用循环,输出本机所有IP  
		for (int i = 0; p->h_addr_list[i] != 0; i++)//h_addr_list是存放ip地址的指针,通过它可以一个个地调出ip值 
		{
			struct in_addr in;//in_addr可表示一个32位的ipv4地址 
			memcpy(&in, p->h_addr_list[i], sizeof(struct in_addr));//复制函数,将h_addr_list所指向的地址复制到in的值中 
			cout << "第" << i + 1 << "块网卡的IP为:" << inet_ntoa(in) << endl;//利用inet_ntoa()函数,转化为点分十进制ip地址 
		}

	}
	char yuming[255];
	cout<<endl<<"请输入要查询的域名:";
	cin>>yuming; 
	struct hostent *q=gethostbyname(yuming);//与上面相同,根据域名查ip 
	if(!q)
	{
		cout<<"域名错误!"<<endl;
		return 0; 
	}
	else
	{
		for(int i=0;q->h_addr_list[i];i++)//把上面的代码稍微一改就可以了 
		{
			struct in_addr inad;
			memcpy(&inad,q->h_addr_list[i],sizeof(struct in_addr));
			cout<<"IP 地址是:"<<i+1<<inet_ntoa(inad)<<endl; 
		}
	}
	WSACleanup();//最后不要忘记关闭动态库 
	return 0;
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值