Error occurs during JOIN and USER, it tells me I need to "Register first". The three: PASS, NICK work correctly (probably). Any idea how is this possible? I've followed the relevant RFC, https://www.rfc-editor.org/rfc/rfc1459#section-4.1
code:
#include <iostream>
#include <winsock2.h>
#include <string>
#include <cstring>
#include <fstream>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
unsigned long resolveHost(const string &host){
LPHOSTENT entryHost = gethostbyname(host.c_str());
if(!entryHost){
unsigned int addr = inet_addr(host.c_str());
entryHost = gethostbyaddr((char*)&addr, 4, AF_INET);
if(!entryHost) return 0;
}
return *((int*)*entryHost->h_addr_list);
}
int main(){
WSADATA wsaData;
SOCKADDR_IN saddr;
SOCKET sock;
char buffer[1024*8] = {"0"};
string adres_hosta = "irc.example.com";
string sbuffer;
string nick = "johnsmith";
string kanal = "#channel";
string password = "p@55w0rd";
string auth = "/AuthServ auth johnsmith p@55w0rd";
WSAStartup(MAKEWORD(2, 2), &wsaData);
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
saddr.sin_addr.S_un.S_addr = resolveHost(adres_hosta);
saddr.sin_port = htons(6667);
saddr.sin_family = AF_INET;
if(connect(sock, (sockaddr*)&saddr, sizeof(sockaddr)) == SOCKET_ERROR){
cout << "Nie udalo sie nawiazac polaczenia z " << adres_hosta << ".";
return 0;
}
recv(sock, buffer, 1024*8, 0);
cout << buffer << endl << endl << flush;
/*
1. Pass message
2. Nick message
3. User message
*/
sbuffer ="PASS " + password + "\r\n";
send(sock, sbuffer.c_str(), strlen(sbuffer.c_str()), 0);
recv(sock, buffer, 1024*8, 0);
cout << sbuffer.c_str() << endl << buffer << endl << endl;
sbuffer = "NICK " + nick + "\r\n";
send(sock, sbuffer.c_str(), strlen(sbuffer.c_str()), 0);
recv(sock, buffer, 1024*8, 0);
cout << sbuffer.c_str() << endl << buffer << endl << endl;
sbuffer = "USER " + nick + " " + adres_hosta + " " + nick + " :" + nick + "\r\n";
send(sock, sbuffer.c_str(), strlen(sbuffer.c_str()), 0);
recv(sock, buffer, 1024*8, 0);
cou开发者_如何学Got << sbuffer.c_str() << endl << buffer << endl << endl;
sbuffer = "JOIN " + kanal + "\r\n";
send(sock, sbuffer.c_str(), strlen(sbuffer.c_str()), 0);
recv(sock, buffer, 1024*8, 0);
cout << sbuffer.c_str() << endl << buffer << endl << endl;
while(true){
recv(sock, buffer, 1024*8, 0);
cout << buffer << endl << endl;
if(buffer[0] == 'PING'){
sbuffer = "PONG :" + adres_hosta + "\r\n";
send(sock, sbuffer.c_str(), strlen(sbuffer.c_str()), 0);
cout << sbuffer.c_str() << endl << buffer << endl << endl;
}
}
return 1;
}
logs with connection :
NOTICE AUTH :*** Looking up your hostname
PASS p@55w0rd
NOTICE AUTH :*** Checking Ident
NOTICE AUTH :*** Found your hostname
NICK johnsmith
PING :229860947
Checking Ident
NOTICE AUTH :*** Found your hostname
USER johnsmith johnSmith test :johnSmith
NOTICE AUTH :*** No ident response
ICE AUTH :*** Found your hostname
JOIN #channel
:server.example.com 451 johnSmith johnSmith :Register first.
I'm guessing that, to join that specific channel, your nickname must be registered with NickServ or equivalent IRC services. You'll probably have to register the nickname you're using with NickServ (I suggest using a regular IRC client to do this to make it easier) and then, from your code, PRIVMSG NickServ with some sort of auth command to "log in" before it will allow you to join that channel. There's probably a channel mode that controls whether non-authorized users are allowed to join.
If you aren't already, I would suggest using an empty, unregistered channel for doing your testing. It helps to be able to control the test environment, and you don't have curious people trying to break your software while you're in the middle of developing it.
精彩评论