BSD C Bind() 到 UDP 挂起的套接字

发布于 2024-12-09 03:24:17 字数 3928 浏览 0 评论 0原文

每个人。我正在做关于使用 UDP 构建 whois 服务的硬件。但是,当我执行代码时遇到问题。

这是我的代码:

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pwd.h>
#include <arpa/inet.h>
#include <string.h>

/*
 * Program:     whoisserver
 *
 * Purpose:     UNIX application program act as a server for the "whois" 
 *              service on the local machine.               
 *
 * Usage:       whois hostname username
 */

#define MSG_LEN         1024
void whois(int sock);

int main(int argc,char *argv[]){

    int s;  /* Socket descriptors */
    struct sockaddr_in local_addr;
    struct hostent *hp;

    char *myname;
    myname = argv[0];// copy program name to name
    printf("This is program: %s \n", myname);


    /*
     *  Create a socket
     *  Address Family (AF_INET)
     *  UDP (SOCK_DGRAM)
     */
    printf("-Allocating socket for incomming connections...\n");
    if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
        perror("socket");
        exit(1);
    }


    /*
      Set Up local Address
          address_family (AF_INET)
          IP address (INADDR_ANY) ?
          port number (use 6087 by default)
    */
    local_addr.sin_port = 54020;
    local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    local_addr.sin_family = AF_INET;


    /*
      Bind the socket to the service port
    */

    printf("-Binding Service to Socket...\n");
    int n = bind(s, (struct sockaddr *)&local_addr, sizeof local_addr);
    if(n <0){
        perror("bind");
        printf("Problem in binding\n");
        exit(1);
    }

    printf("-Waiting for incomming connection...");
    whois(s);// Call whois 
    return(0);

}

/*
    whois function
    param: int s
           Socket Descriptor
*/

void whois(int sock){
     int len, t;
     char bufin[MSG_LEN];

     struct sockaddr_in remote_addr;

     // Get the size of remote address     
     len = sizeof(remote_addr);


     // Infinity loop

     while(1){
        struct passwd *p;

        // recvfrom while waiting for new customers
        if((t = recvfrom(sock, bufin, MSG_LEN, 0,
         (struct sockaddr *) &remote_addr, &len))<0){
            perror("recvfrom");     
            exit(0);        
        }
        bufin[t] = '\0'; // end of string

        if((p = getpwnam(bufin)) == NULL)
              strcpy(bufin, "-- This is the result from Gang's server ---\nUser not found\n");
        else{
             /*Find passwd in pwd.h file. Here is the structure:

               struct passwd {
                    char    *pw_name;
                    char    *pw_passwd;
                    uid_t   pw_uid;
                    gid_t   pw_gid;
                    char    *pw_age;
                    char    *pw_comment;
                    char    *pw_gecos;
                    char    *pw_dir;
                    char    *pw_shell;
               };
               */   

         // Print out all the field
         sprintf(bufin, "-- This is the result from Gang's server ---\nUsername: %s\nPassword: %s\nAge: %s\nUID: %d\nGID: %d\nGECOS: %s\nDIR: %s\nSHELL: %s\nComment: %s\n",
              p->pw_name, 
              p->pw_passwd,
              p->pw_age,
              p->pw_uid,
              p->pw_gid,
              p->pw_gecos,
              p->pw_dir,
              p->pw_shell,
              p->pw_comment
              );
         }
         sendto(sock, bufin, strlen(bufin), 0, (struct sockaddr *)&remote_addr, len);
     }        
}

程序在套接字的绑定地址处停止。这是输出:

{506}paradox:client_server$ a.out
This is program: a.out
-Allocating socket for incomming connections...
-Binding Service to Socket...
^Z
[1]+  Stopped                 a.out

我不知道原因是什么。顺便说一下,我使用的是 gcc 3.4.3。我也在 Mac 和 Ubuntu 上尝试过。相同的结果。

everyone. I was doing my hw about use UDP to build a whois service. Howver I encounter a problem when I execute my code.

Here is my code:

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pwd.h>
#include <arpa/inet.h>
#include <string.h>

/*
 * Program:     whoisserver
 *
 * Purpose:     UNIX application program act as a server for the "whois" 
 *              service on the local machine.               
 *
 * Usage:       whois hostname username
 */

#define MSG_LEN         1024
void whois(int sock);

int main(int argc,char *argv[]){

    int s;  /* Socket descriptors */
    struct sockaddr_in local_addr;
    struct hostent *hp;

    char *myname;
    myname = argv[0];// copy program name to name
    printf("This is program: %s \n", myname);


    /*
     *  Create a socket
     *  Address Family (AF_INET)
     *  UDP (SOCK_DGRAM)
     */
    printf("-Allocating socket for incomming connections...\n");
    if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
        perror("socket");
        exit(1);
    }


    /*
      Set Up local Address
          address_family (AF_INET)
          IP address (INADDR_ANY) ?
          port number (use 6087 by default)
    */
    local_addr.sin_port = 54020;
    local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    local_addr.sin_family = AF_INET;


    /*
      Bind the socket to the service port
    */

    printf("-Binding Service to Socket...\n");
    int n = bind(s, (struct sockaddr *)&local_addr, sizeof local_addr);
    if(n <0){
        perror("bind");
        printf("Problem in binding\n");
        exit(1);
    }

    printf("-Waiting for incomming connection...");
    whois(s);// Call whois 
    return(0);

}

/*
    whois function
    param: int s
           Socket Descriptor
*/

void whois(int sock){
     int len, t;
     char bufin[MSG_LEN];

     struct sockaddr_in remote_addr;

     // Get the size of remote address     
     len = sizeof(remote_addr);


     // Infinity loop

     while(1){
        struct passwd *p;

        // recvfrom while waiting for new customers
        if((t = recvfrom(sock, bufin, MSG_LEN, 0,
         (struct sockaddr *) &remote_addr, &len))<0){
            perror("recvfrom");     
            exit(0);        
        }
        bufin[t] = '\0'; // end of string

        if((p = getpwnam(bufin)) == NULL)
              strcpy(bufin, "-- This is the result from Gang's server ---\nUser not found\n");
        else{
             /*Find passwd in pwd.h file. Here is the structure:

               struct passwd {
                    char    *pw_name;
                    char    *pw_passwd;
                    uid_t   pw_uid;
                    gid_t   pw_gid;
                    char    *pw_age;
                    char    *pw_comment;
                    char    *pw_gecos;
                    char    *pw_dir;
                    char    *pw_shell;
               };
               */   

         // Print out all the field
         sprintf(bufin, "-- This is the result from Gang's server ---\nUsername: %s\nPassword: %s\nAge: %s\nUID: %d\nGID: %d\nGECOS: %s\nDIR: %s\nSHELL: %s\nComment: %s\n",
              p->pw_name, 
              p->pw_passwd,
              p->pw_age,
              p->pw_uid,
              p->pw_gid,
              p->pw_gecos,
              p->pw_dir,
              p->pw_shell,
              p->pw_comment
              );
         }
         sendto(sock, bufin, strlen(bufin), 0, (struct sockaddr *)&remote_addr, len);
     }        
}

The program stops at bind address to socket. Here is the output:

{506}paradox:client_server$ a.out
This is program: a.out
-Allocating socket for incomming connections...
-Binding Service to Socket...
^Z
[1]+  Stopped                 a.out

I can't figure out what's the reason. By the way, I am using gcc 3.4.3. And I also tried it in Mac and Ubuntu. Same result.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

扛刀软妹 2024-12-16 03:24:17

似乎停止的原因是因为默认情况下标准输出是行缓冲的,并且此消息末尾没有换行符:

printf("-Waiting for incomming connection...");

添加 \n到该消息的末尾,您可能会发现它在 recvfrom() 调用处阻塞。

The reason it appears to stop is because standard output is line-buffered by default, and you don't have a newline at the end of this message:

printf("-Waiting for incomming connection...");

Add a \n to the end of that message and you will likely find that it is blocking at the recvfrom() call.

痕至 2024-12-16 03:24:17

有几件事您应该更改:

  • 在设置 local_addr 的成员之前,尝试 memset(&local_addr, 0, sizeof(local_addr)); 这样您就可以确保所有内容都已正确初始化。
  • 设置端口时,请使用 local_addr.sin_port = htons(54020); 端口还必须符合网络顺序。

There's a couple things you should change:

  • Before setting the members of local_addr, try memset(&local_addr, 0, sizeof(local_addr)); That way you're sure that everything is appropriately initialized.
  • When setting the port, use local_addr.sin_port = htons(54020); The port also must be in network order.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文