[英]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.