C++套接字连接错误
编辑 我已经改变了我在下面看到的,这就是我所拥有的C++套接字连接错误,c++,sockets,irc,C++,Sockets,Irc,编辑 我已经改变了我在下面看到的,这就是我所拥有的 #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 &
#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) );
}
}
我认为问题在于这一行:
c.sin_port = htons(*argv[2]);
不是在做你认为它在做的事。argv[2]是字符串,*argv[2]是字符串的第一个字符。因此,如果您将4567作为第二个命令行参数传递,那么*argv[2]将是具有ASCII值52的“4”。这意味着您将尝试连接到端口52,而不是预期的4567
将行更改为:
c.sin_port = htons(atoi(argv[2]));
函数接受字符串并将其转换为整数。所以4567会变成4567
另外,一般来说,当这样的函数调用失败时,您应该检查errno的值。它通常会告诉您是否设置了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 );
}
我认为问题在于这一行:
c.sin_port = htons(*argv[2]);
不是在做你认为它在做的事。argv[2]是字符串,*argv[2]是字符串的第一个字符。因此,如果您将4567作为第二个命令行参数传递,那么*argv[2]将是具有ASCII值52的“4”。这意味着您将尝试连接到端口52,而不是预期的4567
将行更改为:
c.sin_port = htons(atoi(argv[2]));
函数接受字符串并将其转换为整数。所以4567会变成4567
另外,一般来说,当这样的函数调用失败时,您应该检查errno的值。它通常会告诉您是否设置了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*和 gethostbyaddr*函数是 淘汰的应用程序应使用 和getnameinfo3 相反 下面是使用getaddrinfo稍微清理的返工程序。我强烈建议始终使用以下选项进行编译:
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) );
}
}
我决定完全重做我的回答,部分原因是手册页中有以下评论: gethostbyname*和 gethostbyaddr*函数是 淘汰的应用程序应使用 和getnameinfo3 相反 下面是使用getaddrinfo稍微清理的返工程序。我强烈建议始终使用以下选项进行编译:
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) );
}
}
你应该检查errno的值,看看实际的错误是什么。另外,注意大括号-有几个地方缩进显示两行将一起执行,但它们不会,例如,在“无法连接到网络”错误之后。我建议使用自动缩进编辑器或其他工具,并且在块周围始终使用大括号。C不是Python。你能用telnet或netcat?Err、.cpp?等其他工具连接到irc机器上的那个端口吗/4096 ? 连接到IRC?你想做一些可疑的事情吗?你应该检查errno的值,看看实际的错误是什么。另外,注意大括号-有几个地方缩进显示两行将一起执行,但它们不会执行,例如,在“无法连接到网络”错误之后。我建议使用自动缩进编辑器或其他工具,并且在块周围始终使用大括号。C不是Python。你能用telnet或netcat?Err、.cpp?等其他工具连接到irc机器上的那个端口吗/4096 ? 连接到IRC?你想做些可疑的事吗?我根据你说的话编辑了文件。仍然有问题。@dbdii407:是否检查errno的值?上面写了什么?是的,这是我的错误。网络无法访问,ScrapIRC是我的网络。它起作用了。这段代码有点奇怪,我无法理解。我根据你说的内容编辑了文件。仍然有问题。@dbdii407:是否检查errno的值?上面写了什么?是的,这是我的错误。网络无法访问,ScrapIRC是我的网络。它起作用了。这段代码有一些奇怪的地方我无法理解。即使你做了更改,仍然存在一些问题。h->h\U地址列表[0]返回B�Z和inet_addr使其成为4294967295。不知道这意味着什么,只是把它扔出去。@dbdii407:这是工作程序。我建议在凯尼格的C++编程中得到一本好书,比如用C++加速C++。
你的改变,仍然有问题。h->h\U地址列表[0]返回B�Z和inet_addr使其成为4294967295。不知道这意味着什么,只是把它扔出去。@dbdii407:这是工作程序。我建议得到一本关于C++编程的好书,比如凯尼格的C++加速程序。