【问题标题】:C UDP client server not workingC UDP 客户端服务器不工作
【发布时间】:2018-06-29 18:22:05
【问题描述】:

所以我有一个 UDP 服务器,它使用以下代码向客户端返回小时或日期:

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#include <time.h>

void main(int argc, char *argv[]) {
    struct addrinfo hints;
    struct addrinfo *res;
    struct sockaddr_storage cli;
    time_t rawtime;
    struct tm* timeinfo;
    char tbuffer[9];
    char buf[81], host[NI_MAXHOST], serv[NI_MAXSERV];

    hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
    hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
    hints.ai_flags = AI_PASSIVE;    /* For wildcard IP address */
    hints.ai_protocol = 0;          /* Any protocol */

    getaddrinfo(argv[1], argv[2], &hints, &res);
    int sd = socket(res->ai_family, res->ai_socktype, 0);
    bind(sd, (struct sockaddr *)res->ai_addr, res->ai_addrlen);
    freeaddrinfo(res);

    while(1) {
        socklen_t clen = sizeof(cli);
        int c = recvfrom(sd, buf, 80, 0, (struct sockaddr*) &cli, &clen);
        buf[c] = '\0';
        getnameinfo((struct sockaddr*) &cli, clen, host, NI_MAXHOST, serv, NI_MAXSERV, NI_NUMERICHOST);
        time(&rawtime);
        timeinfo = localtime(&rawtime);
        if(buf[0] == 't') {
                printf("%ld bytes de %s:%s\n", c, host, serv);
                ssize_t chars = strftime(tbuffer, sizeof(tbuffer), "%T", timeinfo);
                sendto(sd, tbuffer, chars, 0, (struct sockaddr *)&cli, clen);
        } else if(buf[0] == 'd') {
                printf("%ld bytes de %s:%s\n", c, host, serv);
                ssize_t chars = strftime(tbuffer, sizeof(tbuffer), "%D", timeinfo);
                sendto(sd, tbuffer, chars, 0, (struct sockaddr *)&cli, clen);
        } else if(buf[0] == 'q') {
                printf("Saliendo...\n");
                exit(EXIT_SUCCESS);
        } else {
                printf("Comando no soportado %s", buf);
        }
    }
}

为了测试我在服务器端使用./server &lt;IPServerAddres&gt; &lt;PortAddress&gt; 和在客户端(另一台机器)上使用nc -u &lt;IpServerAddress&gt; &lt;PortServer&gt; 的代码。

现在我想创建 UDP 客户端 UDP 并在不使用 nc 的情况下执行相同的操作,只需编写 ./client &lt;IPServerAddres&gt; &lt;PortAddress&gt; &lt;command&gt; 其中 command 可以是 t 时间 d 用于日期,q 用于退出,就像在服务器中一样。

这是客户端程序的代码:

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#include <time.h>

int main(int argc, char *argv[]) {
    struct addrinfo hints;
    struct addrinfo *res, *resp;
    int sd, j, s;
    size_t len;
    ssize_t nread, nwrite;
    char buf[500];

    if (argc < 3) {
        fprintf(stderr, "Usage: %s host port command...\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
    hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
    hints.ai_flags = 0;
    hints.ai_protocol = 0;          /* Any protocol */

    getaddrinfo(argv[1], argv[2], &hints, &res);

    for(resp = res; resp != NULL; resp = resp->ai_next) {
        sd = socket(resp->ai_family, resp->ai_socktype, resp->ai_protocol);
        if(sd == -1) {
            perror("socket()");
            continue;
        }

        if(connect(sd, resp->ai_addr, resp->ai_addrlen) == -1) {
            perror("socket()");
        } else {
            break;
        }

        close(sd);
    }

    freeaddrinfo(res);

    for(j = 3; j < argc; j++) {
        len = strlen(argv[j]) + 1;
        nwrite = write(sd, argv[j], len);
        if(nwrite == -1) perror("write()");
        nread = read(sd, buf, 500);
        buf[nread] = 0;
        if(nread == -1) perror("read()");
        printf("Recibidos %ld bytes: %s\n", (long) nread, buf);
    }

    exit(EXIT_SUCCESS);
}

问题是,当我尝试运行我的客户端程序时,我没有得到任何响应,所以我猜是处于无限循环或类似情况。

任何帮助将不胜感激,我正在学习 C,所以对于错误我深表歉意,谢谢。

已编辑:更正了 for 循环中的 break,以防 connect() 返回不同于 -1 的值。

【问题讨论】:

  • for循环之后检查resp是否为NULL。
  • 我添加了if(resp == NULL) { fprintf(stderr, "Could not connect\n"); exit(EXIT_FAILURE); },但出现错误“无法连接”,这是为什么呢?
  • 您需要查看从getaddrinfo 返回的地址(如果有)。您还可以检查getaddrinfo 的返回码并将任何非零返回值传递给gai_strerror 以获取错误字符串。
  • 我现在检查getaddrinfo 的返回值,如果for 循环是错误的,我已经更改了break 的情况,以防connect 返回不同于-1 的值然后循环中断。经过这些更改后,我运行程序时一无所获,它似乎陷入了无限循环......

标签: c linux server udp client


【解决方案1】:

问题在于您计算要发送的消息的长度:

len = strlen(argv[j] + 1);

这将获取字符串的长度从第二个字符开始。你想要:

len = strlen(argv[j]) + 1;

这将为您提供字符串长度加 1 作为空终止符。

此外,在阅读响应后,您需要对返回的内容进行空终止:

buf[nread] = 0;

【讨论】:

  • 这是真的,谢谢,我已经改变了计算问题和缓冲区空终止,但它一直作为一个无限循环执行,我不知道为什么......我已经编辑了带有最新版本客户端程序的帖子,以防您看到更多内容。
猜你喜欢
  • 1970-01-01
  • 2010-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-09
相关资源
最近更新 更多