পাইথনের সকেট recv পদ্ধতিতে আমার সময়সীমা নির্ধারণ করতে হবে। এটা কিভাবে করতে হবে?
পাইথনের সকেট recv পদ্ধতিতে আমার সময়সীমা নির্ধারণ করতে হবে। এটা কিভাবে করতে হবে?
উত্তর:
আদর্শ পদ্ধতির মধ্যে ডেটা উপলব্ধ না হওয়া বা সময়সীমা ঘটে যাওয়া অবধি অপেক্ষা করতে নির্বাচন () নির্বাচন করা হয়। 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
তবে উইনসক লাইব্রেরিতে নির্ভর করে যা কিছু তথ্য আসার সাথে সাথে ফিরে আসার অভ্যাস রাখে , তবে অগত্যা এটি সমস্ত কিছু নয়। সুতরাং select.select()
সমস্ত ডেটা প্রাপ্ত না হওয়া পর্যন্ত আপনার কলিং চালিয়ে যাওয়ার জন্য একটি লুপ অন্তর্ভুক্ত করতে হবে । আপনি কীভাবে জানেন যে আপনি সমস্ত ডেটা পেয়েছেন (দুর্ভাগ্যক্রমে) এটি নির্ধারণ করার জন্য - এটির অর্থ কোনও টার্মিনেটর স্ট্রিং, একটি নির্দিষ্ট সংখ্যক বাইটের সন্ধান বা কেবল একটি নির্ধারিত সময়সীমার জন্য অপেক্ষা করা।
ready[0]
শুধুমাত্র মিথ্যা হতে যদি সার্ভারের প্রতিক্রিয়া কোন শরীর?
সেখানে socket.settimeout()
select
দ্রবণটি যখন ওয়ান লাইনার (বজায় রাখা সহজ, ভুল প্রয়োগের ক্ষেত্রে কম ঝুঁকি থাকে) এবং হুডের নীচে নির্বাচনগুলি ব্যবহার করে তবে যে সমাধানটি ব্যবহার করা হয় সেটিকে কেন অগ্রাধিকার দেওয়া হয় (বাস্তবায়ন @ ড্যানিয়েল স্টুজবাচের উত্তর হিসাবে একই)।
উভয় উল্লিখিত 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 সেকেন্ডে সেট করবে
এটি অন্তর্নিহিত সি ব্যবহার করে দেখুন
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 এমএস
#! /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/sketutils.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)