Я пытаюсь написать irc-бот на c ++ и позаботился о подключении и настройке моего псевдонима, а также идентификатора, пинг также работает. Единственная проблема, с которой я столкнулся — это присоединение к каналу. Сервер продолжает отправлять обратно «JOIN: неизвестная команда». Я считаю, что следующие строки наиболее актуальны:
#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);
}
}
}}
Вы не ждете завершения регистрации перед отправкой.
Ваш клиент слишком прост, правда. Чтобы получить желаемый эффект, вы можете поместить режим сна между командами USER / NICK и командой JOIN.
Тем не менее, правильное решение без ошибок — иметь правильный цикл отправки / получения с использованием опроса, выбора и т. Д., Дождаться номера 001 (первого правильного, полученного после регистрации соединения) или, что более правильно, либо RPL_ENDOFMOTD (376), либо ERR_NOMOTD (422). После получения этой строки отправьте свой JOIN.
Увидеть: https://tools.ietf.org/html/rfc1459
Кроме того, вам нужно гораздо больше реагировать, чем PING, чтобы сделать работающего клиента, но это что-то для другого дня. Некоторые серверы отправляют PING «безопасность» во время регистрации, на который вы должны ответить, прежде чем сервер примет соединение и отправит цифру 001. Если вы не ответите на это, ваше соединение никогда не будет зарегистрировано и в конечном итоге истечет время ожидания.
Других решений пока нет …