#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,不知道是不是系统或者地址设置错误了,望有经验的朋友看看代码,解说下这代码重点在哪,错误在哪~谢