简体   繁体   中英

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. I'm working on a linux cluster, at my school.

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.

 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.

The output of this code is

89.16.176.16
con fail -1

Alternatively, I've also used the addrinfo struct, to no avail:

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 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 .

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! Also, you don't use the servAddr properly. 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

Also, I suggest you try using Strace - it's exceptionally useful when you want to check quickly what's going on.

Edit: I can see one more bug - free() should be called regardless of connect() result, you are leaking memory here. And again, a tool hint: Valgrind

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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