লোকালহোস্টে, আমি কীভাবে একটি বিনামূল্যে পোর্ট নম্বর চয়ন করব?


161

আমি আন্ত-প্রক্রিয়া যোগাযোগের সাথে খেলতে চেষ্টা করছি এবং যেহেতু উইন্ডোজ এর অধীনে নামযুক্ত পাইপগুলি কীভাবে ব্যবহার করব তা আমি বুঝতে পারি না যে আমি নেটওয়ার্ক সকেটগুলি ব্যবহার করব। স্থানীয়ভাবে সবকিছু ঘটে। সার্ভারটি পৃথক প্রক্রিয়াতে ক্রীতদাস প্রবর্তন করতে সক্ষম এবং কিছু বন্দরে শুনে। দাসরা তাদের কাজ করে এবং ফলাফল মাস্টারের কাছে জমা দেয়। কোন বন্দরটি উপলব্ধ তা আমি কীভাবে বুঝব? আমি ধরে নিয়েছি যে আমি 80 বা 21 পোর্টে শুনতে পারি না?

আমি পাইথন ব্যবহার করছি, যদি এটি পছন্দগুলি হ্রাস করে।

ধন্যবাদ!


1
ঘটনাক্রমে, আপনি যদি কেবল একটি এলোমেলো বা এলোমেলো-ইশ পোর্ট নম্বর চয়ন করেন (পছন্দ হয় 1024 এর চেয়ে বেশি) তবে এটি সম্ভবত উপলব্ধ থাকবে। এমনকি আপনি 80 বা 21 পোর্ট বা যে কোনও কিছু ব্যবহার করতে পারেন, যতক্ষণ না অন্য কোনও প্রোগ্রাম এতে শুনছে না। যে কোনও সময়, একটি সাধারণ সিস্টেমে, পোর্টগুলির মধ্যে কেবল একটি ছোট্ট অংশ ব্যবহৃত হয়।
ডেভিড জেড

19
এলোমেলো বন্দর বেছে নেওয়া ভাল ধারণা নয় - আপনার জন্য ওএসকে একটি বেছে নিতে দিন let
Corehpf

উত্তর:


225

বেঁধে বন্দর 0, যেমন জন্য নির্দিষ্ট বন্দর সংলগ্ন, অথবা না sock.bind(('', 0))। এর পরে ওএস আপনার জন্য উপলব্ধ একটি পোর্ট বেছে নেবে। আপনি যে বন্দরটি ব্যবহার করে বেছে নেওয়া হয়েছিল তা পেতে পারেন sock.getsockname()[1]এবং এটি ক্রীতদাসদের কাছে দিয়ে দিতে পারেন যাতে তারা আবার সংযোগ করতে পারে।


4
দেখুন stackoverflow.com/a/2838309/3538289 একটি উদাহরণ জন্যsock.bind(('',0))
cevaris

10
আপনি দাসদের সংখ্যায় কীভাবে পাস করবেন? আমার কাছে মুরগির মতো ডিম এবং ডিমের সমস্যা।
সেবাস্তিয়ান

2
যদি দাসগুলি আবদ্ধ হওয়ার পরে তৈরি করা হয় তবে তাদের তৈরি করার সময় আপনি কেবল এটি প্যারামিটার হিসাবে পাস করতে পারেন। বিকল্পভাবে আপনি এটিকে কিছু ভাগ করা মেমরি বা এমন একটি ফাইলে লিখতে পারেন যা উভয়ই অ্যাক্সেস করতে পারে, বা কোনও কেন্দ্রীয় সার্ভার কিছু পরিচিত বন্দর নম্বর ব্যবহার করে এটি ট্র্যাক রাখতে পারে track
4o

49

ছেলেরা উপরে কী ব্যাখ্যা করেছে তার স্নিপেটের জন্য:

import socket
from contextlib import closing

def find_free_port():
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
        s.bind(('', 0))
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        return s.getsockname()[1]

3
লোকালহোস্টে থাকলে: সম্ভবত s.bind(('localhost', 0))আরও ভাল
কোডস্কিব্লু

3
নিম্নলিখিতগুলি যুক্ত s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
করাও ভাল,

1
@ জোনাবার্ড socket.SO_REUSEADDRএই ক্ষেত্রে সত্যই সহায়তা করে? আমি যা পড়েছি তা কেবলমাত্র এটিই প্রাসঙ্গিক যে সকেটকে বাঁধতে চেষ্টা করা SO_REUSEADDRহচ্ছে তা অপ্রাসঙ্গিক এবং সেই পতাকাটি দীর্ঘায়িত সকেটে সেট করা আছে কিনা ir
কার্ল বার্টেল

41

সকেটকে বন্দর 0 এ বাঁধুন। 1024 থেকে 65535 পর্যন্ত একটি এলোমেলো মুক্ত পোর্ট নির্বাচন করা হবে। আপনি getsockname()ঠিক পরে নির্বাচিত পোর্ট পুনরুদ্ধার করতে পারেন bind()


2

আপনি যেটি বন্দর চান তা শুনতে পারেন; সাধারণত, ব্যবহারকারী অ্যাপ্লিকেশনগুলির 1024 বা তদূর্ধের পোর্টগুলি শুনতে হবে (65535 এর মাধ্যমে)। আপনার যদি শ্রোতার একটি পরিবর্তনশীল সংখ্যক থাকে তবে প্রধান জিনিসটি হ'ল আপনার অ্যাপ্লিকেশনে একটি ব্যাপ্তি বরাদ্দ করা - 20000-21000 বলুন, এবং ক্যাচ ছাড় করুন । আপনার কম্পিউটারে কোনও পোর্ট অপব্যবহারযোগ্য (অন্য কোনও প্রক্রিয়া দ্বারা ব্যবহৃত) অন্য কোনও পদ্ধতিতে আপনি কীভাবে তা জানতে পারবেন।

যাইহোক, আপনার ক্ষেত্রে, আপনার শ্রোতার জন্য একক হার্ড-কোডেড পোর্ট ব্যবহার করতে আপনার সমস্যা হওয়া উচিত নয়, যতক্ষণ না আপনি বাঁধন ব্যর্থ হয়ে থাকেন ততক্ষণ আপনি কোনও ত্রুটি বার্তা মুদ্রণ করেন।

আরও লক্ষ করুন যে আপনার বেশিরভাগ সকেট (দাসদের জন্য) নির্দিষ্ট পোর্ট সংখ্যায় স্পষ্টভাবে আবদ্ধ হওয়ার দরকার নেই - কেবলমাত্র এমন সকেট যা আগত সংযোগগুলির জন্য অপেক্ষা করে (আপনার মাস্টারের মতো এখানে) শ্রোতা তৈরি করতে হবে এবং একটি বন্দরে আবদ্ধ হতে হবে। যদি কোনও পোর্টটি সকেটের ব্যবহারের আগে নির্দিষ্ট না করা হয়, তবে ওএস সকেটে একটি ব্যবহারযোগ্য পোর্ট বরাদ্দ করবে। যখন মাস্টার কোনও গোলামের কাছে এটি ডেটা প্রেরণে প্রতিক্রিয়া জানাতে চান, শ্রোতা যখন তথ্য গ্রহণ করেন তখন প্রেরকের ঠিকানা অ্যাক্সেসযোগ্য হয়।

আমার ধারণা আপনি এর জন্য ইউডিপি ব্যবহার করবেন?


0

আপনার যদি কেবল পরবর্তী ব্যবহারের জন্য একটি বিনামূল্যে পোর্ট সন্ধান করতে হয় তবে এখানে সকেট সার্ভার ব্যবহার করে পূর্বের উত্তরের মতো স্নিপেট রয়েছে তবে খাটো :

import socketserver

with socketserver.TCPServer(("localhost", 0), None) as s:
    free_port = s.server_address[1]

নোট করুন যে বন্দরটি মুক্ত থাকার গ্যারান্টিযুক্ত নয়, সুতরাং আপনাকে এই স্নিপেট এবং কোডটি একটি লুপে ব্যবহার করার প্রয়োজন হতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.