简体   繁体   English

即使服务器可通过telnet访问,TCP connect()(在C中)也始终失败

[英]TCP connect() (in C) always fails, even when the server is telnet accessible

I'm trying to create a program that monitors an IRC server, and I'm having trouble even with the basics of connecting. 我正在尝试创建一个监视IRC服务器的程序,即使在基本连接方面也遇到了麻烦。 I'm working on a linux cluster, at my school. 我在学校正在研究Linux集群。

I simply don't know what I'm doing wrong. 我根本不知道我在做什么错。 Here's my code, copied almost verbatim from TCP IP Sockets in C, Chapter 2. 这是我的代码,几乎完全从C第2章的TCP IP套接字复制而来。

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

      char *servName = "irc.freenode.net";
      in_port_t servPort = 6667;

      //Start populating server information into a sockaddr
      struct sockaddr_in servAddr;
           memset(&servAddr, 0, sizeof(servAddr));

           //To get the IP address of irc.freenode.net
               //Using gethostbyname
           char servIP[16];
           struct hostent *hent;
           hent = gethostbyname(servName);
           inet_ntop(AF_INET, (void *)hent->h_addr_list[0],servIP,16);         

           //Convert the IP address's endianness
           int rtnVal = inet_pton(AF_INET, servIP, &servAddr.sin_addr.s_addr);
           if(rtnVal <= 0)
                dieMsg("inet fail",rtnVal);

           servAddr.sin_port = htons(servPort);
           servAddr.sin_family = AF_INET;
           printf("%s\n",servIP);
      //End server information

      //Open a socket to use
      int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);          
      if(sock<0)
           dieMsg("sock fail",sock);

      //Connect using the sock, and the populated sockaddr struct.
      if(connect(sock,(struct sockaddr*) &servAddr, sizeof(servAddr))<0);
      {
           dieMsg("con fail",-1);
      }

      return 0;
 }

dieMsg is a function that takes a string and an int, prints them, and then exits. dieMsg是一个函数,该函数需要一个字符串和一个int,打印它们,然后退出。

The output of this code is 此代码的输出是

89.16.176.16
con fail -1

Alternatively, I've also used the addrinfo struct, to no avail: 另外,我也使用了addrinfo结构,但无济于事:

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

     char *servHostc = "irc.freenode.net";
     char *servPortc = "6667";

     struct addrinfo addrCriteria;
     memset(&addrCriteria, 0, sizeof(addrCriteria));
     addrCriteria.ai_family = AF_INET;
     addrCriteria.ai_socktype = SOCK_STREAM;
     addrCriteria.ai_protocol = IPPROTO_TCP;

     struct addrinfo *servAddr;
     int rtnVal = getaddrinfo(servHostc,servPortc, &addrCriteria, &servAddr);
     if(rtnVal != 0)
          dieMsg("getaddrinfo() connect fail", rtnVal);

     int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

     if(connect(sock, (struct sockaddr*) &servAddr, sizeof(servAddr) < 0))
     {
          free(servAddr);
          dieMsg("Connect failed",-1);
     }

     return 0;
}

Telnet works for both addresses, so it's not my internet connection. Telnet适用于两个地址,因此不是我的Internet连接。

$ telnet irc.freenode.net 6667
Trying 128.237.157.136...
Connected to irc.freenode.net (128.237.157.136).
Escape character is '^]'.
:hubbard.freenode.net NOTICE * :*** Looking up your hostname...
:hubbard.freenode.net NOTICE * :*** Checking Ident
:hubbard.freenode.net NOTICE * :*** Found your hostname
^]
telnet> Connection closed.
$ telnet 89.16.176.16 6667
Trying 89.16.176.16...
Connected to wolfe.freenode.net (89.16.176.16).
Escape character is '^]'.
:wolfe.freenode.net NOTICE * :*** Looking up your hostname...
:wolfe.freenode.net NOTICE * :*** Checking Ident
:wolfe.freenode.net NOTICE * :*** Found your hostname
^]
telnet> Connection closed.

I usually hate asking questions, so this is my last resort. 我通常不喜欢问问题,所以这是我的不得已。 If anyone can please please shed some light on my predicament, I will be so grateful. 如果有人可以,请向我阐明一下我的困境,我将非常感激。

  if(connect(sock,(struct sockaddr*) &servAddr, sizeof(servAddr))<0);
  {
       dieMsg("con fail",-1);
  }

; at the end of if . if的末尾。

The second code sample is also buggy. 第二个代码示例也是错误的。 The line: 该行:

 if(connect(sock, (struct sockaddr*) &servAddr, sizeof(servAddr) < 0))

Can you see? 你知道吗? You are comparing sizeof() to zero, not the connect() result! 您正在比较sizeof()为零,而不是connect()结果! Also, you don't use the servAddr properly. 另外,您没有正确使用servAddr Try replacing this line with (again, it works for me after the change): 尝试将其替换为(再次,更改后对我有用):

 if(connect(sock, servAddr->ai_addr, servAddr->ai_addrlen) < 0)

Also note, that servAddr is in fact a linked list, see this sample: http://www.geekpage.jp/en/programming/linux-network/getaddrinfo-3.php 还要注意, servAddr实际上是一个链表,请参见以下示例: http : //www.geekpage.jp/en/programming/linux-network/getaddrinfo-3.php

Also, I suggest you try using Strace - it's exceptionally useful when you want to check quickly what's going on. 另外,我建议您尝试使用Strace-当您想快速查看发生了什么时,它特别有用。

Edit: I can see one more bug - free() should be called regardless of connect() result, you are leaking memory here. 编辑:我可以看到另一个bug-无论connect()结果如何,都应调用free() ,这是在泄漏内存。 And again, a tool hint: Valgrind 再次,一个工具提示: Valgrind

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM