问题
Using a typical irc client I can type in:
/server localhost 6667 nick:pass
When I enter the nick:pass I configured for ZNC,(an IRC bouncer) I'm forwarded to the server that znc is connected to under my server/nick:pass combination.
How can I programmatically open a winsock connection with all of these arguments simultaneously? /server localhost 6667 nick:pass
I've tried sending the data after connecting but znc seems to be ignoring the requests. Or I'm just not connecting to it at all. This code has connected to an IRC server that doesn't require Ping authentication, so I know it works.
#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);
回答1:
See the python explanation below:
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);
}
The code above finally works and this works for me in python to authenticate with ZNC. Basically, in the other language I was throwing commands to znc but they never got to znc because the code was missing return and newline characters '\r\n'
. With python, I was able to diagnose the problem in real-time.
#!/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')
回答2:
Use a packet sniffer like Wireshark to view the socket traffic when conecting to ZNC using an IRC client versus your code, and look for any differences in the commands being sent.
With that said, there are some oddities in your code as well. Try this instead:
#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);
回答3:
an IRC server implements the Internet Relay Chat protocol.
the protocol has nothing in common with the commands you type in your IRC client. since you don't respect the IRC protocol, the server does not understand what you are saying, and thus ignores you at best, or just drops the connection.
the protocol is defined in a set of 4 RFCs: RFC2810, RFC2811, RFC2812 and RFC2813.
you should read those documents and understand the IRC architecture and procotol, before trying to implement any program which will interact with an IRC server.
additionally, you will easily find some library which implements the protocol for you.
来源:https://stackoverflow.com/questions/10343533/winsock-why-isnt-znc-and-irc-bouncer-accepting-my-winsock-connection