2011-09-13 70 views
2

我已經成功地實現與多個客戶端簡單的服務器:優化簡單的服務器與多個客戶端

class ProcessingServer: 
    def __init__(self, bindaddress="127.0.0.1", portname=50001, maxqueue=5): 
     self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.socket.bind((bindaddress, portname)) 
     self.socket.listen(maxqueue) 
     self.inputsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.data = [] 

    def start(self): 
     rsocks, wsocks = [], [] 
     rsocks.append(self.socket) 
     rsocks.append(self.inputsocket) 
     print "Waiting for connection..." 
     self.inputsocket.connect(("192.168.1.1", 1234)) 
     print "Connected." 
     clients = [] 

     try: 
      while True: 
       try: 
        reads, writes, errs = select.select(rsocks, wsocks, []) 
       except: 
        return 
       for sock in reads: 
        if sock == self.socket: 
         client, address = sock.accept() 
         print "Client ", address, " connected" 
         wsocks.append(client) 
         clients.append(client) 
        elif sock == self.inputsocket: 
         self.data.append(sock.recv(256)) 

       outstring = "" 
       if len(self.data) > 1: 
        msg_list = self.data[0].split('\n') 
        for msg in msg_list: 
         if msg != '': 
          curr_msg = msg.split(',') 
          process_message(curr_msg) 
          outstring = ','.join(curr_msg) 
          print curr_msg 
        self.data = [] 

       for sock in writes: 
        if sock in clients: 
         if outstring != "": 
          sock.send(outstring) 

     except KeyboardInterrupt: 
      print "Server was stopped" 
      self.inputsocket.close() 
      self.socket.close() 
      for sock in writes: 
       sock.close() 
      for sock in reads: 
       sock.close() 
      for sock in clients: 
       sock.close() 

process_message只是增加了某些字段

一切工作正常,但是當客戶端連接到服務器,CPU負載變到100%。

這裏的客戶端:

import socket 
mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
mysocket.connect(("127.0.0.1", 50001)) 
while True: 
    data = mysocket.recv(512) 
mysocket.close() 
outfile.close() 

這裏是探查統計:

ncalls tottime percall cumtime percall filename:lineno(function) 
     1 0.000 0.000 34.563 34.563 <string>:1(<module>) 
     1 0.000 0.000 0.000 0.000 <string>:1(bind) 
     1 0.000 0.000 0.000 0.000 <string>:1(connect) 
    6870763 6.408 0.000 9.030 0.000 <string>:1(fileno) 
     1 0.000 0.000 0.000 0.000 <string>:1(listen) 
     1 0.000 0.000 0.000 0.000 server.py:113(__init__) 
     1 4.409 4.409 34.556 34.556 server.py:123(start) 
     1 0.007 0.007 34.563 34.563 server.py:176(main) 
     91 0.002 0.000 0.010 0.000 server.py:80(process_message) 
     3 0.000 0.000 0.000 0.000 socket.py:182(__init__) 
     1 0.000 0.000 0.000 0.000 socket.py:196(accept) 
     18 0.000 0.000 0.000 0.000 {getattr} 
    2290358 0.906 0.000 0.906 0.000 {len} 
     1 0.000 0.000 0.000 0.000 {method 'accept' of '_socket.socket' objects} 
     186 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects} 
     1 0.000 0.000 0.000 0.000 {method 'bind' of '_socket.socket' objects} 
     1 0.000 0.000 0.000 0.000 {method 'connect' of '_socket.socket' objects} 
     1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 
    6870763 2.622 0.000 2.622 0.000 {method 'fileno' of '_socket.socket' objects} 
     273 0.000 0.000 0.000 0.000 {method 'insert' of 'list' objects} 
     91 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects} 
     1 0.000 0.000 0.000 0.000 {method 'listen' of '_socket.socket' objects} 
     182 0.001 0.000 0.001 0.000 {method 'recv' of '_socket.socket' objects} 
     71 0.001 0.000 0.001 0.000 {method 'send' of '_socket.socket' objects} 
     182 0.000 0.000 0.000 0.000 {method 'split' of 'str' objects} 
    2290268 20.197 0.000 29.227 0.000 {select.select} 
     18 0.000 0.000 0.000 0.000 {setattr} 

這有什麼錯呢?

+0

1)你如何檢查CPU負載達到100 %,2)你使用的是什麼環境 – varela

+0

@varela:通過系統監視器。我使用的是Ubuntu 10.10。 – qutron

回答

1

我建議select返回,有一些可寫的套接字。還有,如果沒有可讀的套接字並且外接字符串保持爲'',那麼您立即一次又一次地運行循環,導致高cpu負載。所以它可能更好,如果你真的需要寫數據只添加wsocks。然後,選擇呼叫將等待數據可供讀取。

關於你的評論,替換:

reads, writes, errs = select.select(rsocks, wsocks, []) 

reads, writes, errs = select.select(rsocks, [], []) 

,並添加for sock in writes:加的面前:

reads, writes, errs = select.select([], wsocks, [], 0) 
+0

那麼,我應該在腳本中改變什麼? – qutron

+0

我更新了答案。 – rumpel

相關問題