Winsock - Почему ZNC (и IRC-баунсер) не принимают мое соединение Winsock?
Используя типичного клиента irc, я могу набрать:
/server localhost 6667 nick:pass
Когда я вхожу в nick:pass, который я настроил для ZNC (IRC-баунсер), я перенаправляюсь на сервер, к которому подключен znc, в соответствии с моей комбинацией server/nick:pass.
Как программно открыть соединение winsock со всеми этими аргументами одновременно? /server localhost 6667 nick:pass
Я попытался отправить данные после подключения, но znc, похоже, игнорирует запросы. Или я просто не подключаюсь к этому вообще. Этот код подключился к IRC-серверу, который не требует проверки подлинности Ping, поэтому я знаю, что он работает.
#define AF_INET 2
#define SOCK_STREAM 1
#define SOL_SOCKET 0xffff
#define SO_SNDTIMEO 0x1005
string server_addr = "127.0.0.1";
int server_port = 6667;
void ircconnect(){
int struct_sockaddr[4];
int addr, port_low, port_high;
int opts[1];
int c;
if (irc_disabled == 1) return(0);
// fill the sockaddr struct
addr = inet_addr(server_addr);
port_low = server_port & 0x00ff;
port_high = (server_port & 0xff00) >> 8;
struct_sockaddr[0] = AF_INET | (port_high << 16) | (port_low << 24);
struct_sockaddr[1] = addr;
struct_sockaddr[2] = 0;
struct_sockaddr[3] = 0;
// connect
s = socket(AF_INET, SOCK_STREAM, 0);
opts[0] = 1000; // send timeout milliseconds
setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, opts, 4);
c = connect(s, struct_sockaddr, 16);
Sleep(5000);
sendLine(nick + ":" + password);
3 ответа
Смотрите объяснение Python ниже:
int struct_sockaddr[4];
int addr, port_low, port_high;
int opts[1];
int c;
string zncauth = nick + ":" + password;
if (irc_disabled == 1) return(0);
// fill the sockaddr struct
addr = inet_addr(server_addr);
port_low = server_port & 0x00ff;
port_high = (server_port & 0xff00) >> 8;
struct_sockaddr[0] = AF_INET | (port_high << 16) | (port_low << 24);
struct_sockaddr[1] = addr;
struct_sockaddr[2] = 0;
struct_sockaddr[3] = 0;
// connect
s = socket(AF_INET, SOCK_STREAM, 0);
opts[0] = 1000; // send timeout milliseconds
setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, opts, 4);
c = connect(s, struct_sockaddr, 16);
// send
sendLine("NICK zncbotnick");
sendLine("USER znc bot znc :znc");
sendLine("PASS " + zncauth);
void sendLine(string text){
if (irc_disabled == 1) return(0);
text = text + "\r\n";
send(s, text, StringLen(text), 0);
}
Код выше, наконец, работает, и это работает для меня в Python для аутентификации с ZNC. По сути, на другом языке я бросал команды в znc, но они никогда не доходили до znc, потому что в коде отсутствовали символы возврата и перевода строки. '\r\n'
, С помощью python я смог диагностировать проблему в режиме реального времени.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
//Test.py
import socket
zncauth = 'nick:password'
server_addr = '127.0.0.1'
server_port = 6667
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((server_addr, server_port))
s.send( 'NICK botnick\r\n')
s.send( 'USER znc bot znc :znc\r\n')
s.send( 'PASS ' + zncauth + ' \r\n')
Используйте анализатор пакетов, такой как Wireshark, для просмотра трафика сокета при соединении с ZNC с использованием IRC-клиента и вашего кода и найдите любые различия в отправляемых командах.
С учетом сказанного, в вашем коде также есть некоторые странности. Попробуйте это вместо этого:
#define AF_INET 2
#define SOCK_STREAM 1
#define SOL_SOCKET 0xffff
#define SO_SNDTIMEO 0x1005
string server_addr = "127.0.0.1";
u_short server_port = 6667;
void ircconnect(){
struct sockaddr_in addr;
int opts;
int c;
if (irc_disabled == 1) return(0);
// fill the sockaddr struct
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(server_port);
addr.sin_addr.s_addr = inet_addr(server_addr.c_str());
// connect
s = socket(AF_INET, SOCK_STREAM, 0);
opts = 1000; // send timeout milliseconds
setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *)&opts, sizeof(opts));
c = connect(s, (struct sockaddr *)&addr, sizeof(addr));
Sleep(5000);
sendLine(nick + ":" + password);
IRC-сервер реализует протокол Internet Relay Chat.
протокол не имеет ничего общего с командами, которые вы вводите в IRC-клиенте. так как вы не уважаете протокол IRC, сервер не понимает, что вы говорите, и, таким образом, в лучшем случае игнорирует вас, или просто разрывает соединение.
протокол определен в наборе из 4 RFC: RFC2810, RFC2811, RFC2812 и RFC2813.
Вы должны прочитать эти документы и понять архитектуру IRC и procotol, прежде чем пытаться реализовать какую-либо программу, которая будет взаимодействовать с сервером IRC.
Кроме того, вы легко найдете библиотеку, которая реализует протокол для вас.