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.