这是python中多线程服务器和客户端的源代码.
在代码客户端和服务器完成作业后关闭连接.我希望保持连接存活并通过相同的连接发送更多数据,以避免每次关闭和打开套接字的开销.
以下代码来自:http://www.devshed.com/c/a/Python/Basic-Threading-in-Python/1/
import pickle import socket import threading # We'll pickle a list of numbers: someList = [ 1, 2, 7, 9, 0 ] pickledList = pickle.dumps ( someList ) # Our thread class: class ClientThread ( threading.Thread ): # Override Thread's __init__ method to accept the parameters needed: def __init__ ( self, channel, details ): self.channel = channel self.details = details threading.Thread.__init__ ( self ) def run ( self ): print 'Received connection:', self.details [ 0 ] self.channel.send ( pickledList ) for x in xrange ( 10 ): print self.channel.recv ( 1024 ) self.channel.close() print 'Closed connection:', self.details [ 0 ] # Set up the server: server = socket.socket ( socket.AF_INET, socket.SOCK_STREAM ) server.bind ( ( '', 2727 ) ) server.listen ( 5 ) # Have the server serve "forever": while True: channel, details = server.accept() ClientThread ( channel, details ).start()
import pickle import socket import threading # Here's our thread: class ConnectionThread ( threading.Thread ): def run ( self ): # Connect to the server: client = socket.socket ( socket.AF_INET, socket.SOCK_STREAM ) client.connect ( ( 'localhost', 2727 ) ) # Retrieve and unpickle the list object: print pickle.loads ( client.recv ( 1024 ) ) # Send some messages: for x in xrange ( 10 ): client.send ( 'Hey. ' + str ( x ) + '\n' ) # Close the connection client.close() # Let's spawn a few threads: for x in xrange ( 5 ): ConnectionThread().start()
nosklo.. 20
为每个连接产生一个新线程是一个非常糟糕的设计选择.如果你被很多连接击中会发生什么?
实际上,使用线程等待网络IO是不值得的.你的程序变得非常复杂,你绝对没有任何好处,因为在线程中等待网络不会让你等待更快.在这种情况下,您只会因使用线程而丢失.
以下文本来自python文档:
只有两种方法让一个程序在一个处理器上做"一次不止一件事."多线程编程是最简单和最流行的方法,但还有另一种非常不同的技术,它可以让你几乎没有多线程的所有优点,没有实际使用多线程.如果您的程序主要受I/O限制,那么它真的很实用.如果您的程序受处理器限制,那么先发制人的预定线程可能就是您真正需要的.但是,网络服务器很少受处理器限制.
如果它是处理器绑定的服务器案例.您可以随时留下另一个进程/线程来执行处理器部分.继续:
如果您的操作系统支持其I/O库中的select系统调用(几乎所有操作系统),那么您可以使用它来同时处理多个通信通道; 当你的I/O在"背景"中进行时做其他工作.尽管这个策略看起来很奇怪和复杂,特别是起初,它在很多方面比多线程编程更容易理解和控制.
因此,不使用线程,而是使用非阻塞输入/输出:收集列表中的套接字并使用带有select.select的事件循环来知道哪个套接字有要读取的数据.在单个线程中执行此操作.
您可以选择一个python异步网络框架,如扭曲为您做到这一点.这将为您节省很多麻烦.Twisted的代码已经改进多年了,并涵盖了你需要时间掌握的一些极端情况.
编辑:任何现有的异步IO库(如Twisted)都是python代码.你可以自己写,但它已经为你写了.我不明白为什么你不会使用其中一个库而是编写自己最差的代码,因为你是初学者.Networing IO很难做到.
为每个连接产生一个新线程是一个非常糟糕的设计选择.如果你被很多连接击中会发生什么?
实际上,使用线程等待网络IO是不值得的.你的程序变得非常复杂,你绝对没有任何好处,因为在线程中等待网络不会让你等待更快.在这种情况下,您只会因使用线程而丢失.
以下文本来自python文档:
只有两种方法让一个程序在一个处理器上做"一次不止一件事."多线程编程是最简单和最流行的方法,但还有另一种非常不同的技术,它可以让你几乎没有多线程的所有优点,没有实际使用多线程.如果您的程序主要受I/O限制,那么它真的很实用.如果您的程序受处理器限制,那么先发制人的预定线程可能就是您真正需要的.但是,网络服务器很少受处理器限制.
如果它是处理器绑定的服务器案例.您可以随时留下另一个进程/线程来执行处理器部分.继续:
如果您的操作系统支持其I/O库中的select系统调用(几乎所有操作系统),那么您可以使用它来同时处理多个通信通道; 当你的I/O在"背景"中进行时做其他工作.尽管这个策略看起来很奇怪和复杂,特别是起初,它在很多方面比多线程编程更容易理解和控制.
因此,不使用线程,而是使用非阻塞输入/输出:收集列表中的套接字并使用带有select.select的事件循环来知道哪个套接字有要读取的数据.在单个线程中执行此操作.
您可以选择一个python异步网络框架,如扭曲为您做到这一点.这将为您节省很多麻烦.Twisted的代码已经改进多年了,并涵盖了你需要时间掌握的一些极端情况.
编辑:任何现有的异步IO库(如Twisted)都是python代码.你可以自己写,但它已经为你写了.我不明白为什么你不会使用其中一个库而是编写自己最差的代码,因为你是初学者.Networing IO很难做到.