【问题标题】:Not Getting the output at the client side (UDP socket in C)未在客户端获取输出(C 中的 UDP 套接字)
【发布时间】:2020-07-22 05:31:40
【问题描述】:

这是我的 UDP 套接字服务器和客户端的代码。

问题是,当我在终端中运行它时,一旦客户端到达服务器,服务器执行就会停止,但在客户端我没有收到任何数据。

客户端.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
    int network_socket;

    network_socket = socket(AF_INET, SOCK_DGRAM, 0);

    struct sockaddr_in server_address;

    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9002);
    server_address.sin_addr.s_addr = INADDR_ANY;

    sendto(network_socket, 0, 0, MSG_CONFIRM, (const struct sockaddr *) &server_address, sizeof(server_address));
    char server_response[256];
    int len = sizeof(network_socket);
    int = recvfrom(network_socket, &server_response, sizeof(server_response), 0,(struct sockaddr*) &network_socket, (socklen_t*)&len);

    printf("The server sent the data : %s\n", server_response);

    close(network_socket);
    return 0;
}

服务器.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
    char server_message[256] = "you have reached the UDP server";

    int server_socket,client_address;
    server_socket = socket(AF_INET, SOCK_DGRAM,0);

    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9002);
    server_address.sin_addr.s_addr = INADDR_ANY;

    bind(server_socket, (struct sockaddr *) &server_address, sizeof(server_address));

    int n,len;
    len = sizeof(client_address);
    n = recvfrom(server_socket, server_message, sizeof(server_message), 0, (struct sockaddr *) &client_address, (socklen_t*)&len);

    sendto(server_socket, server_message, sizeof(server_message), 0, (struct sockaddr *) &client_address, len);
    close(server_socket);
    return 0;
}

【问题讨论】:

  • 这是我注意到的两件事。首先,您发送的是 0 字节消息。如果您将其更改为非零长度消息,它是否会有所不同。另外,您是否使用 Wireshark 之类的工具监控流量?服务器端可能存在防火墙问题,端口 9002 被阻止。
  • 客户端需要指定服务器的IP地址吗?
  • 关于:int = recvfrom(network_socket, &amp;server_response, sizeof(server_response), 0,(struct sockaddr*) &amp;network_socket, (socklen_t*)&amp;len); 这不会编译!在int 和= 之间需要有一个变量名。此外,recvfrom() 返回 ssize_t,而不是 int
  • 关于:int = recvfrom(network_socket, &amp;server_response, sizeof(server_response), 0,(struct sockaddr*) &amp;network_socket, (socklen_t*)&amp;len); 和 `printf("The server sent the data : %s\n", server_response );` 函数:recvfrom() 不为 NUL 终止数据读取,所以在这两个语句必须是语句:server_response[ &lt;returned value from recvfrom()&gt; ] = '\0';
  • 关于:server_address.sin_addr.s_addr = INADDR_ANY; INADDR_ANY 是字符串:“0.0.0.0”,不能直接赋值。建议:server_address.sin_addr.s_addr = htonl( INADDR_ANY );

标签: c linux sockets network-programming udp


【解决方案1】:
sendto(network_socket, 0, 0, MSG_CONFIRM, (const struct sockaddr *) &server_address, sizeof(server_address));

您没有发送任何数据。

int = recvfrom(network_socket, &server_response, sizeof(server_response), 0,(struct sockaddr*) &network_socket, (socklen_t*)&len);

printf("The server sent the data : %s\n", server_response);

您没有保留收到的字节数,这就是recvfrom 返回的内容。所以你不知道你收到了多少数据。然后您尝试通过%s 打印此数据,这仅 用于C 样式字符串。您不能使用它来打印任意数据。至少,您必须告诉它要打印多少数据(否则,它怎么可能知道?)然后您将这些信息扔掉了。

【讨论】:

  • "你没有发送任何东西" - 在 UDP 中,可以发送在其有效负载中包含 0 字节的数据报。在接收端,recvfrom() 的返回值为 0。
【解决方案2】:

在双方,您根本没有进行任何错误处理。

在客户端,你不能发送数据报到INADDR_ANY,你需要发送到一个真实的IP地址。而当调用recvfrom()时,你使用network_socket文件描述符作为sockaddr_in结构来接收发送者的地址/端口,这是错误的。

在服务器端,当 client_address 需要成为 sockaddr_in 结构时,您将其声明为 int。而且您正在使用相同的char[] 缓冲区来接收用于存储服务器问候消息的客户端数据,因此您实际上是在回显客户端发送的内容(这没什么),但您并没有占用客户的数据考虑在内。在recvfrom() 退出后,您在滥用printf(),因为客户端没有发送以null 结尾的字符串,但%s 需要一个。

试试这个:

客户端.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main()
{
    int network_socket = socket(AF_INET, SOCK_DGRAM, 0);
    if (network_socket < 0)
    {
        perror("socket() failed");
        return -1;
    }

    struct sockaddr_in server_address;

    bzero(&server_address, sizeof(server_address));
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9002);
    server_address.sin_addr.s_addr = inet_addr("Server IP Address Here"); // or "127.0.0.1" for localhost

    if (sendto(network_socket, 0, 0, MSG_CONFIRM, (struct sockaddr *) &server_address, sizeof(server_address)))
    {
        perror("sendto() failed");
        close(network_socket);
        return -1;
    }

    char server_response[256];

    struct sockaddr_in sender_address;
    socklen_t addrlen = sizeof(sender_address);

    int n = recvfrom(network_socket, server_response, sizeof(server_response), 0, (struct sockaddr*) &sender_address, &addrlen);
    // or, since you are not using the sender's sockaddr_in for anything:
    // int n = recvfrom(network_socket, server_response, sizeof(server_response), 0, NULL, NULL);
    if (n < 0)
    {
        perror("recvfrom() failed");
        close(network_socket);
        return -1;
    }

    printf("The server sent the data : %.*s\n", n, server_response);

    close(network_socket);
    return 0;
}

服务器.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main()
{
    char server_message[] = "you have reached the UDP server";

    int server_socket = socket(AF_INET, SOCK_DGRAM, 0);
    if (server_socket < 0)
    {
        perror("socket() failed");
        return -1;
    }

    struct sockaddr_in server_address;

    bzero(&server_address, sizeof(server_address));
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9002);
    server_address.sin_addr.s_addr = INADDR_ANY;

    if (bind(server_socket, (struct sockaddr *) &server_address, sizeof(server_address)) < 0)
    {
        perror("bind() failed");
        close(server_socket);
        return -1;
    }

    char client_message[256];

    struct sockaddr_in client_address;
    socklen_t addrlen = sizeof(client_address);

    int n = recvfrom(server_socket, client_message, sizeof(client_message), 0, (struct sockaddr *) &client_address, &addrlen);
    if (n < 0)
    {
        perror("recvfrom() failed");
        close(server_socket);
        return -1;
    }

    printf("The client sent the data : %.*s\n", n, client_message);

    if (sendto(server_socket, /*client_message*/server_message, /*n*/strlen(server_message), 0, (struct sockaddr *) &client_address, addrlen) < 0)
    {
        perror("sendto() failed");
        close(server_socket);
        return -1;
    }

    close(server_socket);
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-08
    • 2011-03-16
    • 2011-06-12
    • 2023-03-18
    • 2014-11-19
    • 2016-06-04
    • 1970-01-01
    相关资源
    最近更新 更多