मुझे अजगर के सॉकेट आरईवी विधि पर टाइमआउट सेट करने की आवश्यकता है। यह कैसे करना है?
मुझे अजगर के सॉकेट आरईवी विधि पर टाइमआउट सेट करने की आवश्यकता है। यह कैसे करना है?
जवाबों:
विशिष्ट दृष्टिकोण डेटा के उपलब्ध होने तक या समय समाप्त होने तक प्रतीक्षा करने के लिए चयन () का उपयोग करना है। केवल recv()
तब कॉल करें जब डेटा वास्तव में उपलब्ध हो। सुरक्षित होने के लिए, हम सॉकेट को गैर-अवरोधक मोड पर सेट करने की गारंटी देते हैं जो recv()
कभी भी अनिश्चित काल तक अवरुद्ध नहीं होगा। select()
एक समय में एक से अधिक सॉकेट पर प्रतीक्षा करने के लिए भी इस्तेमाल किया जा सकता है।
import select
mysocket.setblocking(0)
ready = select.select([mysocket], [], [], timeout_in_seconds)
if ready[0]:
data = mysocket.recv(4096)
यदि आपके पास बहुत सारे खुले विवरण हैं, तो पोल () एक अधिक कुशल विकल्प है select()
।
एक अन्य विकल्प सॉकेट का उपयोग करके सभी कार्यों के लिए एक समयबाह्य सेट करना है socket.settimeout()
, लेकिन मैं देख रहा हूं कि आपने उस समाधान को दूसरे उत्तर में स्पष्ट रूप से अस्वीकार कर दिया है।
select
अच्छा है, लेकिन आप कहते हैं कि "आप नहीं कर सकते हैं" भाग भ्रामक है, क्योंकि वहाँ है socket.settimeout()
।
select
- यदि आप विंडोज मशीन पर चल रहे हैं, select
तो WinSock लाइब्रेरी पर निर्भर करता है, जिसमें कुछ डेटा आते ही वापस लौटने की आदत होती है , लेकिन जरूरी नहीं कि यह सब हो। इसलिए आपको select.select()
सभी डेटा प्राप्त होने तक कॉल करने के लिए एक लूप को शामिल करना होगा । आप कैसे जानते हैं कि आपने सारा डेटा प्राप्त कर लिया है (दुर्भाग्य से) यह पता लगाने के लिए - इसका मतलब हो सकता है कि आप एक टर्मिनेटर स्ट्रिंग, एक निश्चित संख्या में बाइट्स की तलाश कर रहे हैं, या बस एक निर्धारित समय के लिए प्रतीक्षा कर रहे हैं।
ready[0]
केवल गलत हो अगर वहाँ सर्वर की प्रतिक्रिया में कोई शरीर है?
वहाँ है socket.settimeout()
select
को प्राथमिकता दी जाती है जब यह समाधान एक लाइनर (आसान बनाए रखना, गलत तरीके से लागू करने में कम जोखिम) और हुड के तहत चयन का उपयोग करता है (कार्यान्वयन @DanielStuzbach उत्तर के समान है)।
जैसा कि दोनों ने उल्लेख किया है select.select()
और socket.settimeout()
काम करेगा।
ध्यान दें कि आपको settimeout
अपनी आवश्यकताओं के लिए दो बार कॉल करने की आवश्यकता हो सकती है , जैसे
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("",0))
sock.listen(1)
# accept can throw socket.timeout
sock.settimeout(5.0)
conn, addr = sock.accept()
# recv can throw socket.timeout
conn.settimeout(5.0)
conn.recv(1024)
.settimeout()
एक से अधिक बार कॉल करते हैं, तो आप setdefaulttimeout()
पहले स्थान पर विधि को कॉल कर सकते हैं ।
आप जिस टाइमआउट की तलाश कर रहे हैं, वह कनेक्शन सॉकेट का टाइमआउट है, न कि प्राइमरी सॉकेट का, अगर आप सर्वर साइड को लागू करते हैं। दूसरे शब्दों में, कनेक्शन सॉकेट ऑब्जेक्ट के लिए एक और टाइमआउट है, जो socket.accept()
विधि का आउटपुट है । इसलिए:
sock.listen(1)
connection, client_address = sock.accept()
connection.settimeout(5) # This is the one that affects recv() method.
connection.gettimeout() # This should result 5
sock.gettimeout() # This outputs None when not set previously, if I remember correctly.
यदि आप ग्राहक पक्ष को लागू करते हैं, तो यह सरल होगा।
sock.connect(server_address)
sock.settimeout(3)
जैसा कि पिछले उत्तरों में बताया गया है, आप कुछ इस तरह उपयोग कर सकते हैं: .settimeout()
उदाहरण के लिए:
import socket
s = socket.socket()
s.settimeout(1) # Sets the socket to timeout after 1 second of no activity
host, port = "somehost", 4444
s.connect((host, port))
s.send("Hello World!\r\n")
try:
rec = s.recv(100) # try to receive 100 bytes
except socket.timeout: # fail after 1 second of no activity
print("Didn't receive data! [Timeout]")
finally:
s.close()
आशा है कि ये आपकी मदद करेगा!!
आप socket.settimeout()
सेकंड की संख्या का प्रतिनिधित्व करने वाले पूर्णांक तर्क को स्वीकार कर सकते हैं । उदाहरण के लिए, socket.settimeout(1)
टाइमआउट को 1 सेकंड में सेट करेगा
इसे आज़माएं यह अंतर्निहित C का उपयोग करता है।
timeval = struct.pack('ll', 2, 100)
s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, timeval)
SO_RCVTIMEO
और SO_SNDTIMEO
।
2
और क्यों 100
? टाइमआउट मान क्या है? किस इकाई में?
timeval = struct.pack('ll', sec, usec)
s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, timeval)
usec = 10000 का अर्थ है 10 ms
#! /usr/bin/python3.6
# -*- coding: utf-8 -*-
import socket
import time
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.settimeout(5)
PORT = 10801
s.bind(('', PORT))
print('Listening for broadcast at ', s.getsockname())
BUFFER_SIZE = 4096
while True:
try:
data, address = s.recvfrom(BUFFER_SIZE)
except socket.timeout:
print("Didn't receive data! [Timeout 5s]")
continue
इसके लिए चिल्लाएँ: https://boltons.readthedocs.io/en/latest/socketutils.html
यह एक बफर सॉकेट प्रदान करता है, यह बहुत उपयोगी कार्यक्षमता प्रदान करता है जैसे:
.recv_until() #recv until occurrence of bytes
.recv_closed() #recv until close
.peek() #peek at buffer but don't pop values
.settimeout() #configure timeout (including recv timeout)