?? socksupport.h
字號(hào):
/**
@file SockSupport.h
Implementation of the winsock2
@author dream2fly
@date 20060921
@note 創(chuàng)建文件
**/
#ifndef SOCKSUPPORT_H_
#define SOCKSUPPORT_H_
#include <vector>
#include <string>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <mstcpip.h>
#pragma comment(lib, "ws2_32.lib")
#define STATUS_FAILED 0xFFFF //定義異常出錯(cuò)代碼
#define MAX_PACK_LEN 65535 // The max IP packet to receive.
#define MAX_ADDR_LEN 16 // The dotted addres's length.
#define MAX_PROTO_TEXT_LEN 16 // The length of sub protocol name(like "TCP").
#define MAX_PROTO_NUM 12 // The count of sub protocols.
#define MAX_HOSTNAME_LAN 255 // The max length of the host name.
/*
// The IP packet is like this. Took from RFC791.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
//定義IP首部
typedef struct ip_hdr // 20 Bytes
{
unsigned char h_verlen; //4位首部長(zhǎng)度,4位IP版本號(hào)
unsigned char tos; //8位服務(wù)類(lèi)型TOS
unsigned short total_len; //16位總長(zhǎng)度(字節(jié))
unsigned short ident; //16位標(biāo)識(shí)
unsigned short frag_and_flags; //3位標(biāo)志位
unsigned char ttl; //8位生存時(shí)間 TTL
unsigned char proto; //8位協(xié)議 (TCP, UDP 或其他)
unsigned short checksum; //16位IP首部校驗(yàn)和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IP_HEADER;
/*
// The TCP packet is like this. Took from RFC793.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|P|R|S|F| |
| Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
//定義TCP首部
typedef struct tcp_hdr // 20 Bytes
{
unsigned short th_sport; //16位源端口
unsigned short th_dport; //16位目的端口
unsigned int th_seq; //32位序列號(hào)
unsigned int th_ack; //32位確認(rèn)號(hào)
unsigned char th_lenres; //4位首部長(zhǎng)度/6位保留字
unsigned char th_flag; //6位標(biāo)志位
unsigned short th_win; //16位窗口大小
unsigned short th_sum; //16位校驗(yàn)和
unsigned short th_urp; //16位緊急數(shù)據(jù)偏移量
}TCP_HEADER;
/*
// The TCP's pseudo header is like this. Took from RFC793.
+--------+--------+--------+--------+
| Source Address |
+--------+--------+--------+--------+
| Destination Address |
+--------+--------+--------+--------+
| zero | PTCL | TCP Length |
+--------+--------+--------+--------+
*/
//定義TCP偽首部 pseudo[ 'psju:dou ] 假的,冒充的
typedef struct psd_hdr // 16 Bytes
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz; //置空
char ptcl; //協(xié)議類(lèi)型
unsigned short tcpl; //TCP長(zhǎng)度
}PSD_HEADER;
/*
// The UDP packet is lick this. Took from RFC768.
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| Source | Destination |
| Port | Port |
+--------+--------+--------+--------+
| | |
| Length | Checksum |
+--------+--------+--------+--------+
|
| data octets ...
+---------------- ...
*/
typedef struct udp_hdr // 8 Bytes
{
unsigned short uh_sport; //16位源端口
unsigned short uh_dport; //16位目的端口
unsigned short uh_len; //16位長(zhǎng)度
unsigned short uh_sum; //16位校驗(yàn)和
} UDP_HEADER;
typedef struct icmp_hdr // 12 Bytes
{
unsigned char ih_type; //8位類(lèi)型
unsigned char ih_code; //8位代碼
unsigned short ih_cksum; //16位校驗(yàn)和
unsigned short ih_id; //識(shí)別號(hào)(一般用進(jìn)程號(hào)作為識(shí)別號(hào))
unsigned short ih_seq; //報(bào)文序列號(hào)
unsigned long ih_timestamp; //時(shí)間戳
}ICMP_HEADER;
// The protocol's map.
typedef struct proto_map
{
int ProtoNum;
char ProtoText[MAX_PROTO_TEXT_LEN];
}PROTOMAP;
static PROTOMAP ProtoMap[MAX_PROTO_NUM]=
{
{ IPPROTO_IP , "IP " },
{ IPPROTO_ICMP , "ICMP" },
{ IPPROTO_IGMP , "IGMP" },
{ IPPROTO_GGP , "GGP " },
{ IPPROTO_TCP , "TCP " },
{ IPPROTO_PUP , "PUP " },
{ IPPROTO_UDP , "UDP " },
{ IPPROTO_IDP , "IDP " },
{ IPPROTO_ND , "NP " },
{ IPPROTO_RAW , "RAW " },
{ IPPROTO_MAX , "MAX " },
{ NULL , "" }
};
//計(jì)算檢驗(yàn)和函數(shù)
static u_short checksum(u_short *buffer, int size)
{
u_long cksum=0;
while(size >1)
{
cksum+=*buffer++;
size-=sizeof(u_short);
}
if(size==1) cksum+=*(u_char*)buffer;
cksum=(cksum >> 16)+(cksum & 0xffff);
cksum+=(cksum >> 16);
return (u_short)(~cksum);
}
static char* CheckProtocol(int iProtocol)
{
for(int i=0; i<MAX_PROTO_NUM; ++i)
{
if(ProtoMap[i].ProtoNum==iProtocol)
return ProtoMap[i].ProtoText;
}
return "";
}
//判斷操作系統(tǒng)涵數(shù)及變量
typedef enum _OS_LEVEL{
WIN_UNSUP,
WIN_NT_3_5,
WIN_NT_3_51,
WIN_NT_4,
WIN_NT_4_SP2,
WIN_NT_4_SP3,
WIN_NT_4_SP4,
WIN_NT_4_SP5,
WIN_NT_4_SP6,
WIN_2000,
WIN_2000_SP1,
WIN_2000_SP2,
WIN_XP,
WIN_XP_SP1,
WIN_XP_SP2,
WIN_2003
}OS_LEVEL;
static OS_LEVEL get_win32_type()
{
static OS_LEVEL os_level;
static OSVERSIONINFO oslev;
oslev.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&oslev);
if (oslev.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
static unsigned int servpack = 0;
char *pservpack;
if (pservpack = oslev.szCSDVersion) {
while (*pservpack && !isdigit(*pservpack)) {
pservpack++;
}
if (*pservpack)
servpack = atoi(pservpack);
}
if (oslev.dwMajorVersion == 3) {
if (oslev.dwMajorVersion < 50) {
os_level = WIN_UNSUP;
}
else if (oslev.dwMajorVersion == 50) {
os_level = WIN_NT_3_5;
}
else {
os_level = WIN_NT_3_51;
}
}
else if (oslev.dwMajorVersion == 4) {
if (servpack < 2)
os_level = WIN_NT_4;
else if (servpack <= 2)
os_level = WIN_NT_4_SP2;
else if (servpack <= 3)
os_level = WIN_NT_4_SP3;
else if (servpack <= 4)
os_level = WIN_NT_4_SP4;
else if (servpack <= 5)
os_level = WIN_NT_4_SP5;
else
os_level = WIN_NT_4_SP6;
}
else if (oslev.dwMajorVersion == 5) {
if (oslev.dwMinorVersion == 0) {
if (servpack == 0)
os_level = WIN_2000;
else if (servpack == 1)
os_level = WIN_2000_SP1;
else
os_level = WIN_2000_SP2;
}
else if (oslev.dwMinorVersion == 2) {
os_level = WIN_2003;
}
else if (oslev.dwMinorVersion == 1){
if (servpack < 1)
os_level = WIN_XP;
else if (servpack == 1)
os_level = WIN_XP_SP1;
else
os_level = WIN_XP_SP2;
}
}
else {
os_level = WIN_UNSUP;
}
}
return os_level;
}
//------------------------------------------------------------
// 函 數(shù):TransformIp(char* addr,DWORD &dwIP,bool flag)
// 參 數(shù):char* addr,DWORD &dwIP,bool flag
// 返回值:如果成功返回true,不成功,返回false
// 描 述:字符串的IP與DWORD的IP轉(zhuǎn)化.當(dāng)為真時(shí),把DWORD的IP轉(zhuǎn)換為字符串,當(dāng)為假時(shí)轉(zhuǎn)化為DWORD型
//------------------------------------------------------------
static bool TransformIp(char* addr,DWORD &dwIP,bool flag) //注意:傳入的dwIP參數(shù)必須為網(wǎng)絡(luò)字節(jié)循序!
{
//char 轉(zhuǎn)化為 DWORD
if (flag)
{
char* ipaddr = NULL;
in_addr inaddr;
inaddr.s_addr=dwIP;
ipaddr= inet_ntoa(inaddr);
strcpy(addr,ipaddr);
return true;
}
//DWORD 轉(zhuǎn)化為 char
else
{
dwIP = inet_addr(addr);
return true;
}
}
static char* GetLocalIP()
{
char szLocname[MAX_HOSTNAME_LAN];
LPHOSTENT pHostent;
struct in_addr in_addrIP;
int iRc = gethostname(szLocname, MAX_HOSTNAME_LAN);
if (iRc == SOCKET_ERROR)
{
return NULL;
}
pHostent = gethostbyname(szLocname);
for (int nAdapter=0; pHostent->h_addr_list[nAdapter]; nAdapter++)
{
in_addrIP = *(struct in_addr *) (pHostent->h_addr_list[nAdapter]);
break;//just 暫時(shí)解決方案
}
return inet_ntoa(in_addrIP);
}
static unsigned long MakeRand32(int i)
{
unsigned long j1,j2,s;
i = i << 15;
//srand( (unsigned int)time(NULL) + i );
j1 = rand()+i;
j2 = rand()+i;
j1 = j1 << 16;
s = j1+j2;
return s;
}
static unsigned short MakeRand16(int i)
{
unsigned short s;
i = i << 15;
//srand( (unsigned int)time(NULL) +i );
s = rand()+i;
return s;
}
static int PrintError(const char* strErr)
{
LPTSTR lpErr=0;
DWORD dwErr;
CString CStrErr;
dwErr=WSAGetLastError();
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, dwErr,LANG_NEUTRAL,
lpErr, 0, NULL);
if(lpErr==NULL)
{
switch(dwErr)
{
case 10004: lpErr = "Interrupted system call"; break;
case 10009: lpErr = "Bad file number"; break;
case 10013: lpErr = "Permission denied"; break;
case 10014: lpErr = "Bad address"; break;
case 10022: lpErr = "Invalid argument (not bind)"; break;
case 10024: lpErr = "Too many open files"; break;
case 10035: lpErr = "Operation would block"; break;
case 10036: lpErr = "Operation now in progress"; break;
case 10037: lpErr = "Operation already in progress"; break;
case 10038: lpErr = "Socket operation on non-socket"; break;
case 10039: lpErr = "Destination address required"; break;
case 10040: lpErr = "Message too long"; break;
case 10041: lpErr = "Protocol wrong type for socket"; break;
case 10042: lpErr = "Bad protocol option"; break;
case 10043: lpErr = "Protocol not supported"; break;
case 10044: lpErr = "Socket type not supported"; break;
case 10045: lpErr = "Operation not supported on socket"; break;
case 10046: lpErr = "Protocol family not supported"; break;
case 10047: lpErr = "Address family not supported by protocol family"; break;
case 10048: lpErr = "Address already in use"; break;
case 10049: lpErr = "Can't assign requested address"; break;
case 10050: lpErr = "Network is down"; break;
case 10051: lpErr = "Network is unreachable"; break;
case 10052: lpErr = "Net dropped connection or reset"; break;
case 10053: lpErr = "Software caused connection abort"; break;
case 10054: lpErr = "Connection reset by peer"; break;
case 10055: lpErr = "No buffer space available"; break;
case 10056: lpErr = "Socket is already connected"; break;
case 10057: lpErr = "Socket is not connected"; break;
case 10058: lpErr = "Can't send after socket shutdown"; break;
case 10059: lpErr = "Too many references, can't splice"; break;
case 10060: lpErr = "Connection timed out"; break;
case 10061: lpErr = "Connection refused"; break;
case 10062: lpErr = "Too many levels of symbolic links"; break;
case 10063: lpErr = "File name too long"; break;
case 10064: lpErr = "Host is down"; break;
case 10065: lpErr = "No Route to Host"; break;
case 10066: lpErr = "Directory not empty"; break;
case 10067: lpErr = "Too many processes"; break;
case 10068: lpErr = "Too many users"; break;
case 10069: lpErr = "Disc Quota Exceeded"; break;
case 10070: lpErr = "Stale NFS file handle"; break;
case 10091: lpErr = "Network SubSystem is unavailable"; break;
case 10092: lpErr = "WINSOCK DLL Version out of range"; break;
case 10093: lpErr = "Successful WSASTARTUP not yet performed"; break;
case 10071: lpErr = "Too many levels of remote in path"; break;
case 11001: lpErr = "Host not found"; break;
case 11002: lpErr = "Non-Authoritative Host not found"; break;
case 11003: lpErr = "Non-Recoverable errors: FORMERR, REFUSED, NOTIMP"; break;
case 11004: lpErr = "Valid name, no data record of requested type"; break;
default: lpErr = "unknown"; break;
}
}
CStrErr.Format("\n\tFail:%s, Reason:%d/%s , at line %d in %s\n\n",strErr,dwErr,lpErr,__LINE__,__FILE__);
TRACE("\n\tFail:%s, Reason:%d/%s , at line %d in %s\n\n",strErr,dwErr,lpErr,__LINE__,__FILE__);
AfxMessageBox(CStrErr);
exit(EXIT_FAILURE);
return 0;
}
enum link_type
{
_CONNECT,
_SYN,
_ICMP,
_TCP,
_UDP
};
///////////////////////
class CSockSupport
{
public:
CSockSupport(bool bAuto = true);
~CSockSupport(void);
int Init();
int Uninit();
// Check whether the winsock is initialized(supported).
bool IsSupported();
private:
bool m_bSupported;
};
#endif
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -