把ping函数改到另一个文件里面
// 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函数放到另一个文件里面,
也就是把程序分多个文件,该如何改呀?那位高手帮帮忙?