尝试写一个IRC客户端,但在努力寻找有关规范和连接协议一个很好的资源 [英] Trying to write an IRC client but struggling to find a good resource regarding codes and connection protocol

查看:80
本文介绍了尝试写一个IRC客户端,但在努力寻找有关规范和连接协议一个很好的资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看了看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:

谈判阶段:


  1. 如果一个密码已为服务器指定,发送 PASS输入mypassword

  2. 发送 USER 命令。

  3. 输入协商昵称舞台

  4. 等待 ERR_NOMOTD END_OFMOTD 。直到这些人来,你不是,正式连接

  1. If a password has been specified for the server, send it PASS mypassword.
  2. Send the USER command.
  3. Enter the Negotiate Nickname Stage
  4. 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:


  1. 发出 NICK 命令

  2. 如果您收到 ERR_NICKINUSE 响应,再次发出它。如果你没有更多的昵称使用,您可以救助或提示用户换一张

  1. Issue a NICK command
  2. 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 return PONG 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆