【问题标题】:UDP socket not respondingUDP 套接字没有响应
【发布时间】:2014-04-22 12:19:04
【问题描述】:

我正在编写一个 c udp 套接字示例。 这是客户

#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <arpa/inet.h>

int
main(int argc, char *argv[]) {
    if (argc < 3) {
        fprintf(stderr, "Usage: %s ip port\n", argv[0]);
        exit(1);
    }

    int sock;
    char *server_ip;
    unsigned short server_port;
    struct sockaddr_in cliAddr, serAddr;

    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)  {
        fprintf(stderr, "socket failed\n");
        exit(1);
    }

    server_ip = argv[1];
    server_port = atoi(argv[2]);

    memset(&cliAddr, 0, sizeof(cliAddr));
    cliAddr.sin_family = AF_INET;
    cliAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    cliAddr.sin_port = htons(21152);

    if (bind(sock, (struct sockaddr *) &cliAddr, sizeof(struct sockaddr)) < 0) {
        fprintf(stderr, "bind failed\n");
        exit(1);
    }

    memset(&serAddr, 0, sizeof(serAddr));
    serAddr.sin_family = AF_INET;
    serAddr.sin_addr.s_addr = inet_addr(server_ip);
    serAddr.sin_port = htons(server_port);

    if (sendto(sock, "hello", 5, 0, (struct sockaddr *) (&serAddr), sizeof(serAddr)) == -1) {
        fprintf(stderr, "sendto failed\n");
        exit(1);
    }

    printf("send success\n");

    int n;
    char recvstr[50];
    if ((n = recvfrom(sock, &recvstr, 50, 0, NULL, NULL)) < 0) {
        fprintf(stderr, "recvfrom failed\n");
        exit(1);
    }

    printf("receive success: %s\n", recvstr);
    printf("from %s:%d\n", inet_ntoa(serAddr.sin_addr), ntohs(serAddr.sin_port));

    exit(0);
  }

这是服务器

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>

int
main(int argc, char *argv[]) {
    if (argc < 2) {
        fprintf(stderr, "Usage: %s port\n", argv[0]);
        exit(1);
    }

    int sock, n;
    struct sockaddr_in servaddr, cliaddr;
    char recvstr[50];
    socklen_t cliaddrlen;

    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        fprintf(stderr, "socket failed\n");
        exit(1);
    }

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(atoi(argv[1]));

    if (bind(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        fprintf(stderr, "bind failed\n");
        exit(1);
    }

    cliaddrlen = sizeof(cliaddr);
    if ((n = recvfrom(sock, recvstr, 50, 0, (struct sockaddr *) &cliaddr, &cliaddrlen)) < 0) {
        fprintf(stderr, "recvfrom failed\n");
        exit(1);
    }

    printf("client ip: %s, client port: %d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));

    if (sendto(sock, "hello from server", 17, 0, (struct sockaddr *) &cliaddr, cliaddrlen) == -1) {
        fprintf(stderr, "sendto failed\n");
        exit(1);
    }

    printf("send success\n");

    exit(0);
}

当客户端和服务器在本地时,它可以正常工作。 如“./server 21151”和“./client 127.0.0.1 21151”。 服务器将获得:

client ip: 127.0.0.1, client port: 21152
send success

客户会得到:

send success
receive success: hello from serverB
from 127.0.0.1:21151

但是当我将 ip 更改为公共 ip 时,客户端无法得到响应 从服务器。 客户端将在函数 recvfrom 处停止。

有什么想法吗?

【问题讨论】:

    标签: sockets udp


    【解决方案1】:

    让我猜猜 - 你是在 Mac 上运行它并且防火墙是打开的?默认过滤规则将允许发送 UDP 并接收响应(客户端),但不允许在打开的套接字(服务器)上接收未经请求的数据报。

    否则您的代码很好,尽管您不一定需要bind(2) 套接字的客户端。内核将为源分配下一个可用的高编号端口。如果您计划在给定客户端和服务器之间进行任何扩展对话,则可以考虑在客户端上使用 connect(2)

    您还总是希望明确地零终止从网络接收到的字符串。不这样做是无穷无尽的远程攻击的根源。

    【讨论】:

    • 谢谢。是的,我在 Mac 上运行它。我想写一个 udp 打孔示例。所以我绑定了套接字的客户端。如何实现?
    • 使用函数connect可以实现吗?
    • 通过connect()-ing UDP 套接字,您不必在每个send() 上使用目标地址,并在recv() 上设置过滤器,因此您只能从“已连接”获取数据报同行。
    • 我保存了客户端ip和端口,可以在新进程中连接客户端吗?
    • 连接 - 没有。你可以sendto()那个IP/端口。
    猜你喜欢
    • 2019-01-28
    • 2018-05-23
    • 2013-01-03
    • 1970-01-01
    • 2014-10-28
    • 1970-01-01
    • 2016-07-10
    • 2021-01-23
    • 1970-01-01
    相关资源
    最近更新 更多