【问题标题】:NO correct data being received on Raw socket未在原始套接字上接收到正确的数据
【发布时间】:2016-09-14 01:08:12
【问题描述】:

我编写了最简单的原始套接字示例,通过原始套接字将数据从一个应用程序发送到另一个应用程序,协议号 = 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);
}

接收者

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

【问题讨论】:

  • 我建议开始检查len(您的读取字节数)以及sendto 实际发送的字节数。也请摆脱那些讨厌的bzeros。
  • 我打印 sendto 和 recv from 返回的值。转发请求:“你好,我是发件人”已转发到服务器,rc = 18(sendto 返回的值是正确的)在接收方:它是 38。

标签: linux sockets


【解决方案1】:

答案非常简单:)。当您收到原始 IP 数据报时,它总是包含 IP 标头。 (提示 - 检查 recvfrom() 的返回值并将其与 sendto() 的返回值进行比较将帮助您实现这一点,正如我在之前的评论中指出的那样。

因此,您可以正确解析 IP 标头以到达您的有效负载,或者您可以假设 IP 标头大小始终为 20 字节并简单地快速转发到它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-27
    • 2022-01-01
    • 2019-11-28
    相关资源
    最近更新 更多