我正在使用套接字和多线程制作基本的聊天程序。程序已连接,当客户端发送消息时,它会在执行时在服务器端引发此错误:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 810, in __bootstrap_inner
self.run()
File "C:\Python27\lib\threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "C:\Users\jclarke14\Desktop\Server - 2.py", line 25, in check_for_data
data = c.recv(1024)
File "C:\Python27\lib\socket.py", line 174, in _dummy
raise error(EBADF, 'Bad file descriptor')
error: [Errno 9] Bad file descriptor
我是初学者,也是多线程和套接字的新手。我做错了什么?
以下是我的客户代码:
#Check For Incoming Data
def check_for_data():
while True:
data = s.recv(1024)
print "Other: " + data
print
#Send Data
def send_data():
while True:
message = raw_input("You: ")
print
s.sendall(message)
#Start Threads
t = threading.Thread(target=send_data)
t.daemon = True
t.start() #1
t = threading.Thread(target=check_for_data)
t.daemon = True
t.start() #2
服务器代码:
c, addr = s.accept()
print "Connection From: " + str(addr)
print
def check_for_data():
while True:
data = c.recv(1024)
print "Other: " + str(data)
print
def send_data():
while True:
message = raw_input("You: ")
print
c.sendall(message)
#Start Threads
t = threading.Thread(target=send_data)
t.daemon = True
t.start() #1
t = threading.Thread(target=check_for_data)
t.daemon = True
t.start() #2
完整代码可在此处找到:https://drive.google.com/folderview?id=0B3t3mUQs3K-iLWY3Y3JZX2YzU2c&usp=sharing
谢谢你:)
答案 0 :(得分:1)
启动线程后,您的代码将关闭服务器和客户端代码中的远程套接字。在关闭它之前,你需要等待线程完成。
因此,对于服务器,删除最后一行c.close()
。您可以使用t.join()
在主线程中等待子线程。之后你可以关闭套接字。
您还可以更改线程代码,以便在远程客户端关闭套接字时终止。最好将套接字传递给线程,而不是让线程访问全局变量:
def check_for_data(c):
while True:
data = c.recv(1024)
if data:
print "Other: " + str(data)
else:
print "Client closed connection"
c.close()
break
t = threading.Thread(target=check_for_data, args=(c,))
t.daemon = True
t.start()
t.join()
#c.close() # if you don't close it in the thread
s.close() # close the main server socket
答案 1 :(得分:0)
这可能是因为您在已关闭的套接字上调用s.connect()
。您可以在客户端代码中找到(在您附加的链接中找到),在s.connect((host, port))
语句中执行while
,这会导致您稍后在s.close
语句中出现问题相同的代码。要解决此问题,您需要在s = socket.socket()
语句之前将while
命令移动到s.connect((host, port))
语句中;这将确保s.connect((host, port))
语句不会在已关闭的套接字上执行。