Python網路編程 (三)使用select.select()實現聊天伺服器

來源:互聯網
上載者:User

標籤:nts   rgs   try   資訊   socket   nal   通過   pack   cts   

第一步, 實現通用的send()和receive()函數:

send函數定義通過cPicle.dumps()將需要發送的資料序列化,然後通過socket.htonl()方法將序列化後的資料長度轉化為網路位元組序格式,以便於底層傳輸,再將網路位元組序格式的長度打包為‘L‘類型的C struct, 最後發送打包後的長度以及序列化後的資料

receive函數即是send反向過程,先接收到打包後的長度,將其解包,然後再主機序列化,所有資料接收完成以後,返回解除序列化後的未經處理資料。

 

 1 def send(channel, *args): 2     data = cPickle.dumps(*args) 3     htonl_size = socket.htonl(len(data)) 4     size = struct.pack("L", htonl_size) 5     channel.send(size) 6     channel.send(data) 7  8 def receive(channel): 9      recv_size = struct.calsize("L")10      data_size = channel.recv(recv_size) # receive size‘s value11      try:12           size = socket.ntohl(struct.unpack("L", data_size)[0])13      except struct.error, e:14           return ‘‘15      data = ‘‘16      while len(data) < data_size:17           data = channel.recv(data_size - len(data))18      return cPickle.loads(data)

 第二步,建立ChatServer類:

聊天室伺服器需要能做到: 1,記錄串連數  2,記錄串連的用戶端地址以及名稱映射 ,需要時返回名稱地址 3,重用地址 4,檢測鍵盤中斷 5,處理輸入及請求

先實現1,2,3,4點:

 1 class ChatServer(object): 2     def __init__(self, port, backlog=5): 3         self.clients = " # record client number 4         self.clientmap = {} # client address and name‘s mapping 5         self.outputs = [] # socket output objects‘ list 6         self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7         self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 8         self.server.bind((SERVER_HOST, port) 9         self.server.listen(backlog)10         signal.signal(signal.SIGINT, self.sighandler)11 12     def sighandler(self, signum, frame):13         print "Shutting down server..."14         for output in outputs:15              output.close(0)16         self.server.close()17 18     def get_client_name(self, client):19         info = self.clientmap[client]20         host, name = info[0][0], info[1]21         return ‘@‘.join((name, host))22    

 第5點處理輸入及請求分幾種情況,1處理用戶端接入並通知其他用戶端,2處理用戶端輸入資訊並轉寄給其他用戶端,處理標準輸入, 這裡丟棄,3處理異常

 1     def run(self): 2         inputs = [self.server, sys.stdin] #inputs for select.select() first arg 3         self.outputs = [] # define outputs for select.select(), second arg 4         running = True 5         while running: 6             try: 7                 readable, writeable, exceptional =  8                     select.selcet(inputs, self.outputs, []) 9             except select.error, e:10                 break11             12             for sock in readable:13                 if sock == self.server:14                     client, address = self.server.accept()15                     print "Chat server: got connection %d from %s" % \ 16                         (client.fileno, address)17                     cname = receive(client).spilt(‘NAME: ‘)[1]18                     self.clients += 119                     send(client, "CLIENT: " + str(address[0])20                     inputs.append(client)21                     self.clientmap[client] = (address, cname)22                     # send joining information to other clients23                     msg = ‘\n (Connected: New client (%d) from %s" % 24                          (self.clients, self.get_client_name(client))‘25                     for output in self.outputs:26                         send(output, msg)27                     self.outputs.append(client)28               29                  elif sock == sys.stdin:30                      junk = sys.stdin.readable()31                      running = False32                  else:33                      try:34                          data = receive(sock)35                          if data:36                              msg = ‘\n#[‘ + self.get_client_name(sock) + 37                                  ‘]>>‘ + data38                              for output in self.outputs:39                                  if output != sock:40                                      send(output.msg)41                          else:42                              print "Chat server: %d hung up" % sock.fileno()43                              self.clients -= 144                              sock.close()45                              inputs.remove(sock)46                              self.outputs.remove(sock)47                              msg = ‘\n(now hung up: client from %s)‘ % \ 48                                   sef.get_client_name(sock)49                              for output in self.outputs:50                                  send(output, msg)51                     except socket.error, e:52                         inputs.remove(sock)53                         self.outputs.remove(sock)54              55             self.server.close()

 

Python網路編程 (三)使用select.select()實現聊天伺服器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.