国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python的Socket編程過程中實現UDP端口復用的實例分享

Python的Socket編程過程中實現UDP端口復用的實例分享

2020-08-17 11:14liweisnake Python

這篇文章主要介紹了Python的Socket編程過程中實現UDP端口復用的實例分享,文中作者用到了Python的twisted異步框架,需要的朋友可以參考下

關于端口復用

一個套接字不能同時綁定多個端口,如果客戶端想綁定端口號,一定要調用發送信息函數之前綁定( bind )端口,因為在發送信息函數( sendto, 或 write ),系統會自動給當前網絡程序分配一個隨機端口號,這相當于隨機綁定了一個端口號,這里只會分配一次,以后通信就以這個隨機端口通信,我們再綁定端口號的話,就會綁定失敗。如果我們放在發送信息函數( sendto, 或 write )之前綁定,那樣程序將以我們綁定的端口號發送信息,不會再隨機分配一個端口號。實際上,默認的情況下,如果一個網絡應用程序的一個套接字 綁定了一個端口,這時候,別的套接字就無法使用這個端口。那如何讓兩個套接字都能成功綁定一個端口呢?這時候就需要要到端口復用了。端口復用允許在一個應用程序可以把 n 個套接字綁在一個端口上而不出錯。
端口復用能在系統已開放的端口上進行通訊,只對輸入的信息進行字符匹配,不對網絡數據進行任何攔截、復制類操作,所以對網絡數據的傳輸性能絲毫不受影響。
但要注意,建立連接后服務端程序占用極少系統資源,被控端不會在系統性能上有任何察覺,通常被后門木馬所利用。
在winsock的實現中,對于服務器的綁定是可以多重綁定的,在確定多重綁定使用誰的時候,根據一條原則是誰的指定最明確則將包遞交給誰,而且沒有權限之分,也就是說低級權限的用戶是可以重綁定在高級權限如服務啟動的端口上的,這是非常重大的一個安全隱患。

Python解決UDP端口復用問題
一直覺得UDP協議很簡單,但是今天問題讓我感覺到網絡的基礎真是博大精深。

    廢話少說,來看問題吧。由于協議的需要,我得實現一個UDP的客戶端和服務器端,并且從同一個端口讀寫數據。

    最初不以為然,無非就是用兩個socket,一個監聽并從這個端口讀取數據(服務器端采用了twisted),另一個向這個端口寫入數據,用python實現只要10行左右的代碼。

?
1
2
3
4
5
6
7
8
9
def startServer(queue, port):
  reactor.listenUDP(port, DhtResponseHandler(queue))
  reactor.run()
 
def sendUdpMsg(self, addr, msg):
  socketHandler = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  socketHandler.bind(("", self.port))
  socketHandler.sendto(msg, addr)
  socketHandler.close()

     由于要向同一個端口寫數據,于是client必須有bind,但是運行后發現server先bind了這個端口,client運行時會報錯

 

復制代碼 代碼如下:

 

error: [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted  

 


     一般這種錯誤時因為多個socket不能同時bind同一個地址
     由于基礎不夠扎實,我開始瘋狂的搜索,發現有人說端口復用的問題,所謂的端口復用,是指一個套接字釋放掉一個端口后有一個wait_time,另一個套接字如果接著bind就會報錯。雖然我的問題不完全一樣,但是我欣喜若狂的使用了。即在client bind前加上如下一句

 

?
1
socketHandler.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

     但是仍然報錯:

 

復制代碼 代碼如下:

 

 

error: [Errno 10013] An attempt was made to access a socket in a way forbidden by its access permissions  

 


    (順便一提,還有另一個參數叫SO_REUSEPORT,即復用端口,另外有一個叫SO_EXCLUSIVEADDRUSE,即不準復用該端口,其他socket的參數還有很多,可以參考winsockhttp://msdn.microsoft.com/en-us/library/aa924071.aspx或者unix下的socket)
     這個10013錯誤讓我百思不得其解,搜索一下,主要有兩種解釋,有人說是需要提升應用程序的權限為管理員,我用的是eclipse+pydev,提升完eclipse權限沒用,實際上還要修改python.exe的權限,方法是在這個程序上右鍵,兼容性一欄中勾上以系統管理員身份運行;有人說是跟其他程序地址或者端口沖突。但是我測試過發現都不行。

 

     另外,運行的時候發現,twisted的服務器端一定是要在主線程中,否則會報signal一定要在主線程才能接受的錯誤,但是twisted的reactor一運行起來就阻塞了。

     在twisted文檔中翻到,原來還有一種UDP叫做connected UDP,變態吧,所謂connected UDP,就是只能向一個地址收發數據,看起來貌似可以,但是不符合可以向多個地址接收數據。

     最后在一篇文章中翻到說需要兩個端口都設置重用,于是我試著重新寫一個服務器,與之前的客戶端配合,運行良好,完全無錯

?
1
2
3
4
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("", port))
data, address = sock.recvfrom(4096)

     好吧,看來問題在調用twisted了,不知道他是否有這樣的設置,進去將這部分代碼翻了一下,找不到這樣設置的參數。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class Port(abstract.FileHandle):
  def __init__(self, port, proto, interface='', maxPacketSize=8192,
         reactor=None):
    """
    Initialize with a numeric port to listen on.
    """
    self.port = port
    self.protocol = proto
    self.readBufferSize = maxPacketSize
    self.interface = interface
    self.setLogStr()
    self._connectedAddr = None
 
    abstract.FileHandle.__init__(self, reactor)
 
    skt = socket.socket(self.addressFamily, self.socketType)
    addrLen = _iocp.maxAddrLen(skt.fileno())
    self.addressBuffer = _iocp.AllocateReadBuffer(addrLen)
    # WSARecvFrom takes an int
    self.addressLengthBuffer = _iocp.AllocateReadBuffer(
        struct.calcsize('i'))
 
  def startListening(self):
    """
    Create and bind my socket, and begin listening on it.
 
    This is called on unserialization, and must be called after creating a
    server to begin listening on the specified port.
    """
    self._bindSocket()
    self._connectToProtocol()
 
 
  def createSocket(self):
    return self.reactor.createSocket(self.addressFamily, self.socketType)
 
 
  def _bindSocket(self):
    try:
      skt = self.createSocket()
      skt.bind((self.interface, self.port))
    except socket.error, le:
      raise error.CannotListenError, (self.interface, self.port, le)
 
    # Make sure that if we listened on port 0, we update that to
    # reflect what the OS actually assigned us.
    self._realPortNumber = skt.getsockname()[1]
 
    log.msg("%s starting on %s" % (
        self._getLogPrefix(self.protocol), self._realPortNumber))
 
    self.connected = True
    self.socket = skt
    self.getFileHandle = self.socket.fileno

    難道說twisted就完全不提供這樣的功能?最終在multicast中翻到這樣一段,也就是,多播的情況是支持地址復用的,動手測起來。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class MulticastPort(MulticastMixin, Port):
  """
  UDP Port that supports multicasting.
  """
 
  implements(interfaces.IMulticastTransport)
 
 
  def __init__(self, port, proto, interface='', maxPacketSize=8192,
         reactor=None, listenMultiple=False):
    Port.__init__(self, port, proto, interface, maxPacketSize, reactor)
    self.listenMultiple = listenMultiple
 
 
  def createSocket(self):
    skt = Port.createSocket(self)
    if self.listenMultiple:
      skt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
      if hasattr(socket, "SO_REUSEPORT"):
        skt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
    return skt

     將server端改成如下代碼,運行通過!

?
1
2
reactor.listenMulticast(port, DhtResponseHandler(queue), listenMultiple=True)
reactor.run()

     感觸良多,底層的知識比較重要,浮沙筑高臺果然危險。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 日韩欧美在线视频 | 欧美日韩高清在线观看 | www夜夜操 | 欧美精品一二三区 | 国产高清精品一区 | 白浆在线 | 久久久www成人免费无遮挡大片 | 久久影院一区 | 黄色免费在线看 | 精品一区二区三区免费毛片 | 久久精彩| 成人免费毛片嘿嘿连载视频 | 91电影在线| 久久久久久香蕉 | 99久久精品国产一区二区三区 | 国产精品久久久久久久久免费桃花 | 午夜天堂精品久久久久 | 在线中文字幕av | 亚洲精品一二三区 | 国产精品一二 | 日韩中文一区二区三区 | 偷拍一区二区三区四区 | 午夜av电影 | 成人在线中文字幕 | 国产一区二区三区在线免费看 | 久久窝| 国产精品久久久久一区二区三区 | 成人一区二区三区久久精品嫩草 | 久久99精品久久久久久园产越南 | 天天干天天爽 | 午夜视频在线播放 | 99精品免费| 国产精品自拍视频 | 国产视频综合在线 | 日本网站在线免费观看 | 欧美视频在线一区 | 中文字幕三区 | 丁香婷婷综合激情五月色 | 久久久久亚洲 | 视频一区二区在线观看 | 99久久精品免费看国产一区二区三区 |