UDP套接字 - 服务器未接收任何数据

时间:2016-03-07 00:58:24

标签: c linux sockets ubuntu udp

我正在尝试开发UDP客户端 - 服务器程序。这是我的代码:

服务器

int main(int argc, char *argv[]) {
    struct sockaddr_in client, server;
    int s, i=0;
    socklen_t n;
    char buf[4];
    s=socket(AF_INET,SOCK_DGRAM,0);
    server.sin_family=AF_INET;
    server.sin_port=atoi(argv[1]);
    inet_pton(AF_INET, "localhost", &(server.sin_addr));
    bind(s,(struct sockaddr *)&server,sizeof(server));
    n=sizeof(client);

    while(1) {
        recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&client, &n);
        printf("%s", buf);
    }
    close(s);
    return 0;
}

客户端

int main (int argc, char *argv[]) {
    struct sockaddr_in client, server;
    int s, n;
    char buf[30];
    char temp[4];
    s=socket(AF_INET,SOCK_DGRAM,0);
    server.sin_family=AF_INET;
    server.sin_port=atoi(argv[2]);
    inet_pton(AF_INET, argv[1], &(server.sin_addr));

    n=sizeof(server);

    while(1) {
        scanf("%s", buf);
        fflush(stdin);
        sendto(s, buf, sizeof(buf), 0, (struct sockaddr *) &server, n);
    }
    close(s);
    return 0;
}

性质相当基本,没有任何错误处理。服务器输出客户端发送的任何内容。

在我测试时忘记删除/释放动态分配的内存后,它停止在我的Ubuntu机器上工作。它在不同的Linux服务器上运行良好。

知道可能导致这种情况的原因是什么?未封闭的端口,内存泄漏?我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

您的方法存在问题:

  • fflush(stdin);调用未定义的行为。如果您想要阅读并丢弃用户输入的其余行,请使用:

    scanf("%*[^\n]");  /* consume all remaining chars on the line, if any */
    scanf("%*c");      /* consume the linefeed if any */
    
  • 客户端代码应该只发送字符串,可能带有分隔符,但不是完整缓冲区,其中部分未初始化:

    sendto(s, buf, strlen(buf), 0, (struct sockaddr *)&server, n);
    
  • 服务器代码应该为null终止从客户端收到的缓冲区:

    while(1) {
        ssize_t nr = recvfrom(s, buf, sizeof(buf) - 1, 0, (struct sockaddr *)&client, &n);
    
        if (nr >= 0) {
            buf[nr] = '\0';
            printf("%s", buf);
        }
    }
    
  • 客户端和服务器都应该正常处理文件结束和系统调用失败。

答案 1 :(得分:0)

首先,正如@kaylum所提到的,你需要检查错误。除此之外,我看到了几个问题:

  • inet_pton()不会将主机名转换为地址。通常,你 不想绑定到服务器端的特定IP地址 无论如何;相反,将其设置为INADDR_ANY。在客户端,127.0.0.1将用于发送到同一台计算机上的服务器。
  • 您需要将端口号转换为网络字节顺序 htons()
  • 您正在发送30个字节,但您的接收缓冲区只有4个字节长。 有人提到你不应该发送整个30字节 缓冲区,但这取决于您和您的协议。你必须是 能够处理发送的任何内容。
  • 正如其他人所说,fflush(stdin)不正确;使用fflush() 用于刷新输出,但stdin是输入文件。
  • scanf("%s", buf)不会将输入限制为缓冲区的大小, 这可能会导致问题。请改用fgets()