📄 socket.cpp
字号:
#include "stdafx.h"
//预编译头文件通过编译stdafx.cpp生成,以工程名命名,
//由于预编译的头文件的后缀是“.pch”,所以编译结果文件是ping.pch。
//编译器通过一个头文件stdafx.h来使用预编译头文件。
//stdafx.h这个头文件名是可以在project的编译设置里指定的。
//编译器认为,所有在指令#include "stdafx.h"前的代码都是预编译的,
//它跳过#include "stdafx. h"指令,使用projectname.pch编译这条指令之后的所有代码。
#include <winsock.h>
#pragma comment(lib, "wsock32.lib")//
#define ICMP_ECHO 8
#define ICMP_ECHOREPLY 0
#pragma pack(push,1)//
typedef struct iphdr {
unsigned int h_len:4; // length of the header
unsigned int version:4; // Version of IP
unsigned char tos; // Type of service
unsigned short total_len; // total length of the packet
unsigned short ident; // unique identifier
unsigned short frag_and_flags; // flags
unsigned char ttl;
unsigned char proto; // protocol (TCP, UDP etc)
unsigned short checksum; // IP checksum
unsigned int sourceIP;
unsigned int destIP;
}IpHeader;
typedef struct _ihdr {
BYTE i_type; /* ICMP 包类型 */
BYTE i_code; /* ICMP 包子类型 */
USHORT i_cksum; /* 校验和 */
USHORT i_id; /* 报文ID */
USHORT i_seq; /* 报文序号 */
ULONG timestamp; /* 发送时间 */
}IcmpHeader;
#pragma pack(pop)//
USHORT checksum(USHORT *buffer, int size);
SOCKET m_socket;
int seq_no = 0;
BOOL ping( const char *ipaddr, char *resp )
{
struct sockaddr_in dest,from;
int fromlen;
int res;
int datasize = 32;
IcmpHeader *icmphdr;
IpHeader *iphdr;
int iphdrlen;
char *datapart;
char pkt[1024];
memset(&dest,0,sizeof(dest));
dest.sin_addr.s_addr = inet_addr(ipaddr);//将地址转换成一个整数
dest.sin_family = AF_INET;
datasize += sizeof(IcmpHeader);
memset(pkt,0,1024);
icmphdr = (IcmpHeader*)pkt;
//填充报文头
icmphdr->i_type = ICMP_ECHO;
icmphdr->i_code = 0;
icmphdr->i_cksum = 0;
icmphdr->i_seq = seq_no;
seq_no = (seq_no + 1) % 100;
icmphdr->timestamp = GetTickCount();
datapart = pkt + sizeof(IcmpHeader);
memset(datapart,'E', datasize - sizeof(IcmpHeader));
icmphdr->i_cksum = checksum((USHORT*)pkt,datasize);
res = sendto(m_socket,pkt,datasize,0,(struct sockaddr*)&dest, sizeof(dest));
if (res == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAETIMEDOUT)
{
strcpy(resp,"发送超时!");
return FALSE;
}
strcpy(resp,"发送失败!");
return FALSE;
}
fromlen = sizeof(from);
res = recvfrom(m_socket,pkt,1024,0,(struct sockaddr*)&from,&fromlen);
if (res == SOCKET_ERROR)
{
int err = WSAGetLastError();
if (err == WSAETIMEDOUT)
{
strcpy(resp,"接收超时!");
return FALSE;
}
strcpy(resp,"接收失败!");
return FALSE;
}
iphdr = (IpHeader *)pkt;
iphdrlen = iphdr->h_len * 4 ; // number of 32-bit words *4 = bytes
icmphdr = (IcmpHeader*)(pkt + iphdrlen);
if (icmphdr->i_type != ICMP_ECHOREPLY) {
strcpy(resp,"未知的回应");
return FALSE;
}
int dist = GetTickCount() - icmphdr->timestamp;
if(dist < 0)
dist = 0;
sprintf(resp,"收到来自 %s: %d 字节 费时: %d ms ",
inet_ntoa(from.sin_addr),
res - iphdrlen - sizeof(IcmpHeader),
dist);
return TRUE;
}
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while(size >1) {
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size ) {
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -