基于原始套接字的编程

// ping.cpp : Defines the entry point for the console application.
//服务器端

#include "stdafx.h"

#include <winsock2.h>
#include "ping.h"
#pragma comment (lib,"ws2_32.lib")

u_short in_cksum(u_short *addr, int len)
{
    register int nleft = len;
    register u_short *w = addr;
    register u_short answer;
    register int sum = 0;
    while( nleft > 1 )  {
        sum += *w++;
        nleft -= 2;
    }

    if( nleft == 1 ) {
        u_short    u = 0;

        *(u_char *)(&u) = *(u_char *)w ;
        sum += u;
    }

    
    sum = (sum >> 16) + (sum & 0xffff);    /* add hi 16 to low 16 */
    sum += (sum >> 16);            /* add carry */
    answer = ~sum;                /* truncate to 16 bits */
    return (answer);
}
int main(int argc, char* argv[])
{
    WSADATA data;
    int r=WSAStartup(MAKEWORD(2,2),&data);
    char name[100]={0};
    gethostname(name,100);   
    printf("本机名%s\n",name);
    SOCKET s=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
    if(s==-1)
    {
        printf("创建套接字失败!");
        WSACleanup();
        return 0;
    }
    LPHOSTENT lpHost;
    struct    sockaddr_in saDest;
    struct    sockaddr_in saSrc;
    DWORD      dwTimeSent;
    DWORD      dwElapsed;

    HOSTENT* local=gethostbyname(argv[1]);
    saDest.sin_family=AF_INET;
    saDest.sin_port=0;
    saDest.sin_addr.S_un.S_addr=*(unsigned long *)local->h_addr_list[0];


    //    =inet_addr("127.0.0.1");//*(unsigned long *)local->h_addr_list[0];

    saSrc.sin_addr.S_un.S_addr=inet_addr("172.19.1.42");
    saSrc.sin_family=AF_INET;
    saSrc.sin_port=0;

    r=bind(s,(const sockaddr *)&saSrc,sizeof(saSrc));

    ECHOREQUEST req;
    ECHOREPLY rep;
    for(int i=0;i<REQ_DATASIZE;i++)
    req.cData[i]=i;

    req.icmpHdr.Type=8;
    req.icmpHdr.Code=0;
    req.icmpHdr.ID=GetCurrentProcessId();
    for(i=0;i<3;i++)
    {
        req.icmpHdr.Seq=i+1;
        req.icmpHdr.Checksum=0;
        req.dwTime=GetTickCount();
        
        req.icmpHdr.Checksum=in_cksum((u_short *)&req,sizeof(req));
        r=sendto(s,(const char *)&req,sizeof(req),0,(const sockaddr *)&saDest,sizeof(saDest));
        
        
        memset((void *)&rep,0,sizeof(rep));
        struct sockaddr_in from;
        int fromlen=sizeof(from);
        r=recvfrom(s,(char *)&rep,sizeof(rep),0,(sockaddr *)&from,&fromlen);
        if(r>0)
        {
            char *srcip=inet_ntoa(*(in_addr *)&rep.ipHdr.iaSrc.S_un.S_addr);
            int size=r-sizeof(IPHDR)-sizeof(ICMPHDR)-sizeof(long);
            long time=GetTickCount()-rep.echoRequest.dwTime;
            int ttl=rep.ipHdr.TTL;
            printf("第 %d个应答:srcip=%s,size=%d,time=%d,ttl=%d\n",req.icmpHdr.Seq,srcip,size,time,ttl);
            
        }
    }
    closesocket(s);
    WSACleanup();
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值