尝试写一个IRC客户端,但在努力寻找有关规范和连接协议一个很好的资源 [英] Trying to write an IRC client but struggling to find a good resource regarding codes and connection protocol
问题描述
我看了看RFC,但我仍然在挣扎。我写了一个基本的客户在C#中,但我无法找到如何正确连接文档。
I've looked at the RFC but I am still struggling. I've written a basic client in C# but I cannot find documentation for how to connect properly.
在我连接和发送NICK和用户信息,我需要加入渠道。如果我做了JOIN马上,什么都不会发生 - 大概是因为它是太快了。我不得不推迟,但我不知道是哪个命令我需要等待知道它的好前进
Once I connect and transmit NICK and USER information, I need to join a channel. If I do a JOIN straight away, nothing happens - presumably because it's too soon. I have to delay it, but I don't know which command I need to wait for to know it's okay to go ahead.
我得到的东西,如:
:irc.fish.net注意AUTH:寻找你的主机名...
:irc.fish.net NOTICE AUTH :looking up your hostname...
和
:irc.fish.net 001 FishBot:欢迎
:irc.fish.net 001 FishBot :Welcome
以及东西与代码002,003,005,251,252,等等,但我找不到任何地方上网,显示我这是什么意思
as well as stuff with codes 002, 003, 005, 251, 252, etc. but I can't find anywhere online that shows me what these are.
所以我的基本的2个问题是:你怎么发送响应JOIN和我在哪里可以找到什么上面的IRC码对应?该RFC文件是没用的!
So my basic 2 questions are: What do you send a JOIN in response to, and where can I find what the IRC codes above correspond to? The RFC document was useless!
推荐答案
的RFC文档肯定不是没用!你是正确的,你需要发送 USER
然后按 NICK
。在的通知
你得到的是IRC服务器正在试图通过一个称为协议 IDENTD
来连接回您的电脑。这是一个相对简单的协议,但它的结果是,它要知道,在主机上的程序,其连接到服务器,使用该服务器具有本地/远程端口
The RFC documents are certainly not useless! You are correct that you need to send USER
followed by NICK
. The NOTICE
you are getting is that the IRC server is attempting to connect back to your PC via a protocol called IDENTD
. It's a relatively simple protocol but the upshot of it is that it wants to know that a program on the host that is connected to the server, is using the local/remote ports that the server has.
有机会,你的防火墙阻止这(和你可能没有运行IDENTD服务器)。这是不是一个巨大的问题,虽然一个不折不扣的IRC客户端将实现它。你可以在这里了解更多。那去到更多的细节。这是比较容易实现。
Chances are, your firewall is preventing this (and you're probably not running an IDENTD server). This is not a huge problem, though a fully-fledged IRC client will implement it. You can find out more here. That goes in to much more detail. It's relatively simple to implement.
大多数IRC服务器会放弃,如果它不能连接到你的,我忘了的确切的副作用这种效应(它已经有一段时间),但你要寻找出下一个消息是MOTD_START / MOTD / MOTD_END和ERR_NOMOTD。只有的之后的你已经收到了当天的邮件的末尾,或者处理的ERR_NOMOTD(没有之一),你可以再使用加入
加盟渠道
Most IRC servers will give up if it cannot connect to you, and I've forgotten the exact side-effect of this (it has been a while), but the next messages you want to look out for are the MOTD_START/MOTD/MOTD_END and ERR_NOMOTD. Only after you have received the end of the Message of the day, or handled the ERR_NOMOTD (there isn't one), can you then use JOIN
to join channels.
顺便说一句,这是从一个IRC服务器匹配输入一个良好的正则表达式:
Incidentally, this is a good RegEx for matching input from an IRC Server:
^(?:[:@]([^\\s]+) )?([^\\s]+)(?: ((?:[^:\\s][^\\s]* ?)*))?(?: ?:(.*))?$
的IRC RFC文档列表中的所有可能的代码和他们的意思。我不知道为什么你觉得自己很没用。哪些你一直在引用?
The IRC RFCs list all the possible codes and what they mean. I'm not sure why you think they are useless. Which ones have you been referencing?
修改
我抬头一看我的老为IRC C ++代码,所以我可能会多一点帮助。连接后,它进入一个阶段(即我已经标记)的谈判:
I looked up my old C++ code for IRC so I could be a bit more helpful. After connecting, it enters a stage (that I have labelled) negotiating:
谈判阶段:
- 如果一个密码已为服务器指定,发送
PASS输入mypassword
。 - 发送
USER
命令。 - 输入协商昵称舞台
- 等待
ERR_NOMOTD
,END_OFMOTD
。直到这些人来,你不是,正式连接
- If a password has been specified for the server, send it
PASS mypassword
. - Send the
USER
command. - Enter the Negotiate Nickname Stage
- Wait for
ERR_NOMOTD
,END_OFMOTD
. Until one of these comes, you're not "officially connected".
协商昵称阶段:
这是完全可能的连接时,您要使用的昵称已在使用。因此,客户端应该:
It's entirely possible that during connection, the nickname you want to use is already in use. Therefore the client should:
- 发出
NICK
命令 - 如果您收到
ERR_NICKINUSE
响应,再次发出它。如果你没有更多的昵称使用,您可以救助或提示用户换一张
- Issue a
NICK
command - If you receive a
ERR_NICKINUSE
response, issue it again. If you have no more nicknames to use, you can either bailout or prompt the user for another one.
其他的一些事情需要考虑:
Some other thing to consider:
- 查找我们对
PING
命令。当你空闲的服务器将发送这一点。处理这种高优先级,并返回PONG
与服务器给你的数据。如果不这样做将确保你得到切断,并且当你正在测试一个IRC客户端,这可以在追尾一种痛苦。
- Look our for the
PING
command. The server will send this when you're idle. Handle this as high-priority and returnPONG
with the data the server gave you. Failure to do this will ensure you get disconnected and when you're testing an IRC client, this can be a pain in the rear-end.
奖金玩转
这是我对IRC命令枚举,你应该可以把这个到C#轻松就够了:
This is my enum for the IRC commands, you should be able to put this in to C# easily enough:
// reply ids
enum Reply
{
RplNone = 0,
// Initial
RplWelcome = 001, // :Welcome to the Internet Relay Network <nickname>
RplYourHost = 002, // :Your host is <server>, running version <ver>
RplCreated = 003, // :This server was created <datetime>
RplMyInfo = 004, // <server> <ver> <usermode> <chanmode>
RplMap = 005, // :map
RplEndOfMap = 007, // :End of /MAP
RplMotdStart = 375, // :- server Message of the Day
RplMotd = 372, // :- <info>
RplMotdAlt = 377, // :- <info> (some)
RplMotdAlt2 = 378, // :- <info> (some)
RplMotdEnd = 376, // :End of /MOTD command.
RplUModeIs = 221, // <mode>
// IsOn/UserHost
RplUserHost = 302, // :userhosts
RplIsOn = 303, // :nicknames
// Away
RplAway = 301, // <nick> :away
RplUnAway = 305, // :You are no longer marked as being away
RplNowAway = 306, // :You have been marked as being away
// WHOIS/WHOWAS
RplWhoisHelper = 310, // <nick> :looks very helpful DALNET
RplWhoIsUser = 311, // <nick> <username> <address> * :<info>
RplWhoIsServer = 312, // <nick> <server> :<info>
RplWhoIsOperator = 313, // <nick> :is an IRC Operator
RplWhoIsIdle = 317, // <nick> <seconds> <signon> :<info>
RplEndOfWhois = 318, // <request> :End of /WHOIS list.
RplWhoIsChannels = 319, // <nick> :<channels>
RplWhoWasUser = 314, // <nick> <username> <address> * :<info>
RplEndOfWhoWas = 369, // <request> :End of WHOWAS
RplWhoReply = 352, // <channel> <username> <address> <server> <nick> <flags> :<hops> <info>
RplEndOfWho = 315, // <request> :End of /WHO list.
RplUserIPs = 307, // :userips UNDERNET
RplUserIP = 340, // <nick> :<nickname>=+<user>@<IP.address> UNDERNET
// List
RplListStart = 321, // Channel :Users Name
RplList = 322, // <channel> <users> :<topic>
RplListEnd = 323, // :End of /LIST
RplLinks = 364, // <server> <hub> :<hops> <info>
RplEndOfLinks = 365, // <mask> :End of /LINKS list.
// Post-Channel Join
RplUniqOpIs = 325,
RplChannelModeIs = 324, // <channel> <mode>
RplChannelUrl = 328, // <channel> :url DALNET
RplChannelCreated = 329, // <channel> <time>
RplNoTopic = 331, // <channel> :No topic is set.
RplTopic = 332, // <channel> :<topic>
RplTopicSetBy = 333, // <channel> <nickname> <time>
RplNamReply = 353, // = <channel> :<names>
RplEndOfNames = 366, // <channel> :End of /NAMES list.
// Invitational
RplInviting = 341, // <nick> <channel>
RplSummoning = 342,
// Channel Lists
RplInviteList = 346, // <channel> <invite> <nick> <time> IRCNET
RplEndOfInviteList = 357, // <channel> :End of Channel Invite List IRCNET
RplExceptList = 348, // <channel> <exception> <nick> <time> IRCNET
RplEndOfExceptList = 349, // <channel> :End of Channel Exception List IRCNET
RplBanList = 367, // <channel> <ban> <nick> <time>
RplEndOfBanList = 368, // <channel> :End of Channel Ban List
// server/misc
RplVersion = 351, // <version>.<debug> <server> :<info>
RplInfo = 371, // :<info>
RplEndOfInfo = 374, // :End of /INFO list.
RplYoureOper = 381, // :You are now an IRC Operator
RplRehashing = 382, // <file> :Rehashing
RplYoureService = 383,
RplTime = 391, // <server> :<time>
RplUsersStart = 392,
RplUsers = 393,
RplEndOfUsers = 394,
RplNoUsers = 395,
RplServList = 234,
RplServListEnd = 235,
RplAdminMe = 256, // :Administrative info about server
RplAdminLoc1 = 257, // :<info>
RplAdminLoc2 = 258, // :<info>
RplAdminEMail = 259, // :<info>
RplTryAgain = 263, // :Server load is temporarily too heavy. Please wait a while and try again.
// tracing
RplTraceLink = 200,
RplTraceConnecting = 201,
RplTraceHandshake = 202,
RplTraceUnknown = 203,
RplTraceOperator = 204,
RplTraceUser = 205,
RplTraceServer = 206,
RplTraceService = 207,
RplTraceNewType = 208,
RplTraceClass = 209,
RplTraceReconnect = 210,
RplTraceLog = 261,
RplTraceEnd = 262,
// stats
RplStatsLinkInfo = 211, // <connection> <sendq> <sentmsg> <sentbyte> <recdmsg> <recdbyte> :<open>
RplStatsCommands = 212, // <command> <uses> <bytes>
RplStatsCLine = 213, // C <address> * <server> <port> <class>
RplStatsNLine = 214, // N <address> * <server> <port> <class>
RplStatsILine = 215, // I <ipmask> * <hostmask> <port> <class>
RplStatsKLine = 216, // k <address> * <username> <details>
RplStatsPLine = 217, // P <port> <??> <??>
RplStatsQLine = 222, // <mask> :<comment>
RplStatsELine = 223, // E <hostmask> * <username> <??> <??>
RplStatsDLine = 224, // D <ipmask> * <username> <??> <??>
RplStatsLLine = 241, // L <address> * <server> <??> <??>
RplStatsuLine = 242, // :Server Up <num> days, <time>
RplStatsoLine = 243, // o <mask> <password> <user> <??> <class>
RplStatsHLine = 244, // H <address> * <server> <??> <??>
RplStatsGLine = 247, // G <address> <timestamp> :<reason>
RplStatsULine = 248, // U <host> * <??> <??> <??>
RplStatsZLine = 249, // :info
RplStatsYLine = 218, // Y <class> <ping> <freq> <maxconnect> <sendq>
RplEndOfStats = 219, // <char> :End of /STATS report
RplStatsUptime = 242,
// GLINE
RplGLineList = 280, // <address> <timestamp> <reason> UNDERNET
RplEndOfGLineList = 281, // :End of G-line List UNDERNET
// Silence
RplSilenceList = 271, // <nick> <mask> UNDERNET/DALNET
RplEndOfSilenceList = 272, // <nick> :End of Silence List UNDERNET/DALNET
// LUser
RplLUserClient = 251, // :There are <user> users and <invis> invisible on <serv> servers
RplLUserOp = 252, // <num> :operator(s) online
RplLUserUnknown = 253, // <num> :unknown connection(s)
RplLUserChannels = 254, // <num> :channels formed
RplLUserMe = 255, // :I have <user> clients and <serv> servers
RplLUserLocalUser = 265, // :Current local users: <curr> Max: <max>
RplLUserGlobalUser = 266, // :Current global users: <curr> Max: <max>
// Errors
ErrNoSuchNick = 401, // <nickname> :No such nick
ErrNoSuchServer = 402, // <server> :No such server
ErrNoSuchChannel = 403, // <channel> :No such channel
ErrCannotSendToChan = 404, // <channel> :Cannot send to channel
ErrTooManyChannels = 405, // <channel> :You have joined too many channels
ErrWasNoSuchNick = 406, // <nickname> :There was no such nickname
ErrTooManyTargets = 407, // <target> :Duplicate recipients. No message delivered
ErrNoColors = 408, // <nickname> #<channel> :You cannot use colors on this channel. Not sent: <text> DALNET
ErrNoOrigin = 409, // :No origin specified
ErrNoRecipient = 411, // :No recipient given (<command>)
ErrNoTextToSend = 412, // :No text to send
ErrNoTopLevel = 413, // <mask> :No toplevel domain specified
ErrWildTopLevel = 414, // <mask> :Wildcard in toplevel Domain
ErrBadMask = 415,
ErrTooMuchInfo = 416, // <command> :Too many lines in the output, restrict your query UNDERNET
ErrUnknownCommand = 421, // <command> :Unknown command
ErrNoMotd = 422, // :MOTD File is missing
ErrNoAdminInfo = 423, // <server> :No administrative info available
ErrFileError = 424,
ErrNoNicknameGiven = 431, // :No nickname given
ErrErroneusNickname = 432, // <nickname> :Erroneus Nickname
ErrNickNameInUse = 433, // <nickname> :Nickname is already in use.
ErrNickCollision = 436, // <nickname> :Nickname collision KILL
ErrUnAvailResource = 437, // <channel> :Cannot change nickname while banned on channel
ErrNickTooFast = 438, // <nick> :Nick change too fast. Please wait <sec> seconds. (most)
ErrTargetTooFast = 439, // <target> :Target change too fast. Please wait <sec> seconds. DALNET/UNDERNET
ErrUserNotInChannel = 441, // <nickname> <channel> :They aren't on that channel
ErrNotOnChannel = 442, // <channel> :You're not on that channel
ErrUserOnChannel = 443, // <nickname> <channel> :is already on channel
ErrNoLogin = 444,
ErrSummonDisabled = 445, // :SUMMON has been disabled
ErrUsersDisabled = 446, // :USERS has been disabled
ErrNotRegistered = 451, // <command> :Register first.
ErrNeedMoreParams = 461, // <command> :Not enough parameters
ErrAlreadyRegistered= 462, // :You may not reregister
ErrNoPermForHost = 463,
ErrPasswdMistmatch = 464,
ErrYoureBannedCreep = 465,
ErrYouWillBeBanned = 466,
ErrKeySet = 467, // <channel> :Channel key already set
ErrServerCanChange = 468, // <channel> :Only servers can change that mode DALNET
ErrChannelIsFull = 471, // <channel> :Cannot join channel (+l)
ErrUnknownMode = 472, // <char> :is unknown mode char to me
ErrInviteOnlyChan = 473, // <channel> :Cannot join channel (+i)
ErrBannedFromChan = 474, // <channel> :Cannot join channel (+b)
ErrBadChannelKey = 475, // <channel> :Cannot join channel (+k)
ErrBadChanMask = 476,
ErrNickNotRegistered= 477, // <channel> :You need a registered nick to join that channel. DALNET
ErrBanListFull = 478, // <channel> <ban> :Channel ban/ignore list is full
ErrNoPrivileges = 481, // :Permission Denied- You're not an IRC operator
ErrChanOPrivsNeeded = 482, // <channel> :You're not channel operator
ErrCantKillServer = 483, // :You cant kill a server!
ErrRestricted = 484, // <nick> <channel> :Cannot kill, kick or deop channel service UNDERNET
ErrUniqOPrivsNeeded = 485, // <channel> :Cannot join channel (reason)
ErrNoOperHost = 491, // :No O-lines for your host
ErrUModeUnknownFlag = 501, // :Unknown MODE flag
ErrUsersDontMatch = 502, // :Cant change mode for other users
ErrSilenceListFull = 511 // <mask> :Your silence list is full UNDERNET/DALNET
}; // eo enum Reply
这篇关于尝试写一个IRC客户端,但在努力寻找有关规范和连接协议一个很好的资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!