Winsock - 为啥 ZNC(和 IRC 保镖)不接受我的 winsock 连接?
Posted
技术标签:
【中文标题】Winsock - 为啥 ZNC(和 IRC 保镖)不接受我的 winsock 连接?【英文标题】:Winsock - Why isn't ZNC (and IRC bouncer) accepting my winsock connection?Winsock - 为什么 ZNC(和 IRC 保镖)不接受我的 winsock 连接? 【发布时间】:2012-04-27 01:15:11 【问题描述】:使用典型的 irc 客户端,我可以输入:
/server localhost 6667 nick:pass
当我输入为 ZNC 配置的 nick:pass(一个 IRC 保镖)时,我被转发到我的 server/nick:pass 组合下 znc 连接到的服务器。
如何以编程方式同时打开所有这些参数的 winsock 连接? /server localhost 6667 nick:pass
我尝试在连接后发送数据,但 znc 似乎忽略了请求。或者我根本没有连接到它。此代码已连接到不需要 Ping 身份验证的 IRC 服务器,所以我知道它可以工作。
#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.不要在您的文件中定义您的#define
s。相反,#include
适当的头文件。 2、不要再手动设置AF_INET
。现在是 2012 年,是时候使用getaddrinfo()
了。
好的。感谢您的建议。我会的。
【参考方案1】:
请看下面的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 发送命令,但由于代码缺少返回和换行符 '\r\n'
,他们从未到达 znc。使用 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')
【讨论】:
【参考方案2】:使用像 Wireshark 这样的数据包嗅探器来查看使用 IRC 客户端与您的代码连接到 ZNC 时的套接字流量,并查找正在发送的命令中的任何差异。
话虽如此,您的代码中也有一些奇怪之处。试试这个:
#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);
【讨论】:
非常感谢:) 我正在使用wireshark,我得仔细看看。 :) 我会试试你的建议【参考方案3】:IRC 服务器实现 Internet 中继聊天协议。
该协议与您在 IRC 客户端中键入的命令没有任何共同之处。由于您不遵守 IRC 协议,服务器无法理解您在说什么,因此最多会忽略您,或者只是断开连接。
该协议在一组 4 个 RFC 中定义:RFC2810、RFC2811、RFC2812 和 RFC2813。
在尝试实现与 IRC 服务器交互的任何程序之前,您应该阅读这些文档并了解 IRC 架构和协议。
此外,您会很容易找到一些为您实现协议的库。
【讨论】:
非常感谢您的帮助,但通过反复试验,我发现代码只是缺少这些转义字符:"\r\n"
。我现在用它来发布我的交易。我确信它可以改进,但它可以满足我的需要。我的回答如下。以上是关于Winsock - 为啥 ZNC(和 IRC 保镖)不接受我的 winsock 连接?的主要内容,如果未能解决你的问题,请参考以下文章