c++ - 使用原始套接字 (c++)

标签 c++ windows sockets

我是原始套接字的新手。我以前在套接字上工作过,但我从来没有用原始套接字做过什么。我收到错误 #10049 -> WSAEADDRNOTAVAIL“无法分配请求的地址”@“sendto”

我希望你能帮助我!

我的代码:

#include <WinSock2.h>
#include <stdio.h>

typedef unsigned char U8;
typedef unsigned short U16;

struct ipheader
{
    U8 length : 4;// : 4;
    U8 version : 4;

    U8 differentiated_services_field;
    U16 total_length;
    U16 ident;
    U16 fragment; // fragment offset // first 8 bit = flags not 8 bit
    U8 ttl; // time to live
    U8 protocol;
    U16 checksum;
    in_addr src;
    in_addr dst;
};

struct udpheader
{
    U16 srcport;
    U16 dstport;
    U16 length;
    U16 checksum;
};


#define CON_SERVER_IP           "127.0.0.1"
#define CON_SERVER_PORT         1234

#define MY_PORT                 9191
#define MY_IP                   "127.0.0.1"

#define DATA_LENGTH 16
#define WHOLE_LENGTH (20+8+DATA_LENGTH)

// http://www.c-worker.ch/tuts/raw_icmp.php
unsigned short Checksum(unsigned short *p_usBuffer,int iSize)
{
    unsigned long lCheckSum = 0;
    while(iSize > 1)
    {
        lCheckSum += *p_usBuffer++;
        iSize -= sizeof(unsigned short);
    }
    if(iSize)
        lCheckSum += *(unsigned char*)p_usBuffer; // + 0 entfällt, da überflüßig
    lCheckSum = ((lCheckSum >> 16) + (lCheckSum & 0xffff)) + (lCheckSum >> 16);
    return (unsigned short)(~lCheckSum);
}
int main(int argc,char* argv[])
{
    WSADATA wsa;
    WSAStartup(MAKEWORD(2,0),&wsa);

    char packet[WHOLE_LENGTH];

    ZeroMemory(packet,WHOLE_LENGTH);

    ipheader* pIpHeader = (ipheader*)&packet;
    udpheader* pUDPHeader = (udpheader*) &packet + sizeof(ipheader);

    SOCKADDR_IN sAddr;
    ZeroMemory(&sAddr,sizeof(SOCKADDR_IN));
    sAddr.sin_family = AF_INET;
    sAddr.sin_port = htons(CON_SERVER_PORT);
sAddr.sin_addr.s_addr = inet_addr(CON_SERVER_IP); // thank you BevynQ

    pIpHeader->length = 5;
    pIpHeader->version = 4;
    pIpHeader->differentiated_services_field = 0;
    pIpHeader->total_length = sizeof(ipheader) + sizeof(udpheader) + DATA_LENGTH;
    pIpHeader->ident = htonl(54321);
    pIpHeader->fragment = 0;
    pIpHeader->ttl = 65;
    pIpHeader->protocol = IPPROTO_UDP;
    pIpHeader->checksum = 0;
    pIpHeader->src.s_addr = inet_addr(MY_IP);
    pIpHeader->dst.s_addr = inet_addr(CON_SERVER_IP);

    pUDPHeader->srcport = htons(MY_PORT);
    pUDPHeader->dstport = htons(CON_SERVER_PORT);
    pUDPHeader->length = sizeof(udpheader) + DATA_LENGTH;
    pUDPHeader->checksum = 0;

    strcpy(packet+sizeof(ipheader)+sizeof(udpheader),"Lets go\n");

    pUDPHeader->checksum = Checksum((unsigned short*)packet+sizeof(ipheader),sizeof(udpheader)+DATA_LENGTH);

    pIpHeader->checksum = Checksum((unsigned short*)packet,WHOLE_LENGTH);

    printf("UDPHeader checksum:\t0x%04X\n",pUDPHeader->checksum);
    printf("IPHeader checksum:\t0x%04X\n",pIpHeader->checksum);


    SOCKET sock = socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
    if(sock == INVALID_SOCKET)
    {
        printf("socket generation failed (%d)\n",WSAGetLastError());
        goto q1;
    }

    int i = sendto(sock,packet,WHOLE_LENGTH,0,(SOCKADDR*)&sAddr,sizeof(SOCKADDR_IN));
    printf("sendto: %i (%d)\n",i,WSAGetLastError());
q1:
    printf("\n\n\n\nDone\n");
    getchar();
    return 0;
}

编辑:错误不再发生,但没有建立连接。明天我再研究一下。 感谢您的帮助!

Edit2:无法发送数据包,因为尚未设置 IP_HDRINCL 选项。通过这样做,它起作用了;)

最佳答案

尝试

SOCKADDR_IN sAddr;
ZeroMemory(&sAddr,sizeof(SOCKADDR_IN));
sAddr.sin_family = AF_INET;
sAddr.sin_port = htons(CON_SERVER_PORT);
inet_pton(AF_INET, CON_SERVER_IP, &sAddr.sin_addr);

关于c++ - 使用原始套接字 (c++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17459625/

相关文章:

c++ - 无法获得 Boost Spirit 语法以使用 std::map<> 的已知键

windows - 使用 MSVC 2010 构建 OpenSSL 1.0.1c 时出错

android - 蓝牙创建套接字但在 connect() 处阻塞 ANDROID

Python TCP 套接字数据有时会丢失部分。套接字溢出?

java - 在不关闭套接字的情况下使用 java.nio.* 中断 InputStream#read() 的任何方法?

c++ - 使 clang 的 Memory Sanitizer 报告统一变量使用而不决定分支

c# - 哪个更快 - C# 不安全代码或原始 C++

c++ - 线程安全的 TBB::concurrent_hash_map 删除

Python 找不到 pyobdc。文件夹的名称可能是问题所在吗?

python - 使用 pycrypto 时没有名为 'winrandom' 的模块