把ping函数改到另一个文件里面

wwwxxb40000 2009-11-26 12:48:35

// pingcx.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <stdio.h>

#include <stdlib.h>

#include <winsock.h>




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

#define ICMP_ECHOREPLY 0 //ICMP回应答复

#define ICMP_ECHOREQ 8 //ICMP回应请求

#define REQ_DATASIZE 32 //请求数据报大小







//定义IP首部格式

typedef struct _IPHeader

{

u_char VIHL; //版本和首部长度

u_char ToS; //服务类型

u_short TotalLen; //总长度

u_short ID; //标识号

u_short Frag_Flags; //段偏移量

u_char TTL; //生存时间

u_char Protocol; //协议

u_short Checksum; //首部校验和

struct in_addr SrcIP; //源IP地址

struct in_addr DestIP; //目的地址

}IPHDR, *PIPHDR;




//定义ICMP首部格式

typedef struct _ICMPHeader

{

u_char Type; //类型

u_char Code; //代码

u_short Checksum; //首部校验和

u_short ID; //标识

u_short Seq; //序列号

char Data; //数据

}ICMPHDR, *PICMPHDR;




//定义ICMP回应请求

typedef struct _ECHOREQUEST

{

ICMPHDR icmpHdr;

DWORD dwTime;

char cData[REQ_DATASIZE];

}ECHOREQUEST, *PECHOREQUEST;







//定义ICMP回应答复

typedef struct _ECHOREPLY

{

IPHDR ipHdr;

ECHOREQUEST echoRequest;

char cFiller[256];

}ECHOREPLY, *PECHOREPLY;




//计算校验和

u_short checksum(u_short *buffer, int len)

{

register int nleft = len;

register u_short *w = buffer;

register u_short answer;

register int sum = 0;




//使用32位累加器,进行16位的反馈计算

while ( nleft > 1 )

{

sum += *w++;

nleft -= 2;

}




//补全奇数位

if ( nleft == 1 )

{

u_short u = 0;

*(u_char *)(&u) = *(u_char*)w;

sum += u;

}




//将反馈的16位从高位移到低位

sum = (sum >> 16) + (sum & 0xffff);

sum += (sum >> 16);

answer = ~sum;

return (answer);

}







//发送回应请求函数

int SendEchoRequest(SOCKET s, struct sockaddr_in *lpstToAddr)

{

static ECHOREQUEST echoReq;

static nId = 1;

static nSeq = 1;

int nRet;

//填充回应请求消息

echoReq.icmpHdr.Type = ICMP_ECHOREQ;

echoReq.icmpHdr.Code = 0;

echoReq.icmpHdr.Checksum = 0;

echoReq.icmpHdr.ID = nId++;

echoReq.icmpHdr.Seq = nSeq++;

//填充要发送的数据

for (nRet = 0; nRet < REQ_DATASIZE; nRet++)

{

echoReq.cData[nRet] = '1' + nRet;

}

//存储发送的时间

echoReq.dwTime = GetTickCount();

//计算回应请求的校验和

echoReq.icmpHdr.Checksum = checksum((u_short*)&echoReq, sizeof(ECHOREQUEST));




//发送回应请求

nRet = sendto(s,

(LPSTR)&echoReq,

sizeof(ECHOREQUEST),

0,

(struct sockaddr*)lpstToAddr,

sizeof(SOCKADDR_IN));




if (nRet == SOCKET_ERROR)

{

printf("send to() error:%d\n", WSAGetLastError());

}




return (nRet);

}







//接收应答回复并进行解析

DWORD RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL)

{

ECHOREPLY echoReply;

int nRet;

int nAddrLen = sizeof(struct sockaddr_in);




//接收应答回复

nRet = recvfrom(s,

(LPSTR)&echoReply,

sizeof(ECHOREPLY),

0,

(LPSOCKADDR)lpsaFrom,

&nAddrLen);

//检验接收结果

if (nRet == SOCKET_ERROR)

{

printf("recvfrom() error:%d\n",WSAGetLastError());

}

//记录返回的TTL

*pTTL = echoReply.ipHdr.TTL;




//返回应答时间

return(echoReply.echoRequest.dwTime);

}







//等待回应答复,使用select模型

int WaitForEchoReply(SOCKET s)

{

struct timeval timeout;

fd_set readfds;

readfds.fd_count = 1;

readfds.fd_array[0] = s;

timeout.tv_sec = 5;

timeout.tv_usec = 0;

return(select(1, &readfds, NULL, NULL, &timeout));

}







//PING功能实现

void Ping(char *pstrHost)

{

SOCKET rawSocket;

LPHOSTENT lpHost;

struct sockaddr_in destIP;

struct sockaddr_in srcIP;

DWORD dwTimeSent;

DWORD dwElapsed;

u_char cTTL;

int nLoop;

int nRet;




//创建原始套接字,ICMP类型

rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

if (rawSocket == SOCKET_ERROR)

{

printf("socket() error:%d\n", WSAGetLastError());

return;

}




//检测目标主机

lpHost = gethostbyname(pstrHost);

if (lpHost == NULL)

{

printf("Host not found:%s\n", pstrHost);

return;

}




//设置目标机地址

destIP.sin_addr.s_addr = *((u_long FAR*)(lpHost->h_addr)); //设置目标IP

destIP.sin_family = AF_INET;

destIP.sin_port = 0;




//提示开始进行PING

printf("\nPinging %s with %d bytes of data:\n",

inet_ntoa(destIP.sin_addr),

REQ_DATASIZE);




//发起多次PING测试

int max=0;
int min=9000;
int sum=0;
int count=0;
int avag=0;


for (nLoop=0; nLoop<4; nLoop++)

{

//发送ICMP回应请求

SendEchoRequest(rawSocket, &destIP);

//等待回复的数据

nRet = WaitForEchoReply(rawSocket);

if (nRet == SOCKET_ERROR)

{

printf("select() error:%d\n", WSAGetLastError());

break;

}




if (!nRet)

{

printf("\nRequest time out");

break;

}




//接收回复

dwTimeSent = RecvEchoReply(rawSocket, &srcIP, &cTTL);




//计算花费的时间

dwElapsed = GetTickCount() - dwTimeSent;

if (dwElapsed>max)
{
max=dwElapsed;
}

if (dwElapsed<min)
{
min=dwElapsed;
}

sum=sum+dwElapsed;

count=count+1;

printf("\nReply from %s: bytes = %d time = %ldms TTL = %d",

inet_ntoa(srcIP.sin_addr),

REQ_DATASIZE,

dwElapsed,

cTTL);

}

printf("\nPing statistics for ");


printf("Packets: Sent =4 , Received=%d ,loss=%d\n",count,4-count);

printf("Approximate round trip times in milli-seconds:\n");

if (count>0)
avag=sum/count;

printf("Maximum =%d ms ; Minimum = %d ms ; Average= % d ms ",max,min,avag);

printf("\n");


nRet = closesocket(rawSocket);

if (nRet == SOCKET_ERROR)

{

printf("closesocket() error:%d\n", WSAGetLastError());

}


}





//主程序

void main(int argc, char **argv)

{

WSADATA wsd;




//检测输入的参数

if (argc != 2)

{

printf("\nUsage:ping hostname\n");

//return;

}




//初始化Winsock

if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)

{

printf("加载 Winsock 失败!\n");

}




//开始PING
argv[1]="www.sohu.com";
argv[1]="221.236.12.135";
//argv[1]="123.123.122.135";

Ping(argv[1]);

//程序释放 Winsock 资源

WSACleanup();




}

想把这个程序中间的ping函数放到另一个文件里面,

也就是把程序分多个文件,该如何改呀?那位高手帮帮忙?


...全文
110 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
fandh 2009-11-26
  • 打赏
  • 举报
回复
拷贝、粘帖,创建新文件后,要将这个新文件加到工程中!
bragi523 2009-11-26
  • 打赏
  • 举报
回复
新建个函数
把里面代码拷贝过去
调用那个函数
wzdshh 2009-11-26
  • 打赏
  • 举报
回复
可以把main函数改个函数名如ping(),把这些代码复制到一个头文件里,在你要调用ping的代码里#include'ping.h' 然后在现在这个文件里就可以直接调用ping这个函数了
wzdshh 2009-11-26
  • 打赏
  • 举报
回复
可以把main函数改个函数名如ping(),把这些代码复制到一个头文件里,在你要调用ping的代码里#include'ping.h' 然后在现在这个文件里就可以直接调用ping这个函数了
西山小月 2009-11-26
  • 打赏
  • 举报
回复
考过去
wwwxxb40000 2009-11-26
  • 打赏
  • 举报
回复

楼上两位,能不能给我具体的文件示例呀?
MoXiaoRab 2009-11-26
  • 打赏
  • 举报
回复
将Main的名字改成其他的即可,然后代码复制过去

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧