【问题标题】:Problems while setting up a simple UDP server设置简单 UDP 服务器时的问题
【发布时间】:2012-07-14 06:51:58
【问题描述】:

我正在使用 C 进行套接字编程,但我有一个问题 - 我敢肯定 - 它来自我的困惑:如何使用 getaddrinfo() 设置服务器,以及如何从客户那里获得它的地址?我正在使用 UDP。

(我来自Beej's tutorial,但我还是不明白)

这是我的服务器的代码(我试图在 mhgc.net 和端口 3051 上运行它,虽然我还没有找到设置...主机名的方法?抱歉,我很困惑):

int sockd;

/* Get my IP address */
struct addrinfo hints, * servinfo;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;  // use my own address
if( getaddrinfo(NULL, "3051", &hints, &servinfo) != 0 ) {
    /* Yes, below is not... 'pretty code'; this is just an attempt */
    errorf("Failed to get server address: %s", gai_strerror( getaddrinfo(NULL, "3051", &hints, &servinfo) ));
    exit(EXIT_FAILURE);
    return 1;
}

struct addrinfo * p = NULL;
for(p = servinfo; p != NULL; p = p->ai_next) {
    if( (sockd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1 ) {
        perror("Cannot open socket");
        continue;
    }

    if(bind(sockd, p->ai_addr, p->ai_addrlen) == -1) {
        close(sockd);
        perror("Cannot bind to port");
        continue;
    }

    break;
}

if(p == NULL) {
    error("listener: failed to bind socket");
    exit(EXIT_FAILURE);
    return 0;
}

freeaddrinfo(servinfo);

struct sockaddr_storage clientinfo;
socklen_t clientinfo_len = sizeof(clientinfo);

char buffer[15];
memset(buffer, 0, sizeof(buffer));
if( recvfrom(sockd, buffer, sizeof(buffer), 0, (struct sockaddr *)&clientinfo, &clientinfo_len) == -1 ) {
    perror("Error receiving packet");
    exit(EXIT_FAILURE);
    return 0;
}

char s[INET6_ADDRSTRLEN];
printf("listener: got packet from %s\n", inet_ntop(clientinfo.ss_family, get_in_addr((struct sockaddr *)&clientinfo), s, sizeof(s)));
printf("listener: packet contains \"%s\"\n", buffer);

/* Close the socket descriptor */
close(sockd);

    /* And now, exit, or whatever I need ... ... ... */

对于我的客户:

int sockd;

struct addrinfo hints, * servinfo;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
//hints.ai_flags = AI_CANONNAME;
if( getaddrinfo(MKS_HOSTNAME, "www", &hints, &servinfo) != 0 ) {
    errorf("Failed to get server address: %s", gai_strerror( getaddrinfo(NULL, "3051", &hints, &servinfo) ));
    return 1;
}

struct addrinfo * p = NULL;
for(p = servinfo; p != NULL; p = p->ai_next) {
    if((sockd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
        perror("Cannot open socket");
        continue;
    }

    break;
}

if(p == NULL) {
    error("talker: failed to bind socket");
    return 2;
}

if( sendto(sockd, "this-is-a-test", strlen("this-is-a-test")+1, 0, p->ai_addr, p->ai_addrlen) == -1 ) {
    perror("Error sending packet");
    return 1;
}

freeaddrinfo(servinfo);

close(sockd);

errorerrorf 是帮助我调试应用程序的宏。不用担心他们。

另一个提示,如果您允许我的话:Beej 教程中的talker.c 使用主机名来“查找”服务器。我下载了 listener.c 和talker.c,编译了它(make listener && maketalker)但是,我不知道要传递什么作为talker 参数。侦听器的主机名是什么?我怎样才能找到它?再次抱歉。我真的很困惑:S

使用 gcc 编译器 v4.4.5 处理 Debian GNU/Linux “挤压”

【问题讨论】:

    标签: c sockets


    【解决方案1】:

    在服务器上,如果您不想监听特定地址,只需传递any 地址(所有地址元素设置为零)。您致电getaddrinfo 以获取本地地址永远不会给您一个合理的答案。将service 参数设置为NULL,因为您想知道主机的IP 地址,而不是服务的名称。

    要将客户端连接到服务器,请使用服务器的 IP 地址(在服务器上执行 /sbin/ifconfig 并搜索客户端可访问的地址)或主机名(即在服务器上执行 hostname服务器并在客户端上使用该名称来连接服务器)。

    【讨论】:

    • 谢谢!昨天晚上我终于拿到了,我睡得很开心:)。我的计算机的 DNS 域名存在“问题”(不是代码/防火墙问题),因此,当我将其作为 getaddrinfo() 的第一个参数传递时,...找主人。我输入了我机器的“总”IP 地址……然后得到它!再次感谢您的回答
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    • 2010-10-21
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2015-06-16
    • 2012-10-24
    相关资源
    最近更新 更多