用python编写客户机-服务器程序?

2024-05-09 14:18:26 发布

您现在位置:Python中文网/ 问答频道 /正文

这是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()

Tags: theinimportselfclientserverinitchannel
3条回答

我不确定我是否理解这个问题,但如果您不想关闭连接,请不要调用close()。。。

例如,客户端保持TCP连接打开并使用熟悉的协议, 看看telnetlib modulesource。(抱歉,其他人必须回答您的线程问题。)

SocketServer module(任何标准的Python安装都包括源代码)的源代码中有一个保持TCP连接打开的服务器示例。

为每个连接生成一个新线程是一个非常糟糕的设计选择。 如果你被很多人打了怎么办?

事实上,使用线程等待网络IO是不值得的。您的程序变得非常复杂,而且您完全没有好处,因为在线程中等待网络不会让您更快地等待。在这种情况下,使用线程只会失败。

以下文本来自python文档:

There are only two ways to have a program on a single processor do “more than one thing at a time.” Multi-threaded programming is the simplest and most popular way to do it, but there is another very different technique, that lets you have nearly all the advantages of multi-threading, without actually using multiple threads. It’s really only practical if your program is largely I/O bound. If your program is processor bound, then pre-emptive scheduled threads are probably what you really need. Network servers are rarely processor bound, however.

如果是处理器绑定的服务器案例。您总是可以留下另一个进程/线程来完成处理器部分。继续:

If your operating system supports the select system call in its I/O library (and nearly all do), then you can use it to juggle multiple communication channels at once; doing other work while your I/O is taking place in the “background.” Although this strategy can seem strange and complex, especially at first, it is in many ways easier to understand and control than multi-threaded programming.

因此,不要使用线程,而是使用非阻塞输入/输出:收集列表中的套接字,并使用带有select.select的事件循环来知道哪个套接字有数据要读取。用一根线做。

您可以选择像twisted这样的python异步网络框架来实现这一点。这会让你省去很多头疼的事。Twisted的代码已经改进了很多年,并且涵盖了一些你需要花时间掌握的角落案例。

编辑:任何现有的异步IO库(如Twisted)都是python代码。你本可以自己写的,但已经为你写了。我不明白为什么你不使用这些库中的一个来编写自己最差的代码,因为你是一个初学者。网络IO很难实现。

相关问题 更多 >