2011-12-13 30 views
6

我已经看过RFC但我仍在挣扎。我用C#编写了一个基本的客户端,但是我找不到正确连接的文档。试图写一个IRC客户端,但努力寻找关于代码和连接协议的好资源

一旦我连接并传输NICK和USER信息,我需要加入一个频道。如果我马上加入,没有任何反应 - 大概是因为它太快了。我必须推迟它,但我不知道我需要等待哪个命令才能知道可以继续。

我得到的东西,如:

:irc.fish.net注意AUTH:查找您的主机...

:irc.fish.net 001 FishBot:欢迎

以及代码为002,003,005,251,252等的东西,但我无法在网上找到任何地方,告诉我这些是什么。

所以我最基本的两个问题是:你发送一个JOIN响应什么,我在哪里可以找到上面的IRC代码对应的? RFC文件没用!

+0

虽然这是一个痛苦的解决方案,但您可以随时连接MIRC(或现在使用的任何人)使用Fiddler的代理服务器,并且您可以查看从签入到加入房间时所需的所有流量。 –

+0

有关完整源代码的最终解决方案? – Kiquenet

回答

13

RFC文档当然不是无用的!你是正确的,你需要发送USER然后NICK。您所得到的NOTICE是IRC服务器试图通过名为IDENTD的协议连接回您的PC。这是一个相对简单的协议,但其结果是它想知道连接到服务器的主机上的程序正在使用服务器所具有的本地/远程端口。

很可能你的防火墙阻止了这个(你可能没有运行IDENTD服务器)。这不是一个大问题,尽管一个完全成熟的IRC客户端会实现它。你可以找到更多here。这涉及更多的细节。实施起来相对简单。

大多数IRC服务器会放弃,如果它不能连接到你的,我忘了确切的这种副作用(它已经有一段时间),但要注意的事项是下一组信息MOTD_START/MOTD/MOTD_END和ERR_NOMOTD。之后只有您已收到当天留言的结束,或者处理了ERR_NOMOTD(没有一个),那么您可以使用JOIN加入频道。

顺便说一句,这是一个很好的正则表达式从一个IRC服务器匹配输入:

^(?:[:@]([^\\s]+))?([^\\s]+)(?: ((?:[^:\\s][^\\s]* ?)*))?(?: ?:(.*))?$ 

的IRC RFC文档列表中的所有可能的代码和他们的意思。我不知道你为什么认为他们没用。你一直在引用哪些内容?

编辑

我抬头看我的旧的C++代码,IRC,所以我可能会多一点帮助。连接后,它进入一个阶段(即我已经标记)谈判:

谈判阶段:

  1. 如果密码已经为服务器指定,发送PASS mypassword
  2. 发送USER命令。
  3. 输入Negotiate昵称阶段
  4. 等待ERR_NOMOTD,END_OFMOTD。直到其中之一出现,你不是“正式连接”。

协商昵称阶段:

这是完全可能的连接时,您要使用的昵称已在使用。因此,客户应:

  1. 问题一个NICK命令
  2. 如果再次收到一个ERR_NICKINUSE响应,问题吧。如果您没有更多昵称可供使用,您可以对其进行救援或提示用户使用另一个昵称。

一些其他的事情要考虑:

  • 看看我们为PING命令。服务器会在闲置时发送。将其作为高优先级处理,并返回PONG与服务器给你的数据。如果不这样做将确保您断开连接,并且在您测试IRC客户端时,这可能会让后端感到痛苦。

奖金乐趣

这是我的IRC命令枚举,你应该能够把这个在C#中很轻松地:

// 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 
+0

干杯,我想过要等待MOTD的结束,但它看起来有点冒险。感谢命令列表! – NibblyPig

+0

这根本不算什么。在它到达之前(或者服务器还没有到达),你不处于发送命令的“状态”,所以它最终成为了解何时发出命令的理想候选者。 –

+0

啊好的,谢谢。 – NibblyPig

3

也许你看过旧版本(RFC 1459)而不是当前版本(RFC 2812)的标准?

后者列出了第5的数字代码“回复”:

001 RPL_WELCOME 
      "Welcome to the Internet Relay Network 
      <nick>!<user>@<host>" 
    002 RPL_YOURHOST 
      "Your host is <servername>, running version <ver>" 
    003 RPL_CREATED 
      "This server was created <date>" 
    ... 

(这应该回答你的第二个问题;不幸的是,我不是用协议来回答你的第一个再熟悉不过了。简单的解决方案让你走上正确的轨道可能是使用一些packet sniffer跟踪现有IRC客户端的连接。)

2

的代码可以在this document找到,您指定的是:

  • 002 RPL_YOURHOST“您的主机是正在运行的版本”
  • 003 RPL_CREATED “此服务器创建”
  • 005 RPL_BOUNCE “尝试服务器,端口”
  • 251 RPL_LUSERCLIENT “:有网友服务的服务器上”
  • 252 RPL_LUSEROP “:运营商(县)在线”