在C++中绑定数据报套接字

3

我正在查看一些简单的数据报套接字发送和接收消息的示例。

服务器端代码。

    sock = socket(AF_INET, SOCK_DGRAM, 0);

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(5000);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    addr_len = sizeof(struct sockaddr);

    if (bind(sock, (struct sockaddr*)&server_addr, addr_len) < 0) 
        exit(1);

    printf("Receiving data ... \n");
    bytes_read = recvfrom(sock, recv_data, 1024, 0, (struct sockaddr*)&client_addr, &addr_len);

    printf("Server received: %s\n", recv_data);

    printf("Sending data ... \n");
    sendto(sock, send_data, strlen(send_data) + 1, 0, (struct sockaddr*)&client_addr, addr_len);

客户端代码。
    sock = socket(AF_INET, SOCK_DGRAM, 0);

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(5000);
    server_addr.sin_addr.s_addr = inet_addr(serverIP);

    addr_len = sizeof(struct sockaddr);

    printf("Sending data ... \n");
    sendto(sock, send_data, strlen(send_data) + 1, 0, (struct sockaddr*)&server_addr, addr_len);

    printf("Receiving data ... \n");
    bytes_read = recvfrom(sock, recv_data, 1024, 0, (struct sockaddr*)&client_addr, &addr_len);
    printf("client received: %s\n", recv_data);

服务器将监听消息并发送响应。
客户端将发送消息,然后监听响应。
在服务器端,我将套接字绑定到INADDR_ANY和端口5000,而在客户端,我根本没有绑定套接字。
如果在服务器端没有进行绑定,则服务器套接字将不会接收任何消息。
而另一方面,即使根本没有进行套接字绑定,客户端套接字也将接收由服务器发送的消息。
为什么我必须绑定服务器套接字而不是客户端套接字?

printf("Server received: %s\n", recv_data); - 是一个安全漏洞。因为坏人可以制造一个没有空终止符的数据包,导致 printf 语句偏离正常操作。 - selbie
简单的解决方法是在输出之前只需添加 recv_data[1023] = '\0'; - selbie
是的,我现在明白了,这些只是大学课程的例子,不会伤害任何人,但还是谢谢。 - pereca
顺便提一句:addr_len = sizeof(struct sockaddr);是错误的,应该是addr_len = sizeof(struct sockaddr_in);或者更好的是addr_len = sizeof(server_addr); ... addr_len = sizeof(client_addr); - Remy Lebeau
1个回答

3
第一次客户端套接字 send 某些内容时,操作系统会自动将套接字绑定到一个随机端口。服务器将作为发送者的端口接收到客户端的端口,并且服务器的响应将发送到客户端套接字绑定的端口。
在服务器端,您需要首先将套接字显式绑定到特定已知端口。如果服务器套接字绑定到某个随机端口,客户端无法找到服务器,这将没有太大帮助。

不绑定到端口0会分配一个合适的随机端口,就像在发送第一个数据包时隐式绑定一样,而显式绑定允许早期知道实际端口号。 - Sam Ginrich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接