C UDP客户端服务器不起作用

时间:2018-06-29 18:22:05

标签: c linux server udp client

所以我有一台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 <IPServerAddres> <PortAddress>在客户端(另一台计算机)上使用nc -u <IpServerAddress> <PortServer>的代码。

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

这是客户端程序的代码:

q

问题在于,当我尝试运行客户端程序时,我没有任何响应,因此我想它处于无限循环或类似的状态。

任何帮助将不胜感激,我正在学习C,所以对我的错误感到抱歉,谢谢。

已编辑:更正了#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); } 循环中的break,以防for返回不同于-1的情况。

1 个答案:

答案 0 :(得分:1)

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

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

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

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

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

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

buf[nread] = 0;