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

python select.select模塊通信全過程解析

 更新時間:2017年09月20日 08:45:11   作者:又見阿郎  
這篇文章主要為大家解析了python select.select模塊通信全過程,具有一定的參考價值,感興趣的小伙伴們可以參考一下

要理解select.select模塊其實主要就是要理解它的參數(shù), 以及其三個返回值。

select()方法接收并監(jiān)控3個通信列表, 第一個是所有的輸入的data,就是指外部發(fā)過來的數(shù)據(jù),第2個是監(jiān)控和接收所有要發(fā)出去的data(outgoing data),第3個監(jiān)控錯誤信息

在網(wǎng)上一直在找這個select.select的參數(shù)解釋, 但實在是沒有, 哎...自己硬著頭皮分析了一下。
readable, writable, exceptional = select.select(inputs, outputs, inputs)

第一個參數(shù)就是服務(wù)器端的socket, 第二個是我們在運行過程中存儲的客戶端的socket, 第三個存儲錯誤信息。
重點是在返回值, 第一個返回的是可讀的list, 第二個存儲的是可寫的list, 第三個存儲的是錯誤信息的
list。

這個也不必深究, 看看代碼自己分析下就能有大概理解。

網(wǎng)上所有關(guān)于select.select的代碼都是差不多的, 但是有些不能運行, 或是不全。我自己重新寫了一份能運行的程序, 做了很多注釋, 好好看看就能搞懂

服務(wù)器端:

# coding: utf-8
import select
import socket
import Queue
from time import sleep


# Create a TCP/IP
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(False)

# Bind the socket to the port
server_address = ('localhost', 8090)
print ('starting up on %s port %s' % server_address)
server.bind(server_address)

# Listen for incoming connections
server.listen(5)

# Sockets from which we expect to read
inputs = [server]

# Sockets to which we expect to write
# 處理要發(fā)送的消息
outputs = []

# Outgoing message queues (socket: Queue)
message_queues = {}

while inputs:
 # Wait for at least one of the sockets to be ready for processing
 print ('waiting for the next event')
 # 開始select 監(jiān)聽, 對input_list 中的服務(wù)器端server 進(jìn)行監(jiān)聽
 # 一旦調(diào)用socket的send, recv函數(shù),將會再次調(diào)用此模塊
 readable, writable, exceptional = select.select(inputs, outputs, inputs)

 # Handle inputs
 # 循環(huán)判斷是否有客戶端連接進(jìn)來, 當(dāng)有客戶端連接進(jìn)來時select 將觸發(fā)
 for s in readable:
  # 判斷當(dāng)前觸發(fā)的是不是服務(wù)端對象, 當(dāng)觸發(fā)的對象是服務(wù)端對象時,說明有新客戶端連接進(jìn)來了
  # 表示有新用戶來連接
  if s is server:
   # A "readable" socket is ready to accept a connection
   connection, client_address = s.accept()
   print ('connection from', client_address)
   # this is connection not server
   connection.setblocking(0)
   # 將客戶端對象也加入到監(jiān)聽的列表中, 當(dāng)客戶端發(fā)送消息時 select 將觸發(fā)
   inputs.append(connection)

   # Give the connection a queue for data we want to send
   # 為連接的客戶端單獨創(chuàng)建一個消息隊列,用來保存客戶端發(fā)送的消息
   message_queues[connection] = Queue.Queue()
  else:
   # 有老用戶發(fā)消息, 處理接受
   # 由于客戶端連接進(jìn)來時服務(wù)端接收客戶端連接請求,將客戶端加入到了監(jiān)聽列表中(input_list), 客戶端發(fā)送消息將觸發(fā)
   # 所以判斷是否是客戶端對象觸發(fā)
   data = s.recv(1024)
   # 客戶端未斷開
   if data != '':
    # A readable client socket has data
    print ('received "%s" from %s' % (data, s.getpeername()))
    # 將收到的消息放入到相對應(yīng)的socket客戶端的消息隊列中
    message_queues[s].put(data)
    # Add output channel for response
    # 將需要進(jìn)行回復(fù)操作socket放到output 列表中, 讓select監(jiān)聽
    if s not in outputs:
     outputs.append(s)
   else:
    # 客戶端斷開了連接, 將客戶端的監(jiān)聽從input列表中移除
    # Interpret empty result as closed connection
    print ('closing', client_address)
    # Stop listening for input on the connection
    if s in outputs:
     outputs.remove(s)
    inputs.remove(s)
    s.close()

    # Remove message queue
    # 移除對應(yīng)socket客戶端對象的消息隊列
    del message_queues[s]

 # Handle outputs
 # 如果現(xiàn)在沒有客戶端請求, 也沒有客戶端發(fā)送消息時, 開始對發(fā)送消息列表進(jìn)行處理, 是否需要發(fā)送消息
 # 存儲哪個客戶端發(fā)送過消息
 for s in writable:
  try:
   # 如果消息隊列中有消息,從消息隊列中獲取要發(fā)送的消息
   message_queue = message_queues.get(s)
   send_data = ''
   if message_queue is not None:
    send_data = message_queue.get_nowait()
   else:
    # 客戶端連接斷開了
    print "has closed "
  except Queue.Empty:
   # 客戶端連接斷開了
   print "%s" % (s.getpeername())
   outputs.remove(s)
  else:
   # print "sending %s to %s " % (send_data, s.getpeername)
   # print "send something"
   if message_queue is not None:
    s.send(send_data)
   else:
    print "has closed "
   # del message_queues[s]
   # writable.remove(s)
   # print "Client %s disconnected" % (client_address)

 # # Handle "exceptional conditions"
 # 處理異常的情況
 for s in exceptional:
  print ('exception condition on', s.getpeername())
  # Stop listening for input on the connection
  inputs.remove(s)
  if s in outputs:
   outputs.remove(s)
  s.close()

  # Remove message queue
  del message_queues[s]

 sleep(1)

客戶端:

# coding: utf-8
import socket


messages = ['This is the message ', 'It will be sent ', 'in parts ', ]

server_address = ('localhost', 8090)

# Create aTCP/IP socket

socks = [socket.socket(socket.AF_INET, socket.SOCK_STREAM), socket.socket(socket.AF_INET, socket.SOCK_STREAM), ]

# Connect thesocket to the port where the server is listening

print ('connecting to %s port %s' % server_address)
# 連接到服務(wù)器
for s in socks:
 s.connect(server_address)

for index, message in enumerate(messages):
 # Send messages on both sockets
 for s in socks:
  print ('%s: sending "%s"' % (s.getsockname(), message + str(index)))
  s.send(bytes(message + str(index)).decode('utf-8'))
 # Read responses on both sockets

for s in socks:
 data = s.recv(1024)
 print ('%s: received "%s"' % (s.getsockname(), data))
 if data != "":
  print ('closingsocket', s.getsockname())
  s.close()

寫代碼過程中遇到了兩個問題, 一是如何判斷客戶端已經(jīng)關(guān)閉了socket連接, 后來自己分析了下, 如果關(guān)閉了客戶端socket, 那么此時服務(wù)器端接收到的data就是'', 加個這個判斷。二是如果服務(wù)器端關(guān)閉了socket, 一旦在調(diào)用socket的相關(guān)方法都會報錯, 不管socket是不是用不同的容器存儲的(意思是說list_1存儲了socket1, list_2存儲了socket1, 我關(guān)閉了socket1, 兩者都不能在調(diào)用這個socket了)

客戶端:

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

相關(guān)文章

  • python 命令行傳入?yún)?shù)實現(xiàn)解析

    python 命令行傳入?yún)?shù)實現(xiàn)解析

    這篇文章主要介紹了python 命令行傳入?yún)?shù)實現(xiàn)解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • 使用Python模塊進(jìn)行數(shù)據(jù)處理的詳細(xì)步驟

    使用Python模塊進(jìn)行數(shù)據(jù)處理的詳細(xì)步驟

    Python 提供了豐富的模塊和庫,用于處理各種類型的數(shù)據(jù),本文介紹了一些常用的模塊和庫,以及如何使用它們進(jìn)行數(shù)據(jù)處理的詳細(xì)步驟和代碼示例,對我們的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2025-02-02
  • Python中的正則表達(dá)式與JSON數(shù)據(jù)交換格式

    Python中的正則表達(dá)式與JSON數(shù)據(jù)交換格式

    正則表達(dá)式 是一個特殊的字符序列,一個字符串是否與我們所設(shè)定的這樣的字符序列,相匹配快速檢索文本、實現(xiàn)替換文本的操作。這篇文章主要介紹了Python中的正則表達(dá)式與JSON ,需要的朋友可以參考下
    2019-07-07
  • Python腳本,標(biāo)識符,變量使用,腳本語句,注釋,模塊引用詳解

    Python腳本,標(biāo)識符,變量使用,腳本語句,注釋,模塊引用詳解

    這篇文章主要為大家詳細(xì)介紹了Python腳本,標(biāo)識符,變量使用,腳本語句,注釋,模塊引用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Python使用OpenCV對圖像進(jìn)行縮放功能

    Python使用OpenCV對圖像進(jìn)行縮放功能

    這篇文章主要介紹了Python使用OpenCV對圖像進(jìn)行縮放功能,文中給大家提到了兩種調(diào)用方式及OpenCV中pryUp和pryDown的用法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • linux下python抓屏實現(xiàn)方法

    linux下python抓屏實現(xiàn)方法

    這篇文章主要介紹了linux下python抓屏實現(xiàn)方法,涉及Python操作屏幕截取的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • Python實現(xiàn)監(jiān)聽目錄并取消文件只讀屬性

    Python實現(xiàn)監(jiān)聽目錄并取消文件只讀屬性

    這篇文章主要為大家詳細(xì)介紹了如何利用Python實現(xiàn)監(jiān)聽目錄并取消文件只讀屬性,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-07-07
  • 深入學(xué)習(xí)Python+Opencv常用四種圖像處理操作

    深入學(xué)習(xí)Python+Opencv常用四種圖像處理操作

    本文主要介紹了深入學(xué)習(xí)Pytho+OpenCV實現(xiàn)的基本圖像處理操作,例如:改變圖像大小,圖片色彩轉(zhuǎn)換,圖片模糊等,代碼具有一定的學(xué)習(xí)價值,感興趣的小伙伴可以關(guān)注一下
    2021-11-11
  • 一文讀懂Python的’=='和’is’用法

    一文讀懂Python的’=='和’is’用法

    探索Python世界的'=='與'is',一個看似簡單卻隱藏玄機(jī)的話題,本指南將帶你輕松讀懂它們背后的故事,解鎖編程中的這道難題,開始我們的快速之旅,釋放代碼的潛能吧!
    2024-01-01
  • spark dataframe 將一列展開,把該列所有值都變成新列的方法

    spark dataframe 將一列展開,把該列所有值都變成新列的方法

    今天小編就為大家分享一篇spark dataframe 將一列展開,把該列所有值都變成新列的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01

最新評論

三原县| 贵阳市| 正定县| 三台县| 哈巴河县| 河间市| 永寿县| 黎城县| 钦州市| 巍山| 日喀则市| 湘潭县| 海门市| 祁东县| 含山县| 嘉义县| 北京市| 盐亭县| 峨眉山市| 阿鲁科尔沁旗| 宁德市| 蒲江县| 安陆市| 大关县| 大同县| 曲麻莱县| 民和| 冕宁县| 南召县| 柏乡县| 东乌| 徐水县| 岑巩县| 布拖县| 勃利县| 尚志市| 城固县| 和政县| 白朗县| 新兴县| 肥乡县|