-1

我需要做简单的客户端程序,当我添加端口号时,客户端将搜索该端口的所有服务。现在是 if 语句中的分段错误问题。如何退回所有服务?我想在我的程序中它只会返回一个。

我的代码:

   int main (int argc, char *argv[])
{
    int sockfd, n,pol, s;
    int numer;
    char recvline[MAXLINE +1];
    char  p;
    struct sockaddr_in servaddr;
    struct servent *sp;

    if (argc != 3)
        err_sys("Aby uruchomić podaj: klient <Adres IP> <port>");

    s = atoi(argv[2]);
    if((sp = getservbyport(s,NULL)) == NULL)
        {
            printf("port (s): %d \n", s);
            printf("port (sp): %d \n", sp->s_port); //segmentation fault
            err_sys("problem with port");   
        }

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0))<0)
        err_sys("Blad utworzenia polaczenia");
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = sp->s_port;
    if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr)<=0)
        err_sys_kom("Blad konwersji do adresu IP dla %s", argv[1]);

    printf("%s", sp->s_name);
    pol = connect(sockfd, (SA*) &servaddr, sizeof(servaddr));
    if (pol < 0)
       {
          err_sys_kom("Blad polaczenie z serwerem");
          close(sockfd);
          exit(-1);
       }
    else
        str_cli(stdin, sockfd , 1);

exit(0);
}
4

1 回答 1

2

编辑(针对新的新问题- 请参阅下面的评论):

您可能需要获取协议列表并循环使用这些协议。循环的内容大致应该是:

  1. 称呼getprotoent
  2. 如果结果为 NULL,则退出循环。
  3. 否则,从返回的结构中挖掘出协议名称。
  4. 使用该名称作为第二个参数getservbyport
  5. 用结果做你想做的事

编辑(针对新问题):

if((sp = getservbyport(s,NULL)) == NULL)

所以你的逻辑是只读spIF spis NULL。显然它会出现段错误。

它应该是:

if((sp = getservbyport(s,NULL)) != NULL)

但是你会指出另一个新问题

为什么是spNULL?

这可能是因为(根据我的答案的早期版本),您做了一个不是整数的atoi东西。这可能是因为任何其他原因。我们不能说,因为我们不知道你给出了什么意见。


答案的以下部分是针对OP 在同一个问题中提出的一个问题,并从那时起选择对其进行编辑:

首先:既然你正在使用getservbyport,你真的应该阅读services,如果你还没有的话。

现在到错误:

getservbyport是类型:

struct servent *getservbyport(int port, const char *proto);

您正在传递argv[2]which 是 typechar *而不是intfor port

我相信用户在你的程序中输入这个作为参数?

如果您知道achar *指向一组看起来像整数的字符,例如“1024”,那么您可以使用 将其转换为整数atoi

而是在出现错误的情况下,在调用时执行此操作getservbyport,同时确保您已包含stdlib.h

getservbyport(atoi(argv[2]),NULL)

如果argv[2]不能表示为整数,您将获得未定义的行为,因此您可能需要先检查一下。

于 2012-06-06T09:36:50.700 回答