Python 使用多线程的基本套接字聊天程序引发错误

Python 使用多线程的基本套接字聊天程序引发错误,python,multithreading,sockets,networking,Python,Multithreading,Sockets,Networking,我正在使用套接字和多线程制作一个基本的聊天程序。程序已连接,当从客户端发送消息时,执行时会在服务器端引发此错误: 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

我正在使用套接字和多线程制作一个基本的聊天程序。程序已连接,当从客户端发送消息时,执行时会在服务器端引发此错误:

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
完整代码可在此处获得:


谢谢:)

这可能是因为您正在已关闭的套接字上调用
s.connect()
。您可以看到,在客户端代码(在您附加的链接上找到)中,您是如何在
while
语句中执行
s.connect((主机、端口))
的,这导致了同一代码中稍后的
s.close
语句出现问题。要解决此问题,您需要将
s=socket.socket()
命令移动到
while
语句中
s.connect((主机,端口))
语句之前;这将确保
s.connect((主机,端口))
语句不会在关闭的套接字上执行。

启动线程后,代码将关闭服务器和客户端代码中的远程套接字。您需要等待线程完成,然后再关闭其套接字

因此,对于服务器,删除最后一行
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

谢谢你的回答。我在哪里关闭套接字?@J.Clarke:文件的最后一行:
c.close()
。这将关闭连接到客户端的套接字。如果你是初学者,为什么要尝试编写客户端-服务器代码?@MartinJames:OP为什么不应该这样做?要不然他怎么学呢?我认为OP做得很好,因为他们只是初学者。@mhawke谢谢你的建议我已经制作了一个基于服务器、客户端的聊天应用程序,现在我正在积累和提高我的知识。