আপনি কি এইচটিটিপিআরএল সংযোগ সংযোগ প্রক্রিয়াটি ব্যাখ্যা করতে পারেন?


134

আমি HTTPURLConnectionএকটি ওয়েব পরিষেবাতে সংযোগ করতে ব্যবহার করছি । আমি কীভাবে ব্যবহার HTTPURLConnectionকরতে হয় তা জানি তবে এটি কীভাবে কাজ করে তা আমি বুঝতে চাই। মূলত, আমি নিম্নলিখিতগুলি জানতে চাই:

  • কোন বিন্দুতে HTTPURLConnectionপ্রদত্ত ইউআরএল সংযোগ স্থাপনের চেষ্টা করে?
  • কোন বিন্দুতে আমি জানতে পারি যে আমি সফলভাবে একটি সংযোগ স্থাপন করতে পেরেছি?
  • কোনও সংযোগ স্থাপন করছেন এবং প্রকৃত অনুরোধটি একটি পদক্ষেপ / পদ্ধতি কলটিতে সম্পন্ন করছেন? এটা কোন পদ্ধতি?
  • আপনি কি সাধারণ ব্যক্তির মেয়াদে getOutputStreamএবং এর কার্যকারিতা ব্যাখ্যা করতে পারেন getInputStream? আমি লক্ষ্য করেছি যে আমি যখন সার্ভারের সাথে সংযোগ দেওয়ার চেষ্টা করছি তখন ডাউন হয়ে যায়, আমি একটি Exceptionসংক্ষেপণ পাই getOutputStream। এর অর্থ কি এই যে HTTPURLConnectionকেবলমাত্র আমি প্রার্থনা করি তখনই কোনও সংযোগ স্থাপন শুরু হবে getOutputStream? কীভাবে getInputStream? যেহেতু আমি কেবলমাত্র প্রতিক্রিয়া পেতে সক্ষম হয়েছি getInputStream, তার মানে কি এই যে আমি getOutputStreamএখনও কোনও অনুরোধ প্রেরণ করি নি তবে কেবল একটি সংযোগ স্থাপন করেছি? কি HttpURLConnectionপ্রতিক্রিয়ার জন্য অনুরোধ সার্ভারে ফিরে যান যখন আমি ডাকা getInputStream?
  • আমি কি এই কথাটি বলতে পারি যে openConnectionকেবল নতুন সংযোগের বস্তু তৈরি করে তবে কোনও সংযোগ স্থাপন করে না?
  • আমি কীভাবে পঠিত ওভারহেড পরিমাপ করতে এবং ওভারহেড সংযোগ করতে পারি?

উত্তর:


184
String message = URLEncoder.encode("my message", "UTF-8");

try {
    // instantiate the URL object with the target URL of the resource to
    // request
    URL url = new URL("http://www.example.com/comment");

    // instantiate the HttpURLConnection with the URL object - A new
    // connection is opened every time by calling the openConnection
    // method of the protocol handler for this URL.
    // 1. This is the point where the connection is opened.
    HttpURLConnection connection = (HttpURLConnection) url
            .openConnection();
    // set connection output to true
    connection.setDoOutput(true);
    // instead of a GET, we're going to send using method="POST"
    connection.setRequestMethod("POST");

    // instantiate OutputStreamWriter using the output stream, returned
    // from getOutputStream, that writes to this connection.
    // 2. This is the point where you'll know if the connection was
    // successfully established. If an I/O error occurs while creating
    // the output stream, you'll see an IOException.
    OutputStreamWriter writer = new OutputStreamWriter(
            connection.getOutputStream());

    // write data to the connection. This is data that you are sending
    // to the server
    // 3. No. Sending the data is conducted here. We established the
    // connection with getOutputStream
    writer.write("message=" + message);

    // Closes this output stream and releases any system resources
    // associated with this stream. At this point, we've sent all the
    // data. Only the outputStream is closed at this point, not the
    // actual connection
    writer.close();
    // if there is a response code AND that response code is 200 OK, do
    // stuff in the first if block
    if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
        // OK

        // otherwise, if any other status code is returned, or no status
        // code is returned, do stuff in the else block
    } else {
        // Server returned HTTP error code.
    }
} catch (MalformedURLException e) {
    // ...
} catch (IOException e) {
    // ...
}

আপনার প্রশ্নের প্রথম 3 টি উত্তর প্রতিটি পদ্ধতির পাশে, উপরের HTTP পোষ্টের উদাহরণ হিসাবে ইনলাইন মন্তব্য হিসাবে তালিকাভুক্ত রয়েছে।

গেটআউটপুট স্ট্রিম থেকে :

এই সংযোগটিতে লেখার একটি আউটপুট স্ট্রিম ফেরত দেয়।

মূলত, আমি মনে করি এটি কীভাবে কাজ করে সে সম্পর্কে আপনার ভাল ধারণা রয়েছে, সুতরাং আমাকে কেবল সাধারণ ব্যক্তির পদগুলিতে পুনরাবৃত্তি করতে দিন। সার্ভারে ডেটা লেখার ইচ্ছায় getOutputStreamমূলত একটি সংযোগ স্ট্রিম খোলে । উপরের কোড উদাহরণে "বার্তা" একটি মন্তব্য হতে পারে যা আমরা সার্ভারে প্রেরণ করছি যা কোনও পোস্টে থাকা একটি মন্তব্যকে উপস্থাপন করে। আপনি যখন দেখবেন getOutputStream, আপনি লেখার জন্য সংযোগের স্ট্রিমটি খুলছেন , তবে আপনি কল না করা পর্যন্ত আপনি কোনও ডেটা লিখবেন না writer.write("message=" + message);

থেকে getInputStream () :

এই উন্মুক্ত সংযোগ থেকে পড়া একটি ইনপুট স্ট্রিম ফিরিয়ে দেয়। ডেটা পড়ার জন্য উপলব্ধ হওয়ার আগে যদি পাঠের সময়সীমা শেষ হয় তবে ফেরত ইনপুট স্ট্রিম থেকে পড়ার সময় একটি সকেটটাইমআউটপ্লেশন নিক্ষেপ করা যেতে পারে।

getInputStreamবিপরীত না। পছন্দ করুন getOutputStream, এটি একটি সংযোগ স্ট্রিমও খোলায়, তবে উদ্দেশ্যটি সার্ভার থেকে ডেটা পড়ার জন্য, এটিতে লিখিত নয়। সংযোগ অথবা প্রবাহ-খোলার ব্যর্থ হলে, আপনি একটি দেখতে পাবেন SocketTimeoutException

কিভাবে পাবেন ইনপুটস্ট্রিম? যেহেতু আমি কেবল getInputStream এ প্রতিক্রিয়া পেতে সক্ষম হচ্ছি, তার মানে কি এই যে আমি getOutputStream এ এখনও কোনও অনুরোধ প্রেরণ করি নি তবে কেবল একটি সংযোগ স্থাপন করে?

মনে রাখবেন যে একটি অনুরোধ প্রেরণ করা এবং ডেটা প্রেরণ দুটি পৃথক ক্রিয়াকলাপ। আপনি যখন getOutputStream বা getInputStream আবেদন করেন url.openConnection() , আপনি সংযোগ স্থাপনের জন্য সার্ভারে একটি অনুরোধ প্রেরণ করেন। হ্যান্ডশেক রয়েছে যা ঘটে যখন সার্ভারটি আপনাকে একটি স্বীকৃতি প্রেরণ করে যে সংযোগটি প্রতিষ্ঠিত রয়েছে। তখন সেই সময়েই আপনি ডেটা প্রেরণ বা গ্রহণের জন্য প্রস্তুত। সুতরাং, অনুরোধটি করার জন্য আপনার উদ্দেশ্য ডেটা প্রেরণ না করা না হলে কোনও সংযোগ স্থাপনের জন্য একটি প্রবাহ খোলার জন্য আপনাকে getOutputStream কল করার দরকার নেই ।

সাধারণ লোকের ভাষায়, getInputStreamঅনুরোধ করা আপনার বন্ধুর বাড়িতে একটি ফোন কল করার সমতুল্য হ'ল "আরে, আমি যদি এসে সেই জুটি ভাইস গ্রিপ ধার করে তবে কি ঠিক আছে?" এবং আপনার বন্ধু "নিশ্চিত! আসুন এবং এটি পান" এই কথা বলে হ্যান্ডশেকটি স্থাপন করে। তারপরে, সেই সংযোগটি তৈরি হয়ে গেলে, আপনি আপনার বন্ধুর বাড়ির দিকে হাঁটুন, দরজায় কড়া নাড়বেন, ভাইস গ্রিপসের জন্য অনুরোধ করুন এবং আপনার বাড়িতে ফিরে হাঁটবেন।

এর জন্য অনুরূপ উদাহরণ ব্যবহার করা getOutputStreamআপনার বন্ধুকে কল করা এবং "আরে, আমার যে thatণী আপনার কাছে রয়েছে তা আমি কী আপনার কাছে প্রেরণ করতে পারি?" আপনার বন্ধু, অর্থের প্রয়োজন এবং অসুস্থ যে ভিতরে আপনি এত দিন ধরে রেখেছিলেন, "নিশ্চিত, আসুন আপনার উপর সস্তা জারজ"। সুতরাং আপনি আপনার বন্ধুর বাড়িতে যান এবং তাকে "পোষ্ট" করুন। তারপরে সে আপনাকে লাথি মারে এবং আপনি আবার আপনার বাড়িতে ফিরে আসেন।

এখন, সাধারণ ব্যক্তির উদাহরণ দিয়ে চালিয়ে নেওয়া যাক কিছু ব্যতিক্রম দেখুন। যদি আপনি আপনার বন্ধুকে কল করেন এবং তিনি বাড়িতে না থাকেন তবে এটি 500 ত্রুটি হতে পারে। যদি আপনি কল করে এবং সংযোগ বিচ্ছিন্ন নম্বর বার্তা পেয়ে থাকেন কারণ আপনার বন্ধু আপনাকে সারাক্ষণ টাকা ingণ নিতে করতে ক্লান্ত হয়ে থাকে, এটি একটি 404 পৃষ্ঠা পাওয়া যায় নি। আপনার বিলটি পরিশোধ না করার কারণে যদি আপনার ফোনটি মারা যায় তবে এটি আইওএক্সেপশন হতে পারে। (দ্রষ্টব্য: এই বিভাগটি 100% সঠিক নাও হতে পারে lay এটি আপনাকে সাধারণ ব্যক্তির পদে কী ঘটছে সে সম্পর্কে একটি সাধারণ ধারণা দেওয়ার উদ্দেশ্যে))

প্রশ্ন # 5:

হ্যাঁ, আপনি ঠিক বলেছেন যে ওপেন সংযোগটি কেবল একটি নতুন সংযোগ অবজেক্ট তৈরি করে তবে তা প্রতিষ্ঠিত করে না। আপনি getInputStream বা getOutputStream কল করলে সংযোগটি প্রতিষ্ঠিত হয়।

openConnectionএকটি নতুন সংযোগ অবজেক্ট তৈরি করে। থেকে URL.openConnection javadocs :

এই URL টির জন্য প্রোটোকল হ্যান্ডলারের ওপেন সংযোগ পদ্ধতিটি কল করে প্রতিবার একটি নতুন সংযোগ খোলা হয়।

আপনি ওপেন সংযোগটি কল করার সময় সংযোগটি প্রতিষ্ঠিত হয় এবং যখন আপনি তা ইনস্ট্যান্ট করেন তখন ইনপুটস্ট্রিম, আউটপুটস্ট্রিম বা উভয়ই কল করা হয়।

প্রশ্ন # 6 :

ওভারহেড পরিমাপ করতে, আমি সাধারণত পুরো সংযোগ ব্লকের চারপাশে কিছু খুব সাধারণ টাইমিং কোডটি গুটিয়ে রাখি, যেমন:

long start = System.currentTimeMillis();
log.info("Time so far = " + new Long(System.currentTimeMillis() - start) );

// run the above example code here
log.info("Total time to send/receive data = " + new Long(System.currentTimeMillis() - start) );

আমি নিশ্চিত যে অনুরোধ সময় এবং ওভারহেড পরিমাপের জন্য আরও উন্নত পদ্ধতি রয়েছে তবে এটি সাধারণত আমার প্রয়োজনের জন্য যথেষ্ট।

সংযোগগুলি বন্ধ করার বিষয়ে তথ্যের জন্য, যা সম্পর্কে আপনি জিজ্ঞাসা করেননি, জাভাতে দেখুন কখন কোনও ইউআরএল সংযোগ বন্ধ হয়?


ওহে. ধন্যবাদ !!! এটি প্রকৃতপক্ষে একটি বিশদ ব্যাখ্যা ছিল এবং আমি আপনার উত্তরটির সত্যই প্রশংসা করি। যদি আমি আপনার উত্তরটি সঠিকভাবে বুঝতে পারি তবে getOutputStream এবং getInputStream উভয়ই কোনও সংযোগ স্থাপন করে যদি এখনও কোনও সংযোগ স্থাপন করা হয়নি। আমি যদি getOutputStream কল করি, তবে getInputStream কল করুন, অভ্যন্তরীণভাবে, HTTPURL সংযোগটি getInputStream এ আর কোনও সংযোগ পুনঃপ্রকাশ করবে না যেহেতু আমি ইতিমধ্যে getOutStream এ এটি প্রতিষ্ঠিত করতে সক্ষম হয়েছি? এইচটিপিআরএল সংযোগটি getInputStream এ getOutputStream এ আমি যে সংযোগ স্থাপন করতে সক্ষম হয়েছিল তা পুনরায় ব্যবহার করবে।
আরসি

বিপরীত .: বা এটি getOutputStream এবং getInputStream এর জন্য একটি নতুন এবং পৃথক সংযোগ স্থাপন করে? এছাড়াও, আমি যদি কানেক্ট ওভারহেড পেতে চাই, তবে আমার টাইমার লাগানোর উপযুক্ত জায়গাটি getOutputStream এর আগে এবং পরে। আমি যদি ওভারহেডে পড়তে চাই তবে আমার টাইমার লাগানোর উপযুক্ত জায়গাটি getInputStream এর আগে এবং পরে।
আরসি

মনে রাখবেন কি javadoc getInputStream এবং getOutputStream সম্পর্কে বলেন: Returns an output stream that writes to this connection.এবং Returns an input stream that reads from this open connection.। আউটপুটস্প্রিম এবং ইনপুটস্ট্রিম সংযোগ থেকে পৃথক।
jmort253

8
এটি লক্ষ্য করার মতো বিষয় যে এটি প্রদর্শিত হয় যে এইচটিপিআরএল সংযোগ অবজেক্টটি কেবলমাত্র সেই বিন্দুতে লক্ষ্য ইউআরএল পৌঁছেছে যেখানে এটি করা দরকার। আপনার উদাহরণে, আপনার ইনপুট এবং আউটপুট স্ট্রিম রয়েছে, যা সংযোগটি না খোলা পর্যন্ত অবশ্যই কিছু করতে পারে না। খুব সহজ কেসটি হ'ল একটি জিইটি অপারেশন, যাতে আপনি সংযোগটি আরম্ভ করা ছাড়া আর কিছুই করেন না এবং তারপরে প্রতিক্রিয়া কোডটি পরীক্ষা করুন। সেক্ষেত্রে getResponseCode () পদ্ধতি না বলা পর্যন্ত সংযোগটি আসলে তৈরি হয় না। অন্যথায়, এটি সংযোগ জীবনচক্রের একটি দুর্দান্ত ব্যাখ্যা এবং অন্বেষণ!
স্প্যানকি কুইগম্যান

1
আমি 'আরলকনেকশন' উদাহরণ এবং অন্তর্নিহিত টিসিপি / আইপি / এসএসএল সংযোগ, 2 পৃথক ধারণার মধ্যে আগে বিভ্রান্ত হয়ে পড়েছিলাম। প্রাক্তনটি মূলত একটি একক HTTP পৃষ্ঠার অনুরোধের সমার্থক। পরেরটি হ'ল এমন একটি জিনিস যা আশা করা যায় যে আপনি যদি একই সার্ভারে একাধিক পৃষ্ঠার অনুরোধগুলি করেন তবেই একবার তৈরি করা হবে।
টিম কুপার

17

টিম ব্রে একটি সংক্ষেপে ধাপে ধাপে উপস্থাপন করেছেন, উল্লেখ করে যে ওপেনকনেকশন () প্রকৃত সংযোগ স্থাপন করে না। বরং আপনি যতক্ষণ না getInputStream () বা getOutputStream () এর মতো পদ্ধতিগুলি কল না করেন ততক্ষণ একটি আসল HTTP সংযোগ স্থাপন করা হয় না।

http://www.tbray.org/ongoing/When/201x/2012/01/17/HttpURLConnection


1

HTTPURL সংযোগটি কোন বিন্দুতে প্রদত্ত URL টির সাথে সংযোগ স্থাপনের চেষ্টা করে?

ইউআরএল নামক বন্দরটিতে অন্যথায়, অন্যথায় HTTP- র জন্য 80 এবং এইচটিটিপিএসের জন্য 443। আমি বিশ্বাস করি এটি নথিভুক্ত।

কোন বিন্দুতে আমি জানতে পারি যে আমি সফলভাবে একটি সংযোগ স্থাপন করতে পেরেছি?

আপনি যখন getInputStream () বা getOutputStream () বা getResponseCode () কল করবেন তখন কোনও ব্যতিক্রম না পেয়ে।

কোনও সংযোগ স্থাপন করছেন এবং প্রকৃত অনুরোধটি একটি পদক্ষেপ / পদ্ধতি কলটিতে সম্পন্ন করছেন? এটা কোন পদ্ধতি?

না এবং কিছুই না।

আপনি সাধারণ ব্যক্তির মেয়াদে গেটআউটপুট স্ট্রিম এবং গেটইনপুট স্ট্রিমের কার্যকারিতা ব্যাখ্যা করতে পারেন?

তাদের উভয়ই প্রথমে যদি প্রয়োজন হয় তবে সংযোগ করে, তারপরে প্রয়োজনীয় স্ট্রিমটি ফিরিয়ে দেয়।

আমি লক্ষ্য করেছি যে আমি যখন সার্ভারের সাথে সংযোগ দেওয়ার চেষ্টা করছি তখন ডাউন হয়, আমি getOutputStream এ একটি ব্যতিক্রম পাই। এর অর্থ কি এই যে HTTPURL সংযোগটি কেবলমাত্র যখনই getoututstream স্ট্রিমের আবেদন করি তখনই কোনও সংযোগ স্থাপন শুরু করবে? কিভাবে পাবেন ইনপুটস্ট্রিম? যেহেতু আমি কেবল getInputStream এ প্রতিক্রিয়া পেতে সক্ষম হচ্ছি, তার মানে কি এই যে আমি getOutputStream এ এখনও কোনও অনুরোধ প্রেরণ করি নি তবে কেবল একটি সংযোগ স্থাপন করে? আমি যখন গেটপুট স্ট্রিমের অনুরোধ করব তখন কি এইচটিপিআরএল সংযোগটি প্রতিক্রিয়ার জন্য অনুরোধ জানাতে সার্ভারে ফিরে যায়?

উপরে দেখুন.

আমি কি এই কথাটি সঠিক বলতে পারি যে ওপেন সংযোগটি কেবল একটি নতুন সংযোগ অবজেক্ট তৈরি করে তবে এখনও কোনও সংযোগ স্থাপন করে না?

হ্যাঁ.

আমি কীভাবে পঠিত ওভারহেড পরিমাপ করতে এবং ওভারহেড সংযোগ করতে পারি?

সংযোগ করুন: getInoutStream () বা getOutputStream () সময় নিতে হবে, আপনি প্রথমে যাকে কল করুন return পড়ুন: প্রথম পড়া থেকে শুরু করে ইওএস পাওয়ার সময় time


1
আমি মনে করি ওপি বলতে বোঝায় কোন পয়েন্ট সংযোগটি প্রতিষ্ঠিত হয়েছে এবং কোন পর্যায়ে আমরা সংযোগের স্থিতি জানতে পারি। পোর্ট url এর সাথে সংযোগ নেই। আমি অনুমান করছি যে এটি ওপেন সংযোগ () এবং getInoutStream () / getOutputStream () / getResponseCode () এর উত্তর যা পরে রয়েছে এর দিকে পরিচালিত হয়েছিল।
অনিকেত ঠাকুর

1

HTTPURL সংযোগটি কোন বিন্দুতে প্রদত্ত URL টির সাথে সংযোগ স্থাপনের চেষ্টা করে?

এটি স্পষ্ট করার মতো, 'আরলকনেকশন' উদাহরণ রয়েছে এবং তারপরে অন্তর্নিহিত টিসিপি / আইপি / এসএসএল সকেট সংযোগ , 2 টি ভিন্ন ধারণা রয়েছে। 'UrlConnication' বা 'HttpUrlConnication' উদাহরণটি একক HTTP পৃষ্ঠার অনুরোধের সমার্থক এবং আপনি url.openConnection () কল করার সময় তৈরি হয়। তবে যদি আপনি এক 'url' উদাহরণ থেকে একাধিক url.openConnication () করেন তবে আপনি যদি ভাগ্যবান হন তবে তারা একই টিসিপি / আইপি সকেট এবং এসএসএল হ্যান্ডশেকিং স্টাফগুলি পুনরায় ব্যবহার করবেন ... আপনি যদি ভাল হন তবে ভাল একই সার্ভারে প্রচুর পৃষ্ঠার অনুরোধ করা, বিশেষত ভাল যদি আপনি এসএসএল ব্যবহার করছেন যেখানে সকেট স্থাপনের ওভারহেড খুব বেশি।

দেখুন: এইচটিপিআরএল সংযোগ বাস্তবায়ন


0

আমি নিম্ন স্তরের প্যাকেট এক্সচেঞ্জ ক্যাপচার করার জন্য অনুশীলনের মধ্য দিয়ে গিয়েছিলাম এবং দেখেছি যে নেটওয়ার্ক সংযোগটি কেবল getInputStream, getOutputStream, getResponseCode, getResponseMessage ইত্যাদির মতো ক্রিয়াকলাপ দ্বারা চালিত হয় found

ড্রপবক্সে ফাইল আপলোড করার জন্য আমি যখন একটি ছোট প্রোগ্রাম লেখার চেষ্টা করি তখন প্যাকেট এক্সচেঞ্জটি এখানে বন্দী।

এখানে চিত্র বর্ণনা লিখুন

নীচে আমার খেলনা প্রোগ্রাম এবং টিকা আছে

    /* Create a connection LOCAL object,
     * the openConnection() function DOES NOT initiate
     * any packet exchange with the remote server.
     * 
     * The configurations only setup the LOCAL
     * connection object properties.
     */
    HttpURLConnection connection = (HttpURLConnection) dst.openConnection();
    connection.setDoOutput(true);
    connection.setRequestMethod("POST");
    ...//headers setup
    byte[] testContent = {0x32, 0x32};

    /**
     * This triggers packet exchange with the remote
     * server to create a link. But writing/flushing
     * to a output stream does not send out any data.
     * 
     * Payload are buffered locally.
     */
    try (BufferedOutputStream outputStream = new BufferedOutputStream(connection.getOutputStream())) {
        outputStream.write(testContent);
        outputStream.flush();
    }

    /**
     * Trigger payload sending to the server.
     * Client get ALL responses (including response code,
     * message, and content payload) 
     */
    int responseCode = connection.getResponseCode();
    System.out.println(responseCode);

    /* Here no further exchange happens with remote server, since
     * the input stream content has already been buffered
     * in previous step
     */
    try (InputStream is = connection.getInputStream()) {
        Scanner scanner = new Scanner(is);
        StringBuilder stringBuilder = new StringBuilder();
        while (scanner.hasNextLine()) {
        stringBuilder.append(scanner.nextLine()).append(System.lineSeparator());
        }
    }

    /**
     * Trigger the disconnection from the server.
     */
    String responsemsg = connection.getResponseMessage();
    System.out.println(responsemsg);
    connection.disconnect();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.