[英]threaded TCP sockets with python
我是python編程和套接字的新手,所以我從http://docs.python.org/2/library/socketserver.html處的異步(線程)SocketServer示例開始。
ThreadingMixIn類的示例運行良好,但是對於專家我有兩個問題:
每個新連接都會創建一個新線程,很好。 但是似乎線程永遠不會終止,即使另一側的連接隨着線程數量的增加而關閉。
第二個問題是關於handle方法。 我嘗試從客戶端使用sendall發送2條連續消息,但是第二次發送失敗...看來,實際上handle方法等待第一條消息,然后終止。 我必須添加“ while 1:”才能開始工作。
因此,總而言之,我感到這個示例是無用且不好的,因為它只是創建了一個只能接收一條消息的線程。 如果至少它會自行終止,但對我而言似乎並非如此……
感謝您的投入!
這是服務器的代碼:
import threading
import SocketServer
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
data = self.request.recv(1024)
cur_thread = threading.current_thread()
response = "{}: {}".format(cur_thread.name, data)
self.request.sendall(response)
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
if __name__ == "__main__":
server = ThreadedTCPServer(('localhost', 13009), ThreadedTCPRequestHandler)
# Start a thread with the server -- that thread will then start one
# more thread for each request
server_thread = threading.Thread(target=server.serve_forever)
# Exit the server thread when the main thread terminates
server_thread.daemon = True
server_thread.start()
print "Server loop running in thread:", server_thread.name
raw_input("Hit enter to stop the server")
server.shutdown()
和客戶的代碼:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 13009))
try:
sock.sendall('hello\n')
response = sock.recv(1024)
print "Received: {}".format(response)
# A second 'send' will generate an error on Windows.
# On Mac, no error but the received message is empty as the
# handle method in the server isn't called for each new message
sock.sendall('how are you?')
response = sock.recv(1024)
print "Received: {}".format(response)
except socket.error, (value,message):
print "Error: " + message
finally:
sock.close()
如您所見,每次運行客戶端代碼時,即使先前的套接字已關閉,也會創建一個新線程……或者至少,threading.current_thread()返回一個新的ID。 如何檢查上一個線程是否已停止?
關於@luka的答案; Dietrich是正確的,因為以這種方式使用線程很好。 是的,您只能在給定時間執行一條python指令,但是套接字無論如何通常都是I / O綁定的,所以一切都很好。
知道線程已死亡的最簡單方法不是直接從python中獲取,因為這與您使用的接口有些相似。 相反,我會看一下可以提供此信息的操作系統。 在Linux上,只需執行pstree
命令。 您的線程數應顯示為<thread count>*[{process name}]
,其中線程數是您的線程數。
其他方法包括讓您的應用程序打印“狀態線程”,“結束線程”或使用調試的python(pydb)。
關於@luka關於事件驅動的python的最后一點,這是一種過早的優化。 如果您不希望應用程序承受巨大的負擔,請不必擔心。 如果您期望一個巨大的負載,則每個請求的線程派生可能會成為需要解決的瓶頸。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.