2016-03-07 16 views
1

我正在使用套接字和多线程进行基本的聊天程序。该程序连接,并在从客户端发送的消息,执行时会提高在服务器端这个错误:使用多线程的基本Socket聊天程序引发错误

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

谢谢:)

回答

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 
+0

谢谢您的回答。我在哪里关闭套接字? –

+0

我是一个初学者:( –

+1

@ J.Clarke:文件的最后一行:'c.close()'。这会关闭连接到客户端的套接字 – mhawke

0

这可能是因为你在socket上调用s.connect()已关闭。你看到你的客户端代码(在你附加的链接中找到),你在while语句里面做s.connect((host, port)),这就是你在后面使用相同代码的s.close语句的问题。若要解决此问题,您需要将s = socket.socket()命令移至您的while语句之前的s.connect((host, port))语句;这将确保s.connect((host, port))语句不会在封闭套接字上执行。