没有正确的数据正在接收原始套接字
问题描述:
我已经写了最简单的原始套接字示例通过RAW套接字发送数据从一个应用程序到另一个protcol no = 5(未被标准协议使用)。没有正确的数据正在接收原始套接字
这里是我的代码:
发件人
void sendRawData(char sendString[])
{
int sock;
struct sockaddr_in server_addr;
struct hostent *host; //hostent predefined structure use to store info about host host = (struct hostent *) gethostbyname(server);//gethostbyname returns a pointer to hostent
if ((sock = socket(AF_INET, SOCK_RAW, 5)) == -1)
{
perror("socket");
exit(1);
}
//destination address structure
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(NOT_REQ); // NOT_REQ is 2000 but for SOCK_RAW sockets, it should be useless.
server_addr.sin_addr = *((struct in_addr *)host->h_addr); //host->h_addr gives address of host
bzero(&(server_addr.sin_zero),8);
sendto(sock, sendString, strlen(sendString), 0,(struct sockaddr *)&server_addr, sizeof(struct sockaddr));
//sendto() function shall send a message through a connectionless-mode socket.
printf("\nFORWARD REQUEST : '%s' has been forwarded to server\n",sendString);
close(sock);
}
reciever
int main(int argc, char **argv){
int sock = 0, len, addr_len;
char rec_buff[5000];
struct sockaddr_in address,
server_addr_udp,
client_addr;
if ((sock = socket(AF_INET, SOCK_RAW, 5)) == -1) //Creating a UDP Socket
{
perror("Socket");
exit(1);
}
server_addr_udp.sin_family = AF_INET;
server_addr_udp.sin_port = htons(2004); // again it should be useless
server_addr_udp.sin_addr.s_addr = INADDR_ANY;
bzero(&(server_addr_udp.sin_zero),8);
addr_len = sizeof(struct sockaddr);
if (bind(sock,(struct sockaddr *)&server_addr_udp, sizeof(struct sockaddr)) == -1)//Binding UDP socket
{
perror("Bind");
exit(1);
}
len = recvfrom(sock, rec_buff,5000,0,(struct sockaddr *)&client_addr, &addr_len);
printf("ip = %s, port = %d\n", inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
printf("%s\n", rec_buff);
main(0, NULL);
return 0;
}
什么,我观察是在接收端,我收到了不正确的数据。 如果我更改套接字类型SOCK_DGRAM和协议= IPPROTO_UDP,那么一切工作完美。 我的意图是使用自定义协议号(5),因为世界上的每个数据包都不需要是UDP/TCP数据包。
有人能指教我哪里出错了。
输出
ip = 127.0.0.1, port = 0
E
答
答案是出奇的简单:)。当您收到原始IP数据报时,它始终包含IP标头。 (提示 - 检查返回值recvfrom()
并将其与返回值sendto()
进行比较将帮助您实现此目的,正如我在之前的评论中所指出的那样)。
因此,您可以正确解析IP标头以获得有效负载,或者您可以假设IP标头大小始终为20个字节,并且只需快速转发即可。
+0
这确实解决了问题。非常感谢.... –
我推荐开始检查'len'(你的读取字节数)以及'sendto'实际发送的字节数。也请摆脱那些讨厌的'bzero's。 – SergeyA
我打印由sendto和recv来重新调整的值。 FORWARD REQUEST:'你好,我是发件人'已被转发到服务器,rc = 18(由sendto返回的值是正确的) 在接收方:它是38. –