#include <stdio.h>
#include <Winsock2.h>
#include <ws2tcpip.h>
#pragma comment( lib, "ws2_32.lib");
//定义 ip 首部
typedef struct IpHeader
{
u_char Version_HLen; //首部长度ip版本号
u_char TOS; //服务类型 TOS
short Length; //总长度
short Ident; //标识
short Flags_Offset; //标志位
u_char TTL; //生存时间 TTL
u_char Protocol; //协议
short Checksum; //ip 首部校检位
unsigned int SourceAddr; // 源 ip 地址
unsigned int DestinationAddr; //目的 ip 地址
} Ip_Header;// 定义 TCP 伪首部
typedef struct PsdTcpHeader
{
unsigned long SourceAddr; //源地址
unsigned long DestinationAddr; //目的地址
char Zero;
char Protocol; //协议类型
unsigned short TcpLength; //TCP 长度
} PSD_Tcp_Header;//定义 TCP 首部
typedef struct TcpHeader
{
USHORT SrcPort; //16位源端口
USHORT DstPort; //16位目的端口
unsigned int SequenceNum; //32位序列号
unsigned int Acknowledgment; //32位确认号
unsigned char HdrLen; //首部长度
unsigned char Flags; //6位标志位
USHORT AdvertisedWindow; //16位窗口大小
USHORT Checksum; //16位校检和
USHORT UrgPtr; //16位紧急数据偏移量
} Tcp_Header;//计算校检和
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); //这里不懂,麻烦解释一下(USHORT)(~cksum)是什么意思
}
int main()
{
char *Target = "192.168.1.101";
struct in_addr localaddr;
char HostName[255];
struct hostent *Hostent;
WSADATA wsaData;
SOCKET SendSocket;
SOCKADDR_IN addr_in;
Ip_Header ipHeader;
Tcp_Header tcpHeader;
PSD_Tcp_Header psdHeader;
char szSendBuf[100] =
{
0
};
BOOL flag;
int nTimeOver;
int Result;
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (Result == SOCKET_ERROR)
{
printf("第1 error %d\n", Result);
return 0;
}
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
if ((SendSocket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("第2 error %d\n\n", WSAGetLastError());
return false;
}
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
flag = true;
if (setsockopt(SendSocket, IPPROTO_IP, IP_HDRINCL, (char*) &flag, sizeof(flag)) == SOCKET_ERROR)
{
printf("第3 error %d\n\n", WSAGetLastError());
return false;
}
nTimeOver = 1000;
if (setsockopt(SendSocket, SOL_SOCKET, SO_SNDTIMEO, (char*) &nTimeOver, sizeof(nTimeOver)) == SOCKET_ERROR)
{
printf("第4 error %d\n\n", WSAGetLastError());
return false;
}
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(1234);
addr_in.sin_addr.S_un.S_addr = inet_addr(Target);
Result = gethostname(HostName, 255);
if (Result == SOCKET_ERROR)
{
printf("第5 error %d\n", WSAGetLastError());
return 0;
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Hostent = (struct hostent*)malloc(sizeof(struct hostent));
Hostent = gethostbyname(HostName);
memcpy(&localaddr, Hostent->h_addr_list[0], Hostent->h_length);
ipHeader.Version_HLen = (4 << 4 | sizeof(ipHeader) / sizeof(unsigned long));
ipHeader.TOS = 0;
ipHeader.Length = htons(sizeof(ipHeader) + sizeof(tcpHeader));
ipHeader.Ident = htons(1);
ipHeader.Flags_Offset = 0;
ipHeader.TTL = 128;
ipHeader.Protocol = IPPROTO_TCP;
ipHeader.Checksum = 0;
ipHeader.SourceAddr = inet_addr("192.168.1.100");
ipHeader.DestinationAddr = inet_addr(Target);
tcpHeader.DstPort = htons(80);
tcpHeader.SrcPort = htons(6666);
tcpHeader.SequenceNum = 0;
tcpHeader.Acknowledgment = 0;
tcpHeader.HdrLen = (sizeof(tcpHeader) / 4 << 4 | 0);
tcpHeader.Flags = 2;
tcpHeader.AdvertisedWindow = htons(512);
tcpHeader.UrgPtr = 0;
tcpHeader.Checksum = 0;
psdHeader.SourceAddr = ipHeader.SourceAddr;
psdHeader.DestinationAddr = ipHeader.DestinationAddr;
psdHeader.Zero = 0;
psdHeader.Protocol = IPPROTO_TCP;
psdHeader.TcpLength = htons(sizeof(tcpHeader));
memcpy(szSendBuf, &psdHeader, sizeof(psdHeader));
memcpy(szSendBuf + sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));
tcpHeader.Checksum = checksum((USHORT*)szSendBuf, sizeof(psdHeader) + sizeof(tcpHeader));
memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf + sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
ipHeader.Checksum = checksum((USHORT*)szSendBuf, sizeof(ipHeader));
memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
Result = sendto(SendSocket, szSendBuf, sizeof(ipHeader) + sizeof(tcpHeader), 0, (struct sockaddr*) &addr_in, sizeof(addr_in));
if (Result == SOCKET_ERROR)
{
printf("第6 error %d\n", WSAGetLastError());
//~~~~~~~~~~~~~~~~在我机上运行的时候是这里出问题了,但是不知道是啥问题,麻烦了~
return 0;
}
else
{
printf("Send a Tcp data\n");
printf("IP Header--------:\n");
printf("Ip Tos:%d\n", ipHeader.TOS);
printf("IP Length:%d\n", ntohs(ipHeader.Length));
printf("IP Ident:%d\n", ntohs(ipHeader.Ident));
printf("IP TTL:%d\n", ipHeader.TTL);
printf("IP Protocol:%d\n", ipHeader.Protocol);
printf("IP Checksum:%d\n", ntohs(ipHeader.Checksum));
struct in_addr a;
a.s_addr = ipHeader.SourceAddr;
printf("IP SourceAddr:%s\n", inet_ntoa(a));
a.s_addr = ipHeader.DestinationAddr;
printf("IP DestinationAddr:%s\n", inet_ntoa(a));
printf("TCP Header--------:\n");
printf("TCP DstPort:%d\n", ntohs(tcpHeader.DstPort));
printf("TCP SrcPort:%d\n", ntohs(tcpHeader.SrcPort));
printf("TCP SequenceNum:%d\n", ntohl(tcpHeader.SequenceNum));
printf("TCP Acknowledgment:%d\n", ntohs(tcpHeader.Acknowledgment));
unsigned char h;
h = tcpHeader.HdrLen;
h = h >> 4;
printf("Tcp HerderLength:%d\n", 4 *h);
printf("Tcp Flags:%d\n", tcpHeader.Flags);
printf("TCP AdvertisedWindow:%d\n", ntohs(tcpHeader.AdvertisedWindow));
printf("TCP UrgPtr:%d\n", ntohs(tcpHeader.UrgPtr));
printf("TCP Checksum:%d\n", ntohs(tcpHeader.Checksum));
}
if (closesocket(SendSocket) == SOCKET_ERROR)
{
printf("第7 error %d\n", WSAGetLastError());
return 0;
} if (WSACleanup() == SOCKET_ERROR)
{
printf("第8 error %d\n", WSAGetLastError());
return 0;
}
return 1;
}
编译之后运行说第6个地方出错了,但是找不出来原因,书上陪套光盘里的代码,自问应该没错才对,系统是windows sp3,不知道是不是系统或者地址设置错误了,望有经验的朋友看看代码,解说下这代码重点在哪,错误在哪~谢
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货