我试图在Windows 10中使用RAW SOCKET处理传入的网络数据包。
当我调用 recvfrom()
函数,它返回-1值。WSAGetLastError
是10022。
Microsoft Docs页面给我的描述如下。
WSAEINVAL: 10022 无效参数。 提供了一些无效的参数(例如,给setockopt函数指定了一个无效的级别)。在某些情况下,它也指的是套接字的当前状态--例如,在一个没有监听的套接字上调用accept。
我曾尝试使用 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
我已经修复了这个问题。
什么是缺失。
bind()
使用您正在处理的接口的IPSO_RCVALL
以1为单位 WSAIoctl()
所以,现在用这个源码就能用了。
#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;
}
谢谢大家!