2016-03-07 100 views
2

我想开发一个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服务器上工作得很好。

任何想法可能会造成这种情况?未封闭的端口,内存泄漏?我该如何解决?

+0

'fflush(stdin);'调用*未定义的行为*,所以不要使用它。 – MikeCAT

+0

'printf(“%s”,buf);'也可能调用*未定义的行为*如果buf中的内容不是以null结尾的字符串。在打印之前正确终止“字符串”,或以其他方式打印。 – MikeCAT

+0

以前,我的程序被困在无法读取数据,所以我不得不强制清理标准输入缓冲区。任何更好的选择? – ExtremistEnigma

回答

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); 
    
  • 服务器代码应该空终止从客户机接收到的缓冲液:

    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); 
        } 
    } 
    
  • 客户端和服务器都应该优雅地处理文件和系统调用失败的结束。

0

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

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