2016-03-07 38 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))語句不會在封閉套接字上執行。