我正在尝试用c++编写一个irc机器人,并且已经负责连接和设置我的昵称以及身份,ping也在起作用。我遇到的唯一问题就是加入一个频道。服务器一直在发回"JOIN :unknown command“我相信下面这几行是最相关的:
#define JOIN "JOIN #test\r\n"
send(IrcSocket, JOIN, strlen(JOIN),0);在很小的机会,没有什么可以解决的,因为我已经包括了entrie程序,这可能是一个有点有碍观瞻。
#define WIN32_LEAN_AND_MEAN
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <string>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
WSADATA wsaData;
int iresult=WSAStartup(MAKEWORD(2,2),&wsaData);
if(iresult!=0)
{
printf("WSAStartup Failed: %d \n", iresult);
return 1;
}
struct addrinfo *result=NULL, *ptr=NULL, hints;
ZeroMemory(&hints,sizeof(hints));
hints.ai_family=AF_INET;
hints.ai_socktype=SOCK_STREAM;
hints.ai_protocol=IPPROTO_TCP;
#define DEFAULT_PORT "6667"
#define DEFAULT_IP "192.168.0.10"
iresult = getaddrinfo(DEFAULT_IP,DEFAULT_PORT,&hints,&result);
if(iresult!=0)
{
printf("getaddrinfo failed: %d\n", iresult);
WSACleanup();
return 1;
}
SOCKET IrcSocket= INVALID_SOCKET;
ptr=result;
IrcSocket=socket(ptr->ai_family, ptr->ai_socktype,ptr->ai_protocol);
if (IrcSocket == INVALID_SOCKET)
{
printf("Error at socket(): %d \n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
iresult=connect(IrcSocket,ptr->ai_addr,ptr->ai_addrlen);
if(iresult==SOCKET_ERROR)
{
closesocket(IrcSocket);
IrcSocket=INVALID_SOCKET;
freeaddrinfo(result);
}
if(IrcSocket == INVALID_SOCKET)
{
printf("Unable to connect to irc server!");
WSACleanup();
return 1;
}
std::cout<<("connection made\n");
#define NICK "NICK bottester\r\n"
#define IDENT "USER bottester 0 0 bottester\r\n"
#define JOIN "JOIN #test\r\n"
char stringbuffer[256];
iresult=send(IrcSocket,NICK, strlen(NICK),0);
if(iresult == SOCKET_ERROR)
{
printf("send failed: %d\n", WSAGetLastError());
closesocket(IrcSocket);
WSACleanup();
std::cin.get();
return 1;
}
iresult=send(IrcSocket, IDENT, strlen(IDENT),0);
if(iresult == SOCKET_ERROR)
{
printf("send failed: %d\n", WSAGetLastError());
closesocket(IrcSocket);
WSACleanup();
std::cin.get();
return 1;
}
std::cout<<"entering ping loop\n";
char pingnumber[128];
char pinganswer[17]="PONG :";
#define PRMSG "PRIVMSG test :TESTBOT IS HERE!\r\n"
for(;;)
{
memset(stringbuffer,0,256);
recv(IrcSocket,stringbuffer,sizeof(stringbuffer),0);
for(int j=0;j<strlen(stringbuffer);j++)
{
std::cout<<j<<stringbuffer[j]<<"\n";
if(stringbuffer[j]=='P' && stringbuffer[j+1]=='I' && stringbuffer[j+2]=='N' && stringbuffer[j+3]=='G')
{
memset(pingnumber,0,10);
std::memcpy(pingnumber, stringbuffer+j+6,10);
std::memcpy(pinganswer+6,pingnumber,10);
std::memcpy(pinganswer+16, "\r\n",strlen("\r\n"));
send(IrcSocket,pinganswer,strlen(pinganswer),0);
std::cout<< "PINGED<"<<pingnumber<<"\n";
iresult=send(IrcSocket, JOIN, strlen(JOIN),0);
std::cout<< "JOINED\n";
send(IrcSocket, PRMSG, strlen(PRMSG),0);
}
}
}
}发布于 2016-10-18 15:34:29
在发送JOIN之前,您不需要等待注册完成。
你的客户太简单了,真的。为了获得您想要的效果,您可以在USER/NICK命令和JOIN命令之间设置睡眠。
不过,正确而不笨拙的解决方案是使用poll、select等正确的发送/接收轮询循环,等待001数字(注册连接后收到的第一个正确的数字),或者更准确地说是RPL_ENDOFMOTD (376)或ERR_NOMOTD (422)。收到此行后,发送您的JOIN。
请参阅:https://www.rfc-editor.org/rfc/rfc1459
此外,还有更多的东西你真的需要响应而不是PING来建立一个功能正常的客户端,但这是另一天的事情。一些服务器在注册过程中发送一个'security‘PING,在服务器接受连接并发送001数字之前,您必须对此作出响应。如果您不对此作出响应,您的连接将永远不会注册,并且最终ping超时。
https://stackoverflow.com/questions/15868454
复制相似问题