实验一 Winsock编程接口实验

网络程序设计实验报告实验名称:winsock 编程接口实验__________ 实验类型:验证型实验______ ___ 指导教师:贾浩 ________________

网络程序设计

实验报告

实验名称:winsock 编程接口实验__________ 实验类型:验证型实验______ ___ 指导教师:贾浩 ___________________

专业班级: 信安0904_________________ 姓 名:_谌军________________________ 学 号:_20092036___________________ 电子邮件:_448149700@qq.com__________ 实验地点:_东六a 座4--17______________

实 验 日 期: 2012 年 3 月 11 日

实验成绩:__________________________

,

二、实验设计

(一)实验要求如下:

1、编写程序能同时实现对多个域名的解析。比如在控制台输入:getip www.163.com www.swust.edu.cn , 能输出www.163.com 和 www.swust.edu.cn 对应的IP 地址列表。

2、编写程序获取并输出本地主机的所有适配器的IP 地址,子网掩码,默认网关,MAC 地址。

(二)设计:

1、 要实现对域名的解析,最主要是对gethostbyname ()函数的理解和应用。

函数原型为:

struct hostent *gethostbyname(const char *name);

name 为指向主机名的指针,它一般由函数gethostname 返回。

函数返回对应于给定主机名的包含主机名字和地址信息的hostent 结构指针,该结构格式如下:

struct hostent{

char FAR* h_name;

char FAR* FAR* h_aliases;

short h_addrtype;

short h_length;

char FAR* FAR* h_addr_list;

};

由于已知主机名(即输入的域名),所以只要调用该函数就能得到ip 地址列表。 根据分析可得出程序流程图如下:

,

2、要得到本地主机的所有适配器的IP 地址,子网掩码,默认网关,MAC 地址等信息,主要是对GetAdaptersInfo()函数的理解和应用。

该函数可以获取本地主机的所有适配器信息,并保存在pAdapterInfo 所指向的链表中。 函数原型为:

DWORD GetAdaptersInfo(

PIP_ADAPTER_INFO pAdapterInfo, // buffer to receive data

PULONG pOutBufLen // size of data returned

);

IP_ADAPTER_INFO的定义如下:

typedef struct _IP_ADAPTER_INFO {

struct _IP_ADAPTER_INFO* Next;

DWORD ComboIndex;

char AdapterName[MAX_ADAPTER_NAME_LENGTH 4];

char Description[MAX_ADAPTER_DESCRIPTION_LENGTH 4];

UINT AddressLength;

BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];

DWORD Index;

,

UINT Type;

UINT DhcpEnabled;

PIP_ADDR_STRING CurrentIpAddress;

IP_ADDR_STRING IpAddressList;

IP_ADDR_STRING GatewayList;

IP_ADDR_STRING DhcpServer;

BOOL HaveWins;

IP_ADDR_STRING PrimaryWinsServer;

IP_ADDR_STRING SecondaryWinsServer;

time_t LeaseObtained;

time_t LeaseExpires;

} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;

通过调用该函数就可以得到所有适配器信息。

流程图如下:

三、实验过程(包含实验结果)

1. 实验步骤如下:

(1)建立一个C 程序工程,并建立同名的C 文件;

(2)将教材上获取本机IP 等信息代码输入;

(3)将::gethostname(szHost, 256)改为cout<<”请输入主机名”<>szHost;

(4)为主函数中的所有代码加上while 循环,从而实验多次域名的输入。

(5)编译,调试,运行程序,检验程序运行结果。

(6)思考,分析实验结果,编写实验报告。

实验编译及链接错误:无。

解决方案:无。

,

实验结果:如下截图结果

2. 实验步骤如下:

(1)建立名为LocalHostInfo 的一个C 程序工程,并建立同名的文件;

(2)将教材上获取本机ip 地址,子网掩码,网关ip 和本机MAC 地址代码录入;

(3)编译,调试,运行程序,检验程序运行结果。

(4)思考,分析实验结果,编写实验报告。

实验编译及链接错误:无。

解决方案:无。

实验结果:如下截图为运行程序后的结果:

四、讨论与分析

1) Winsock 初始化的作用是什么?

答:作用是为了式程序能够使用一些底层的API 函数,用来完成功能

2) 给出GetAdaptersInfo ()函数的正确使用方法

DWORD GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, //指向一个缓冲区,用来取得IP_ADAPTER_INFO 结构的列表

PULONG pOutBufLen //用来指定上面的缓冲区的大小,如果大小不够,此参数返回所需大小

)//函数调用成功返回ERROR_SUCCESS

3) 域名解析时出现域名对应多个IP ,请解释原因。

因为一台主机上可能会对应多个IP 地址如(笔记本上的无线网卡上对应了一个IP 地址而在有线上也对应了一个IP 地址)

五、实验者自评(从实验设计、实验过程、对实验知识点的理解上给出客观公正的自我评价)

这次实验使我对书本上的知识有了更深的理解,对于这些重要的API 函数的调用也有了一个更加明确的理解,除此之外,我还对套接字、端口、IP 地址之间的关系有了初步的理解, 在以后的实验中,我会更加对书上的代码进行研究,充分的理解其中的关键要素!

,

六、附录:关键代码(给出适当注释,可读性高) #include

#include

#pragma comment(lib,"WS2_32")

class CInitSock

{

public:

CInitSock(BYTE minorVer = 2, BYTE majorVer = 2)

{

// 初始化Winsock

WSADATA wsaData;

WORD sockVersion = MAKEWORD(minorVer, majorVer); if(::WSAStartup(sockVersion, &wsaData) != 0)

{

exit(0);//初始化失败,退出程序

}

}

~CInitSock()

{

::WSACleanup();//释放Winsock 资源

}

};

int main(int argc,char **argv)

{

CInitSock initSock;

char szHost[256];

while(printf("输入域名:"))

{

// 通过域名得到地址信息

scanf("s",&szHost);

if(szHost==0)

{

break;

}

hostent *pHost = ::gethostbyname(szHost);

// 打印出所有IP 地址

in_addr addr;

for(int i = 0; ; i )

{

char *p = pHost->h_addr_list[i];

if(p == NULL) break;

,

memcpy(&addr.S_un.S_addr, p, pHost->h_length); char *szIp = ::inet_ntoa(addr);

printf("IP地址:sn", szIp);

}

}

printf("n");

return 0;

}

#include

#include

#include "Iphlpapi.h"

#pragma comment(lib, "Iphlpapi.lib")

#pragma comment(lib, "WS2_32.lib")

/////////////////////////////////////////

// 全局数据

u_char g_ucLocalMac[6]; // 本地MAC 地址

DWORD g_dwGatewayIP; // 网关IP 地址

////////////////////

DWORD g_dwGatewayIP1;

DWORD g_dwLocalIP; // 本地IP 地址

DWORD g_dwMask; // 子网掩码

char *szAdapterName;

char *szAdapterDescription;

BOOL GetGlobalData()

{

PIP_ADAPTER_INFO pAdapterInfo = NULL;

ULONG ulLen = 0;

// 为适配器结构申请内存

::GetAdaptersInfo(pAdapterInfo,&ulLen);

pAdapterInfo = (PIP_ADAPTER_INFO)::GlobalAlloc(GPTR, ulLen);

// 取得本地适配器结构信息

if(::GetAdaptersInfo(pAdapterInfo,&ulLen) == ERROR_SUCCESS) {

if(pAdapterInfo != NULL)

{

memcpy(g_ucLocalMac, pAdapterInfo->Address, 6); szAdapterName=pAdapterInfo->AdapterName;

,

szAdapterDescription=pAdapterInfo->Description;

g_dwGatewayIP = ::inet_addr(pAdapterInfo->GatewayList.IpAddress.String); g_dwLocalIP = ::inet_addr(pAdapterInfo->IpAddressList.IpAddress.String); g_dwMask = ::inet_addr(pAdapterInfo->IpAddressList.IpMask.String);

g_dwGatewayIP1=::inet_addr(pAdapterInfo->Next->IpAddressList.IpAddress.String); }

}

printf(" n -------------------- 本地主机信息 -----------------------nn");

in_addr in;

in.S_un.S_addr = g_dwLocalIP;

in_addr in1;

in1.S_un .S_addr =g_dwGatewayIP1;

printf(" IP Address : s n", ::inet_ntoa(in));

in.S_un.S_addr = g_dwMask;

printf(" Subnet Mask : s n", ::inet_ntoa(in));

in.S_un.S_addr = g_dwGatewayIP;

printf(" Default Gateway : s n", ::inet_ntoa(in));

u_char *p = g_ucLocalMac;

标签: