【问题标题】:Problem with IRC socket connectionIRC套接字连接问题
【发布时间】:2011-07-11 15:22:17
【问题描述】:

在 JOIN 和 USER 期间发生错误,它告诉我需要“先注册”。三:PASS、NICK工作正常(大概)。知道这怎么可能?我遵循了相关的 RFC,https://www.rfc-editor.org/rfc/rfc1459#section-4.1

代码:

#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);
    cout << 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;
}

有连接的日志:

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.

【问题讨论】:

  • 我要添加一条评论:很多很多 IRC 服务器在这一点上已经远远超出了 1993 年的 RFC,添加了偶尔记录的各种特性和模式——但并非总是如此。可能没有一个主要的 IRC 网络严格遵守 RFC。

标签: c++ sockets connection irc


【解决方案1】:

我猜,要加入该特定频道,您的昵称必须在 NickServ 或等效的 IRC 服务中注册。您可能必须使用 NickServ 注册您使用的昵称(我建议使用常规 IRC 客户端来执行此操作以使其更容易),然后从您的代码中,使用某种身份验证命令 PRIVMSG NickServ 来“登录" 在它允许您加入该频道之前。可能有一种频道模式可以控制是否允许非授权用户加入。

如果您还没有,我建议您使用未注册的空频道进行测试。能够控制测试环境会有所帮助,并且在您开发软件的过程中,您不会有好奇的人试图破坏您的软件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-15
    • 2016-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多