5
import socket, sys

if len(sys.argv) !=3 :
print "Usage: ./supabot.py <host> <port>"
sys.exit(1)

irc = sys.argv[1]
port = int(sys.argv[2])
sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sck.connect((irc, port))
sck.send('NICK supaBOT\r\n')
sck.send('USER supaBOT supaBOT supaBOT :supaBOT Script\r\n')
sck.send('JOIN #darkunderground' + '\r\n')
data = ''
while True:
      data = sck.recv(1024)
      if data.find('PING') != -1:
         sck.send('PONG ' + data.split() [1] + '\r\n')
         print data
      elif data.find('!info') != -1:
          sck.send('PRIVMSG #darkunderground supaBOT v1.0 by sourD' + '\r\n')


print sck.recv(1024)

このコードを実行すると、このエラーが発生します。

socket.error:[Errno10054]既存の接続がリモートホストによって強制的に閉じられました

エラーは16行目にあることを示しています。data=sck.recv(1024)

4

3 に答える 3

4

IRC プロトコルをもう少し確認する必要があります。サーバーが IRC プロトコル コードの使用についてクライアントに通知する特定のアクションが完了するまで、IRC セッションは (サーバーによって) 接続されているとは見なされません。また、接続時にサーバーまたはネットワークがビジー状態の場合、これらのアクションが完了するまでに時間がかかります。

この場合、サーバーが MOTD (今日のメッセージ) を送信する前にチャンネルに参加しようとすると、サーバーによる切断が発生します。MOTD プロトコル コードの末尾は 376 で、IRC 接続シーケンスが終了したことを示します。IRC セッションを続行できます。たとえば、コマンドを入力します (参加など)。

チャネルに参加する前に、RECV ループに入り、サーバーから受信した IRC コード 376 のデータを監視することをお勧めします。Perl では、次のようになります。

 sub chan_join{
  while(my $input = <SOCK>){
    if($input =~ /376/){
      my $talk = "JOIN $channel";
      &send_data($talk);
      &monitor;
    }
    else { print "$input";  }
  }
}

かなり貧弱ですが、あなたはその考えを正しく理解していますか?(一度だけ 376 をチェックする必要があることに注意してください。接続されていることが確認されたら、サーバーの「PING」に応答して接続を維持するだけで済みます)

于 2010-06-20T16:34:59.377 に答える
1

これはおそらく、サーバーに期待されるハンドシェイクまたはプロトコル交換を提供しておらず、接続を閉じていることを意味します。

同じマシンとポートにtelnetで接続し、同じテキストを入力するとどうなりますか?

于 2010-06-17T04:49:56.570 に答える
1

リモート ホストはRST、接続を受け入れた後、TCP リセット ( ) を発行しています。これは、次のような多くの理由で発生する可能性があります。

  • ファイアウォール ルール
  • リモート アプリケーション エラー
  • リモート アプリケーションは単に接続を閉じます

John Weldon が言ったように、同じマシンとポートに telnet で接続し、手動でコマンドを入力してみてください。

また、優れたワイヤ スニファ (Ethereal、WireShark など) は、この種の問題を診断するのに非常に役立ちます。

于 2010-06-20T12:59:34.377 に答える