socket.error: [错误号 10054]

5 投票
3 回答
28298 浏览
提问于 2025-04-16 00:05
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: [错误号 10054] 现有的连接被远程主机强行关闭

它说错误出现在第16行,也就是在 data = sck.recv(1024) 这一行

3 个回答

1

这可能意味着你没有给服务器发送它期待的握手信息或者协议交换,所以服务器关闭了连接。

如果你用telnet连接到同一台机器和端口,然后输入相同的内容,会发生什么呢?

1

远程主机在接受连接后发出了一个TCP重置信号(RST)。这可能是由于很多原因造成的,包括:

  • 防火墙规则
  • 远程应用程序出错
  • 远程应用程序直接关闭了连接
  • 等等。

正如约翰·韦尔登所说,可以尝试用telnet连接到同一台机器和端口,然后手动输入命令。

另外,使用一个好的网络嗅探工具(比如Ethereal、WireShark等)对诊断这种问题非常有帮助。

4

你需要多了解一下IRC协议;在服务器完成某些操作之前,你的IRC会话不会被认为是连接上的。服务器会通过IRC协议代码来告诉你的客户端这些操作是否完成。如果在你连接的时候服务器或网络很忙,这些操作完成的时间就会变长。

在这种情况下,如果你在服务器还没有给你发送“今日消息”(MOTD)之前就尝试加入一个频道,服务器会把你断开连接。MOTD协议代码的结束标志是376,这表示IRC连接的过程结束了,这时你可以继续进行IRC会话,比如输入命令(比如加入频道)。

我建议你先进入一个接收循环,监控从服务器接收到的数据,等待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”来保持连接)

撰写回答