简体   繁体   English

winsock2:RAW SOCKET recvfrom() 返回错误 10022(无效参数)

[英]winsock2: RAW SOCKET recvfrom() returns Error 10022 (Invalid Argument)

I'm trying to handle incoming network packets with RAW SOCKET in Windows 10.我正在尝试使用 Windows 10 中的 RAW SOCKET 处理传入的网络数据包。

When I call recvfrom() function it returns -1 value.当我调用recvfrom() function 它返回 -1 值。 WSAGetLastError is 10022. WSAGetLastError是 10022。

Microsoft Docs page give me the following description: Microsoft Docs 页面给了我以下描述:

WSAEINVAL: 10022 WSAEINVAL:10022
Invalid argument.无效的论点。
Some invalid argument was supplied (for example, specifying an invalid level to the setsockopt function).提供了一些无效参数(例如,为 setsockopt 函数指定无效级别)。 In some instances, it also refers to the current state of the socket—for instance, calling accept on a socket that is not listening.在某些情况下,它还引用套接字的当前 state — 例如,在未侦听的套接字上调用接受。

I have tried to use setsockopt() to set IP_HDRINCL to 1, but it returns the same error when I call recvfrom() .我尝试使用setsockopt()IP_HDRINCL设置为 1,但是当我调用recvfrom()时它返回相同的错误。

My source code:我的源代码:

#include "stdio.h"
#include "winsock2.h"
#include "ws2tcpip.h"


int main(){
    SOCKET s;
    char* buff = malloc(256);
    int optval = 1;
    struct sockaddr_in adr;
    int adr_length = sizeof(adr);
    int i;
    int rcv_len;
    WSADATA wsa;

    memset(buff, 0, 256);

    if(WSAStartup(MAKEWORD(2,2), &wsa) != 0){
        printf("Error in WSAStartup: %d\n", WSAGetLastError());
        getch();
        return 0;
    }

    s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
    if(s == SOCKET_ERROR){
        printf("Error in socket creation: %d\n", WSAGetLastError());
        getch();
        return 0;
    }

    if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval)) == -1){
        printf("Error in setsockopt(): %d\n", WSAGetLastError());
        getch();
        closesocket(s);
        return 0;
    }

    while(1){
        rcv_len = recvfrom(s, buff, 256, 0, (struct sockaddr*)&adr, &adr_length);

        if(rcv_len == -1){
            printf("Error in recvfrom(): %d\n", WSAGetLastError());
            getch();
            break;
        }

        for(i = 0; i < 256; i ++){
            printf("%c", *(buff + i));
        }
    }

    closesocket(s);

    return 1;
}

Return:返回:

Error in recvfrom(): 10022

I have fixed the problem.我已经解决了这个问题。

What was missing:缺少什么:

  1. Turn on the SOCKET with bind() using the IP of the interface you are handling使用您正在处理的接口的 IP 使用bind()打开 SOCKET
  2. Set opt SO_RCVALL to 1 with WSAIoctl()使用WSAIoctl()将 opt SO_RCVALL设置为 1

So, now the code is working with this source:所以,现在代码正在使用这个源:

#include "stdio.h"
#include "winsock2.h"
#include "ws2tcpip.h"

int main(){
    SOCKET s;
    unsigned char* buff = malloc(32768);
    int optval = 1;
    struct sockaddr_in adr;
    struct sockaddr_in sadr;
    int adr_length = 0;
    int i;
    int in;
    int rcv_len;
    WSADATA wsa;

    memset(buff, 0, 32768);

    if(WSAStartup(MAKEWORD(2,2), &wsa) != 0){
        printf("Error in WSAStartup: %d\n", WSAGetLastError());
        getch();
        return 0;
    }

    s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
    if(s == SOCKET_ERROR){
        printf("Error in socket creation: %d\n", WSAGetLastError());
        getch();
        return 0;
    }

    sadr.sin_family = AF_INET;
    sadr.sin_addr.s_addr = inet_addr("127.0.0.1");
    sadr.sin_port = htons(0);

    bind(s, (struct sockaddr*)&sadr, sizeof(sadr));

    if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval)) == -1){
        printf("Error in setsockopt(): %d\n", WSAGetLastError());
        getch();
        closesocket(s);
        return 0;
    }

    optval = 1;
    WSAIoctl(s, SIO_RCVALL, &optval, sizeof(optval), 0, 0, (LPDWORD) &in, 0, 0);

    while(1){
        adr_length = sizeof(adr);
        rcv_len = recvfrom(s, buff, 32768, 0, (struct sockaddr*)&adr, &adr_length);

        if(rcv_len == -1){
            printf("Error in recvfrom(): %d\n", WSAGetLastError());
            getch();
            break;
        }

        for(i = 0; i < rcv_len; i ++){
            printf("%d ", *(buff + i));
        }
    }

    closesocket(s);

    return 1;
}

Thank you all!谢谢你们!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM