我正在编写原始套接字客户端(成功发送UDP数据包)和服务器套接字,问题出在服务器部分 .
我用以下方式创建一个套接字:
int raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
我也尝试使用IPPROTO_RAW,但得到相同的结果,我绑定它:
bind(raw_socket, (struct sockaddr*)&sockstr, sizeof(sockstr))
当尝试使用套接字接收一些数据包时,我收到的唯一有效负载是“E”(我认为这意味着“错误”),或者套接字继续监听但阻塞并且没有任何反应 . 如何使用原始套接字接收UDP数据包?我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
int server(){
int raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (raw_socket== -1){
perror("Socket_creation_error\n");
return 1;
}
struct sockaddr_in sockstr;
sockstr.sin_addr.s_addr = inet_addr("127.0.0.1");
sockstr.sin_family = AF_INET;
sockstr.sin_port = htons(9090);
socklen_t s = (socklen_t)sizeof(sockstr);
if (bind(raw_socket, (struct sockaddr*)&sockstr, sizeof(sockstr))< 0){
perror("binding_err\n");
return 0;
}
char* msg[256];
memset(msg, 0, 256);
recv(raw_socket, msg, sizeof(msg), 0);
printf(msg);
return 0;
}
void main(){
server();
}
1 回答
正如原始套接字手册所述
user@host:~$ man 7 raw
:从手册中提取的另一个重要说明是:
手册也说:
好的,假设你需要手头有IP / UPD Headers ,让我们去上班:-)
首先,我们需要澄清一些观点:
在上面的代码中,缺少某些
#include ...
标头 .IPPROTO_RAW(如手册所述)不能用于接收所有协议 .
为什么要定义socklen?例如,您可以在bind()中使用它 .
char *msg[SIZE]
???这是一个char指针数组!你只需要一个字符数组,如:char msg[SIZE]
.请记住,您正在使用RAW套接字,并且从这些套接字接收的数据包附带 headers . 要打印消息,您需要在msg中执行偏移,该偏移对应于ip header和upd标头 . (在下面的代码中,请注意我已添加
#include <linux/ip.h>
和#include <linux/udp.h>
以获取标头的大小) .最后,做一个清理:在这种情况下只关闭()套接字:-)
代码......
main.c中
好的,现在编译程序:
user@host:~$ gcc -o main main.c
以root身份执行:
root@host:~# ./main
并在另一个终端发送带有nc的消息:
-u指定UPD到nc
user@host:~$ nc -u 127.0.0.1 9090
这就对了!