使用socket库开发的Python IRC bot运行报Bad file descriptor错误求助
错误原因及修复方案
核心触发原因
你遇到的「Bad File Descriptor」错误最直接的诱因是在循环的第一次迭代就主动关闭了socket连接:循环内执行完一次消息发送逻辑后直接调用了ircsock.close(),当进入第二次循环尝试对已经关闭的socket执行send/connect等操作时,系统就会返回无效文件描述符错误。
其他导致问题的代码缺陷
- 缺少socket初始化逻辑:代码中从未声明创建
ircsocksocket对象,直接调用connect方法本身就会触发异常 - 函数语法错误:两处
def main定义行末尾都缺少冒号,且重复定义main函数会导致前一次定义被覆盖 - 端口适配错误:6697是IRC的SSL加密端口,使用普通socket直连会被服务器主动断开,需要先对socket做SSL封装
- 协议格式错误:IRC协议要求命令行结尾必须是
\r\n,你大部分命令只使用了\n,不符合规范会被服务器断连 - 逻辑重复错误:把
channel = f'#{channel}'写在循环内,每次迭代都会重复拼接#符号,最终会生成##xxx格式的错误频道名 - IO操作冗余:每次循环都重新打开读取一次
cookies.txt,完全无必要,放在循环外读取一次即可
修复后参考代码
import socket import random import ssl server = "irc.example.com" # IRC SSL端口默认是6697,普通未加密端口是6667,按需调整 PORT = 6697 def main(nummessages, channel, message): # 提前读取账号信息,避免循环内重复读文件 with open('cookies.txt', 'r') as f: account_list = f.read().splitlines() # 提前处理频道名,避免循环内重复拼接# target_channel = f'#{channel}' for i in range(nummessages): # 每次循环新建一个socket连接(如果要复用连接就把这部分移到循环外,不要每次关socket) raw_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # SSL封装适配加密端口 ircsock = ssl.wrap_socket(raw_sock) ircsock.connect((server, PORT)) # 随机取账号 info = random.choice(account_list).split(':') token = info[1] username = info[0] # 所有IRC命令统一用\r\n结尾 ircsock.send(bytes(f'NICK {username}\r\n', 'UTF-8')) ircsock.send(bytes(f'PASS oauth:{token}\r\n', 'UTF-8')) ircsock.send(bytes(f'JOIN {target_channel}\r\n', 'UTF-8')) ircsock.send(bytes(f'PRIVMSG {target_channel} :{message}\r\n', 'UTF-8')) ircsock.send(bytes(f'PART {target_channel}\r\n', 'UTF-8')) ircsock.send(bytes(f'QUIT :Bye\r\n', 'UTF-8')) # 关闭当前连接 ircsock.shutdown(socket.SHUT_RDWR) ircsock.close() # 调用示例 test1 = 1 test2 = "test" test3 = "test" main(test1, test2, test3)
内容的提问来源于stack exchange,提问作者Level420
相关产品推荐
相关产品推荐

