亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Python實現的服務器示例小結【單進程、多進程、多線程、非阻塞式】

系統 1926 0

本文實例講述了Python實現的服務器。分享給大家供大家參考,具體如下:

python - 單進程服務器

            
#coding=utf-8
from socket import *
#創建套接字
serSocket = socket(AF_INET, SOCK_STREAM)
#重復使用綁定信息
serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
localAddr = ('', 7788)
#綁定端口ip
serSocket.bind(localAddr)
#監聽
serSocket.listen(5)
while True:
  print('---主進程,等待新客戶端的到來---')
  newSocket,destAddr = serSocket.accept()
  print('---主進程,接下來負責數據處理[%s]---'%str(destAddr))
  try:
    while True:
      recvData = newSocket.recv(1024)
      if len(recvData)>0:
        print('recv[%s]:%s'%(str(destAddr),recvData))
      else:
        print('[%s]客戶端已經關閉')
        break
  finally:
    newSocket.close()
serSocket.close()


          

總結

同一時刻只能為一個客戶進行服務,不能同時為多個客戶服務。
當服務器為一個客戶端服務時,另外的客戶端發起了connect,只要服務器listen的隊列有空閑的位置,就會為這個新客戶端進行連接,并且客戶端可以發送數據,但當服務器為這個新客戶端服務時,可能一次性把所有數據接收完畢當recv接收數據時,返回值為空,即沒有返回數據,那么意味著客戶端已經調用了close關閉了;因此服務器通過判斷recv接收數據是否為空 來判斷客戶端是否已經下線。

python - 多進程服務器

            
#coding=utf-8
from socket import *
from multiprocessing import *
from time import sleep
#處理客戶端的請求并為其服務
def dealWithClient(newSocket,destAddr):
  try:
    while True:
      recvData = newSocket.recv(1024)
      if len(recvData) > 0:
        print('recv[%s]:%s' % (str(destAddr), recvData))
      else:
        print('[%s]客戶端已經關閉')
        break
  finally:
    newSocket.close()
def main():
  #創建套接字
  serSocket = socket(AF_INET, SOCK_STREAM)
  #重復使用綁定信息
  serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
  localAddr = ('', 7788)
  #綁定端口ip
  serSocket.bind(localAddr)
  #監聽
  serSocket.listen(5)
  try:
    while True:
      print('---主進程,等待新客戶端的到來---')
      newSocket,destAddr = serSocket.accept()
      print('---主進程,接下來負責數據處理[%s]---'%str(destAddr))
      client = Process(target=dealWithClient, args=(newSocket, destAddr))
      client.start()
      # 因為已經向子進程中copy了一份(引用),并且父進程中這個套接字也沒有用處了
      # 所以關閉
      newSocket.close()
  finally:
    # 當為所有的客戶端服務完之后再進行關閉,表示不再接收新的客戶端的鏈接
    serSocket.close()
if __name__ == '__main__':
  main()


          

總結

通過為每個客戶端創建一個進程的方式,能夠同時為多個客戶端進行服
務當客戶端不是特別多的時候,這種方式還行,如果有成百上千個,就不
可取了,因為每次創建進程的過程需要消耗較多的資源。

python - 多線程服務器

            
#coding=utf-8
from socket import *
from threading import Thread
from time import sleep
# 處理客戶端的請求并執行事情
def dealWithClient(newSocket,destAddr):
  while True:
    recvData = newSocket.recv(1024)
    if len(recvData)>0:
      print('recv[%s]:%s'%(str(destAddr), recvData))
    else:
      print('[%s]客戶端已經關閉'%str(destAddr))
      break
  newSocket.close()
def main():
  serSocket = socket(AF_INET, SOCK_STREAM)
  serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR , 1)
  localAddr = ('', 7788)
  serSocket.bind(localAddr)
  serSocket.listen(5)
  try:
    while True:
      print('-----主進程,,等待新客戶端的到來------')
      newSocket,destAddr = serSocket.accept()
      print('-----主進程,,接下來創建一個新的進程負責數據處理[%s]----'%str(destAddr))
      client = Thread(target=dealWithClient, args=(newSocket,destAddr))
      client.start()
      #因為線程中共享這個套接字,如果關閉了會導致這個套接字不可用,
      #但是此時在線程中這個套接字可能還在收數據,因此不能關閉
      #newSocket.close()
  finally:
    # 當為所有的客戶端服務完之后再進行關閉,表示不再接收新的客戶端的鏈接
    serSocket.close()
if __name__ == '__main__':
  main()


          

單進程服務器-非堵塞模式

服務器:

            
#coding=utf-8
from socket import *
import time
# 用來存儲所有的新鏈接的socket
g_socketList = []
def main():
  serSocket = socket(AF_INET, SOCK_STREAM)
  serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR , 1)
  localAddr = ('', 7788)
  serSocket.bind(localAddr)
  #可以適當修改listen中的值來看看不同的現象
  serSocket.listen(1000)
  #將套接字設置為?堵塞
  #設置為?堵塞后,如果accept時,恰巧沒有客戶端connect,那么accept會
  #產生一個異常,所以需要try來進行處理
  serSocket.setblocking(False)
  while True:
    #?來測試
    #time.sleep(0.5)
    try:
      newClientInfo = serSocket.accept()
    except Exception as result:
      pass
    else:
      print("一個新的客戶端到來:%s"%str(newClientInfo))
      newClientInfo[0].setblocking(False)
      g_socketList.append(newClientInfo)
  # 用來存儲需要刪除的客戶端信息
  needDelClientInfoList = []
  for clientSocket,clientAddr in g_socketList:
    try:
      recvData = clientSocket.recv(1024)
      if len(recvData)>0:
        print('recv[%s]:%s'%(str(clientAddr), recvData))
      else:
        print('[%s]客戶端已經關閉'%str(clientAddr))
        clientSocket.close()
        g_needDelClientInfoList.append((clientSocket,clientAddr))
    except Exception as result:
      pass
  for needDelClientInfo in needDelClientInfoList:
    g_socketList.remove(needDelClientInfo)
if __name__ == '__main__':
  main()


          

客戶端:

            
#coding=utf-8
from socket import *
import random
import time
serverIp = input("請輸入服務器的ip:")
connNum = input("請輸入要鏈接服務器的次數(例如1000):")
g_socketList = []
for i in range(int(connNum)):
  s = socket(AF_INET, SOCK_STREAM)
  s.connect((serverIp, 7788))
  g_socketList.append(s)
  print(i)
while True:
  for s in g_socketList:
    s.send(str(random.randint(0,100)))
  # 用來測試
  #time.sleep(1)


          

更多關于Python相關內容可查看本站專題:《Python Socket編程技巧總結》、《Python數據結構與算法教程》、《Python函數使用技巧總結》、《Python字符串操作技巧匯總》、《Python入門與進階經典教程》及《Python文件與目錄操作技巧匯總》

希望本文所述對大家Python程序設計有所幫助。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 性欧美高清videosex | 午夜在线观看cao | 成年人免费网址 | 久久九九亚洲精品 | 国产一区亚洲二区三区 | 97在线视频观看 | 中文字幕不卡免费高清视频 | 99在线视频免费 | 欧美日韩北条麻妃一区二区 | 日日噜噜夜夜狠狠久久aⅴ 日日噜噜夜夜狠狠久久丁香 | 久久久久嫩草影院精品 | 国人精品视频在线观看 | 日本囗交做爰视频欧美 | 国产成人影院一区二区 | 国产精品日韩欧美一区二区三区 | 日本综合色 | 婷婷四房综合激情五月性色 | 69av美女| 看看的在线视频国产 | 久久不射网| 亚洲国产天堂久久九九九 | 亚洲免费观看视频 | 久久国产精品国产自线拍免费 | 狠狠色丁香婷婷综合欧美 | 4hu四虎免费影院www | 免费国产之a视频 | 一级毛片真人不卡免费播 | 久久精品国产精品青草图片 | 亚洲国产成人久久综合区 | 狠狠色噜噜狠狠狠狠色综合网 | 99热91| 理论片我不卡在线观看 | 四虎永久免费地址在线网站 | a视频网站 | 国产精品久久久久久久久ktv | 久久天天躁狠狠躁夜夜呲 | 国产91在线 | 日本 | 日本免费不卡视频一区二区三区 | 久久久久久国产精品免费免 | 一区二区视频在线观看 | 亚洲免费观看视频 |