C++的Socket连接错误
我已经更改我下面什么看到的,这是我
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string>
#include <vector>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <errno.h>
using namespace std;
string buffer;
vector<string> ex;
int s;
void recvline (int s, string* buf) {
char in, t;
while (1) {
recv (s, &in, 1, 0);
*buf += in;
if (in == 10) {
t = 1; }
if (t && in == 13) {
break; }
}
}
void push (int s, string msg) {
string o = msg + "\r\n";
cout << "SENT:", o;
send (s, o.c_str(), o.size(), 0);
}
int main (int argc, char *argv[]) {
if (argc < 3) {
cout << "Insufficient Arguments" << endl;
exit (7); }
s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s < 0)
exit (1);
struct hostent h = *gethostbyname (argv[1]);
struct sockaddr_in c;
c.sin_family = AF_INET;
c.sin_port = htons(atoi(argv[2]));
c.sin_addr.s_addr = inet_addr (h.h_addr_list[0]);
if (connect (s, (struct sockaddr*)&c, sizeof c) != 0) {
cout << "Unable to connect to network" << endl;
cout << strerror(errno) << endl;
exit (2);
}
push (s, "USER LOLwat Lw lol.wat :LOLwat");
push (s, "NICK LOLwat");
while (true) {
recvline (s, &buffer);
cout << buffer;
if (buffer.substr(0,4).c_str() == "PING")
push (s, "PONG " + buffer.substr(6,-2));
}
}
这是结果:
[[email protected] Desktop]$ g++ ?.cpp -o 4096 -
[[email protected] Desktop]$ ./4096 irc.scrapirc.com 6667 - Unable to connect to network - Network is unreachable
我认为问题在于这一行:
c.sin_port = htons(*argv[2]);
是不是在做你认为它在做的事情。 argv[2]
是一个字符串,*argv[2]
是该字符串的第一个字符。所以如果你通过“4567”作为第二个命令行参数,那么*argv[2]
将是'4',它的ASCII值为52.这意味着你将试图连接到端口52,而不是你所期望的那样连接到“4567”。
行更改为:
c.sin_port = htons(atoi(argv[2]));
的atoi函数采用一个串并将其转换成一个整数。因此,“4567”将成为4567
而且,在一般情况下,你应该在这样的一个函数调用失败检查errno
值(它通常会告诉你在the documentation是否将errno设置和可能的值,它可以被设置为)。这应该有助于在未来给你一些线索。
编辑
正如其他人所指出的,请务必注意你的牙套。如果您只需总是使用大括号if
,while
等等,通常会更容易。也就是说,这样的:
if (connect (s, (struct sockaddr*)&c, sizeof c) != 0)
cout << "Unable to connect to network" << endl;
exit (2);
与此完全不同:
if (connect (s, (struct sockaddr*)&c, sizeof c) != 0) {
cout << "Unable to connect to network" << endl;
exit (2);
}
我决定完全重做我的答案,部分原因是由于在gethostbyname
手册页的评论:
gethostbyname *()和 gethostbyaddr *()函数是 已过时。应用程序应该使用 getaddrinfo(3)和getnameinfo(3) 。
这是重做的程序(根据使用getaddrinfo
使用bcpp清理了一下)。我强烈建议总是与下列选项编译:
g++ -Wall -Wextra irc.cpp -o irc
这显示了以下错误在你的代码:
irc.cpp: In function ‘void push(int, std::string)’:
irc.cpp:40: warning: right-hand operand of comma has no effect
irc.cpp: In function ‘int main(int, char**)’:
irc.cpp:87: warning: comparison with string literal results in unspecified behaviour
我继续和修复错误。此外,尽可能尝试并消除全局变量。
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string>
#include <vector>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <errno.h>
using namespace std;
string buffer;
vector<string> ex;
void recvline (int s, string* buf)
{
char in, t;
while (1)
{
recv (s, &in, 1, 0);
*buf += in;
if (in == 10)
{
t = 1;
}
if (t && in == 13)
{
break;
}
}
}
void push (int s, string msg)
{
string o = msg + "\r\n";
cout << "SENT:" << o;
send (s, o.c_str(), o.size(), 0);
}
int main (int argc, char *argv[])
{
if (argc < 3)
{
cout << "Insufficient Arguments" << endl;
exit (7);
}
int s, sfd;
struct addrinfo *result, *rp;
s = getaddrinfo(argv[1], argv[2], NULL, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}
for (rp = result; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (sfd == -1)
continue;
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
break; /* Success */
close(sfd);
}
if (rp == NULL) { /* No address succeeded */
fprintf(stderr, "Could not connect\n");
exit(EXIT_FAILURE);
}
freeaddrinfo(result); /* No longer needed */
push (sfd, "USER LOLwat Lw lol.wat :LOLwat");
push (sfd, "NICK LOLwat");
while (true)
{
recvline (sfd, &buffer);
cout << buffer;
if (buffer.substr(0,4) == "PING")
push (sfd, "PONG " + buffer.substr(6,-2));
}
}
即使您的更改仍然存在问题。 h-> h_addr_list [0]返回B Z,inet_addr使它成为4294967295.不知道这意味着什么,只是把它扔到那里。 – dbdii407 2010-06-24 14:02:46
@ dbdii407:这是工作程序。我建议在C++编程方面写一本好书,比如Koenig的Accelerated C++。 – 2010-06-25 11:43:16
您应该检查'errno'的值来查看实际的错误是什么。 – 2010-06-23 04:26:31
另外,注意你的大括号 - 有一些地方缩进建议两行将一起执行,但他们不(例如,在无法连接到网络错误之后)。我建议使用自动缩进编辑器或其他东西。 – bdonlan 2010-06-23 04:27:54
*总是*使用花括号。 C不是Python。 – 2010-06-23 04:31:03