最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python實(shí)現(xiàn)一個(gè)服務(wù)器監(jiān)聽(tīng)多個(gè)客戶端請(qǐng)求

 更新時(shí)間:2018年04月12日 14:39:01   作者:驚瑟  
這篇文章主要為大家詳細(xì)介紹了Python如何實(shí)現(xiàn)一個(gè)服務(wù)器監(jiān)聽(tīng)多個(gè)客戶端請(qǐng)求,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

學(xué)習(xí)Python網(wǎng)絡(luò)通信的時(shí)候發(fā)現(xiàn)書(shū)上只有一個(gè)服務(wù)端對(duì)應(yīng)一個(gè)客戶端的情形,于是自己想自己動(dòng)手實(shí)現(xiàn)一個(gè)服務(wù)端響應(yīng)多個(gè)客戶端。

首先建立服務(wù)器的socket來(lái)監(jiān)聽(tīng)客戶端的請(qǐng)求:

tcpSerSock=socket(AF_INET,SOCK_STREAM) 
tcpSerSock.bind(ADDR) 
tcpSerSock.listen(5) 

這樣服務(wù)器的監(jiān)聽(tīng)socket就建好了。

接下來(lái)的思路是,如果要監(jiān)聽(tīng)多個(gè)客戶端,則

tcpSerSock.accept() #(accept()是阻塞式的) 

必須放進(jìn)一個(gè)while循環(huán)(不放進(jìn)循環(huán)監(jiān)聽(tīng)一次就沒(méi)了)。然而,這里就有問(wèn)題了。如果按照一對(duì)一的那種處理順序,客戶端A連進(jìn)來(lái)后,程序順序向下執(zhí)行,服務(wù)端要再寫(xiě)一個(gè)while循環(huán),用來(lái)處理客戶端A的請(qǐng)求,如果此時(shí)客戶端B再來(lái)請(qǐng)求,服務(wù)器將接收不到。于是,很自然想到,將監(jiān)聽(tīng)和處理放到不同的線程進(jìn)行處理。我選擇將監(jiān)聽(tīng)放入主線程,將處理放進(jìn)子線程。該服務(wù)器功能為接收到客戶端的數(shù)據(jù)加上時(shí)間戳后返回給客戶端。服務(wù)端完整代碼如下:

#coding=utf-8 
#!/usr/bin/env python 
''''' 
author:Mr.Jing 
created on Fri Sep 22 14:29:03 2017 
platfrom:win10,python2.7 
''' 
 
from socket import * 
from time import ctime 
import threading 
import time 
HOST='' 
PORT=2159 
BUFSIZ=1024 
ADDR = (HOST,PORT) 
 
tcpSerSock=socket(AF_INET,SOCK_STREAM) 
tcpSerSock.bind(ADDR) 
tcpSerSock.listen(5) 
socks=[]        #放每個(gè)客戶端的socket 
 
def handle(): 
 while True: 
  for s in socks: 
   data = s.recv(BUFSIZ) 
   if not data: 
    socks.remove(s) 
    continue 
   s.send('[%s],%s' % (ctime(), data)) #加上時(shí)間戳返回 
 
t = threading.Thread(target=handle)    #子線程 
if __name__ == '__main__': 
 t.start() 
 print u'我在%s線程中 ' % threading.current_thread().name #本身是主線程 
 print 'waiting for connecting...' 
 while True: 
  clientSock,addr = tcpSerSock.accept() 
  print 'connected from:', addr 
  socks.append(clientSock) 

兩個(gè)客戶端A和B同時(shí)連接,服務(wù)器輸出:

可以看到服務(wù)端是可以相應(yīng)多個(gè)客戶端的。

客戶端A發(fā)條消息試試?

服務(wù)器返回來(lái)了帶時(shí)間戳的消息,goodjob。

那另一個(gè)呢?

很棒。服務(wù)器都能做出響應(yīng)。

再發(fā)一條試試?

發(fā)現(xiàn)服務(wù)器沒(méi)響應(yīng)了,這是怎么回事呢?

經(jīng)過(guò)仔細(xì)勘察發(fā)現(xiàn)是因?yàn)檫@句:

data = s.recv(BUFSIZ) 

因?yàn)閞ecv方法是阻塞的,也就是說(shuō),當(dāng)輪訓(xùn)到某個(gè)客戶端,比如A,這句等待A發(fā)消息,不發(fā)消息就不往下走,所以此時(shí)B再去發(fā)消息的話服務(wù)器就收不到了。

那該怎么辦呢?

很容易想到,將其設(shè)為非阻塞就好了。但上網(wǎng)找了好久,雖然找到可以用setblocking(0)  將套接字設(shè)為非阻塞,然而具體怎么用卻很少有人講清楚。查資料后終于搞明白,非阻塞的recv方法會(huì)繼續(xù)向下執(zhí)行,若超時(shí)得不到數(shù)據(jù)則會(huì)拋出異常。

修改后的代碼如下:

#coding=utf-8 
#!/usr/bin/env python 
''''' 
author:Mr.Jing 
created on Fri Sep 22 14:29:03 2017 
platfrom:win10,python2.7 
''' 
 
from socket import * 
from time import ctime 
import threading 
import time 
HOST='' 
PORT=2159 
BUFSIZ=1024 
ADDR = (HOST,PORT) 
 
tcpSerSock=socket(AF_INET,SOCK_STREAM) 
tcpSerSock.bind(ADDR) 
tcpSerSock.listen(5) 
socks=[]        #放每個(gè)客戶端的socket 
 
def handle(): 
 while True: 
  for s in socks: 
   try: 
    data = s.recv(BUFSIZ)  #到這里程序繼續(xù)向下執(zhí)行 
   except Exception, e:   
    continue 
   if not data: 
    socks.remove(s) 
    continue 
   s.send('[%s],%s' % (ctime(), data)) 
 
t = threading.Thread(target=handle)    #子線程 
if __name__ == '__main__': 
 t.start() 
 print u'我在%s線程中 ' % threading.current_thread().name #本身是主線程 
 print 'waiting for connecting...' 
 while True: 
  clientSock,addr = tcpSerSock.accept() 
  print 'connected from:', addr 
  clientSock.setblocking(0) 
  socks.append(clientSock) 

此時(shí)再去嘗試:

客戶端隨便輸都會(huì)得到響應(yīng)。任務(wù)達(dá)成!

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • numpy.unique()使用方法

    numpy.unique()使用方法

    本文主要介紹了numpy.unique()使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • python掌握字符串只需這一篇就夠了

    python掌握字符串只需這一篇就夠了

    字符串是 Python 中最常用的數(shù)據(jù)類(lèi)型。我們可以使用引號(hào)('或")來(lái)創(chuàng)建字符串。創(chuàng)建字符串很簡(jiǎn)單,只要為變量分配一個(gè)值即可
    2021-11-11
  • Python flashtext文本搜索和替換操作庫(kù)功能使用探索

    Python flashtext文本搜索和替換操作庫(kù)功能使用探索

    本文將深入介紹Python flashtext庫(kù),包括其基本用法、功能特性、示例代碼以及實(shí)際應(yīng)用場(chǎng)景,以幫助大家更好地利用這個(gè)有用的工具
    2024-01-01
  • Python實(shí)現(xiàn)判斷并移除列表指定位置元素的方法

    Python實(shí)現(xiàn)判斷并移除列表指定位置元素的方法

    這篇文章主要介紹了Python實(shí)現(xiàn)判斷并移除列表指定位置元素的方法,涉及Python針對(duì)列表的索引范圍判斷及元素刪除等相關(guān)操作技巧,需要的朋友可以參考下
    2018-04-04
  • python opencv把一張圖片嵌入(疊加)到另一張圖片上的實(shí)現(xiàn)代碼

    python opencv把一張圖片嵌入(疊加)到另一張圖片上的實(shí)現(xiàn)代碼

    這篇文章主要介紹了python opencv把一張圖片嵌入(疊加)到另一張圖片上,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • python的XIsxWriter操作Excel示例詳解

    python的XIsxWriter操作Excel示例詳解

    這篇文章主要介紹了python的XIsxWriter操作Excel示例詳解,xlsxwriter是一個(gè)專(zhuān)門(mén)用于創(chuàng)建、寫(xiě)入和操作Excel文件的Python模塊,它提供了豐富的功能和選項(xiàng),能夠創(chuàng)建復(fù)雜的Excel文檔,需要的朋友可以參考下
    2023-09-09
  • Python ini文件常用操作方法解析

    Python ini文件常用操作方法解析

    這篇文章主要介紹了Python ini文件常用操作方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Python2中文處理紀(jì)要的實(shí)現(xiàn)方法

    Python2中文處理紀(jì)要的實(shí)現(xiàn)方法

    本篇文章主要介紹了Python2中文處理紀(jì)要的實(shí)現(xiàn)方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • 15個(gè)應(yīng)該掌握的Jupyter Notebook使用技巧(小結(jié))

    15個(gè)應(yīng)該掌握的Jupyter Notebook使用技巧(小結(jié))

    這篇文章主要介紹了15個(gè)應(yīng)該掌握的Jupyter Notebook使用技巧(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Python學(xué)習(xí)之內(nèi)置函數(shù)總結(jié)

    Python學(xué)習(xí)之內(nèi)置函數(shù)總結(jié)

    這篇文章主要為大家總結(jié)一下python?中常用的是個(gè)內(nèi)置函數(shù)的使用方法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Python有一定的幫助,需要的可以參考一下
    2022-03-03

最新評(píng)論

昌吉市| 聊城市| 迁西县| 通州区| 青阳县| 潢川县| 阿拉善左旗| 黑龙江省| 屏东县| 阜康市| 凯里市| 彩票| 嘉兴市| 达州市| 堆龙德庆县| 阳朔县| 当涂县| 高雄市| 教育| 长汀县| 北流市| 桂林市| 武川县| 海宁市| 张家港市| 梅河口市| 颍上县| 桑植县| 凤冈县| 友谊县| 连云港市| 泽库县| 华蓥市| 黑河市| 岫岩| 平谷区| 子长县| 玛多县| 西畴县| 湘阴县| 铁岭县|