【发布时间】:2020-08-25 07:25:44
【问题描述】:
我正在尝试在 Windows 10 中使用 RAW SOCKET 处理传入的网络数据包。
当我调用 recvfrom() 函数时,它返回 -1 值。 WSAGetLastError 是 10022。
Microsoft Docs 页面给我以下描述:
WSAEINVAL:10022
参数无效。
提供了一些无效参数(例如,为 setsockopt 函数指定无效级别)。在某些情况下,它还指代套接字的当前状态——例如,在未侦听的套接字上调用接受。
我曾尝试使用setsockopt() 将IP_HDRINCL 设置为1,但是当我调用recvfrom() 时它返回相同的错误。
我的源代码:
#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;
}
返回:
Error in recvfrom(): 10022
【问题讨论】:
-
你真的需要一个原始套接字吗?微软一直在逐渐限制在 Windows 中使用原始套接字可以做什么。事实上,我不确定他们是否真的像某些 *nix 操作系统那样完全支持它。
-
如果你将
addr和addrLen都设置为NULL,你会一直得到错误吗? -
@jwdonahue,我正在研究RAW SOCKET,这个项目仅用于学习目的。我也将尝试研究 winpcap,但我之前尝试使用 RAW SOCKET 处理数据包。用这种方式处理 IP PACKETS 可能不会成功?
-
@RobertoCaboni,如果没有初始化 adr 和 adr_length,或者在所有结构的变量中初始化为 0,或者使用 AF_INET、INADR_ANNY、port = 0 和 adr_length = sizeof(adr) 初始化,也会发生同样的错误。当我使用 bind() 时,recvfrom() 调用不会返回错误,但我没有收到任何数据包。
标签: c windows sockets winsock2 recvfrom