C++ এ সকেট প্রোগ্রামিং

C E Saketa Programim



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

ক্লায়েন্ট-সার্ভার মডেল প্রতিষ্ঠা করা

সকেট প্রোগ্রামিং হল এমন একটি প্রক্রিয়া যা সকেট ব্যবহার করে সার্ভার এবং ক্লায়েন্টের মধ্যে যোগাযোগের চ্যানেল তৈরি করে। নিম্নলিখিত উদাহরণ কোডে, ক্লায়েন্ট সার্ভারের সাথে একটি যোগাযোগ শুরু করে এবং সার্ভারটি ক্লায়েন্ট সংযোগগুলি গ্রহণ করার জন্য সেট আপ করা হয়। আসুন নেটওয়ার্ক যোগাযোগের মধ্যে তাদের মূল কাজ প্রদর্শন করে সার্ভার এবং ক্লায়েন্ট কোড বিভাগগুলি বুঝতে পারি। নিম্নলিখিত সার্ভার-সাইড কোড. আসুন প্রথমে কোডটি দেখি এবং তারপরে কোডটি বিশদে ব্যাখ্যা করি, পয়েন্ট বাই পয়েন্ট।

1. সার্ভার সাইড







মডেলের সার্ভার সাইডের কোড নিচে দেওয়া হল। আসুন কোডে কি ঘটছে তা দেখুন:



# অন্তর্ভুক্ত করুন
# অন্তর্ভুক্ত
#include
#include

ব্যবহার নামস্থান std ;

# পোর্ট 8080 সংজ্ঞায়িত করুন
# MAX_BUF_SIZE 1024 সংজ্ঞায়িত করুন

int প্রধান ( ) {
int ser_সকেট, cli_সকেট ;
গঠন sockaddr_in ser_address, cli_address ;
চর buf [ MAX_BUF_SIZE ] = { 0 } ;

যদি ( ( ser_সকেট = সকেট ( AF_INET, SOCK_STREAM, 0 ) ) == - 1 ) {
ভুল ( 'সকেট তৈরিতে ত্রুটি' ) ;
প্রস্থান ( EXIT_FAILURE ) ;
}

ser_address. পাপ_পরিবার = OF_INET ;
ser_address. sin_addr . s_addr = INADDR_ANY ;
ser_address. sin_port = htons ( পোর্ট ) ;

যদি ( বাঁধাই করা ( হতে_সকেট, ( গঠন sockaddr * ) এবং ser_address, আকার ( ser_address ) ) == - 1 ) {
ভুল ( 'আবদ্ধে ব্যর্থতা' ) ;
প্রস্থান ( EXIT_FAILURE ) ;
}

যদি ( শুনুন ( হতে_সকেট, 3 ) == - 1 ) {
ভুল ( 'শুনতে ব্যর্থ' ) ;
প্রস্থান ( EXIT_FAILURE ) ;
}

cout << 'পোর্টে সার্ভার শুনছে' << পোর্ট << '... \n ' ;

socklen_t cli_address_len = আকার ( cli_ঠিকানা ) ;
যদি ( ( cli_সকেট = গ্রহণ ( হতে_সকেট, ( গঠন sockaddr * ) এবং cli_ঠিকানা, এবং cli_address_len ) ) == - 1 ) {
ভুল ( 'গ্রহণ করতে ব্যর্থ' ) ;
প্রস্থান ( EXIT_FAILURE ) ;
}

পড়া ( cli_socket, buf, MAX_BUF_SIZE ) ;
cout << 'ক্লায়েন্টের বার্তা হল:' << buf << endl ;

পাঠান ( cli_সকেট, 'সার্ভারের বার্তা' , strlen ( 'সার্ভারের বার্তা' ) , 0 ) ;

বন্ধ ( cli_সকেট ) ;
বন্ধ ( ser_সকেট ) ;

ফিরে 0 ;
}

প্রদত্ত উদাহরণ হল C++ প্রোগ্রামের সার্ভার-সাইড কোড। এই কোডটি একটি সাধারণ TCP সার্ভারের জন্য একটি নির্দিষ্ট পোর্টে সংযোগের জন্য কাজ করে। যখন একটি সংযোগ সফলভাবে তৈরি করা হয়, সার্ভারটি একটি বার্তা পাবে যা ক্লায়েন্ট থেকে পাঠানো হয়। এর পরে, এটি কনসোলে এটি মুদ্রণ করে এবং ক্লায়েন্টকে একটি প্রতিক্রিয়া বার্তা পাঠায়। আসুন কোডের প্রতিটি লাইন বুঝতে পারি।



প্রোগ্রামটি লাইব্রেরিগুলি অন্তর্ভুক্ত করে শুরু হয়: স্ট্যান্ডার্ড ইনপুট/আউটপুট সংজ্ঞাগুলির জন্য 'iostream', স্ট্রিং হ্যান্ডলিং ফাংশনের জন্য 'cstring', POSIX অপারেটিং সিস্টেম API-এ অ্যাক্সেস প্রদানের জন্য 'unistd.h', এবং 'arpa/inet.h' ইন্টারনেট অপারেশন সঞ্চালন। '#ডিফাইন পোর্ট 8080' বিবৃতিটির অর্থ হল এটি পোর্ট নম্বর 8080 কে সংজ্ঞায়িত করে যার উপর সার্ভার শুনবে। '#define MAX_BUF_SIZE 1024' মানে ইনকামিং ডেটার সর্বোচ্চ বাফার সাইজ যা 1024।





প্রধান ফাংশনে, সার্ভার এবং ক্লায়েন্ট উভয়ের প্রতিনিধিত্ব করার জন্য যথাক্রমে দুটি ভেরিয়েবল শুরু করা হয়, 'ser_socket' এবং 'cli_socket'। অন্য তিনটি ভেরিয়েবল যা হল “socaddr_in”, “ser_address”, এবং “cli_address” টাইপের “struct” সার্ভার এবং ক্লায়েন্টের জন্য ঠিকানা কাঠামো হিসাবে শুরু করা হয়েছে। এর পরে, 'বাফ' নামে একটি বাফার শুরু করা হয় যা ক্লায়েন্ট থেকে আসা ডেটা সংরক্ষণ করে।

'if' অবস্থায় সকেট() ফাংশন একটি নতুন TCP সকেট তৈরি করে। AF_INET IPv4 নির্দেশ করে, SOCK_STREAM সংযোগ-ভিত্তিক এবং নির্ভরযোগ্য TCP সকেটকে প্রতিনিধিত্ব করে, শেষ আর্গুমেন্ট যা 0 দেওয়া হয় ডিফল্ট TCP প্রোটোকল নির্বাচন করার জন্য, INADDR_ANY যেকোনো IP ঠিকানায় সংযোগগুলি গ্রহণ করে, এবং htons (PORT) থেকে পোর্ট নম্বর রূপান্তর করে নেটওয়ার্ক বাইট অর্ডার হোস্ট বাইট অর্ডার.



যেহেতু সবকিছু সঠিকভাবে সংজ্ঞায়িত করা হয়েছে, পরবর্তী ধাপ হল প্রদত্ত পোর্টে একটি লিস্টার হিসাবে সার্ভার সেট আপ করা এবং যেকোনো নেটওয়ার্ক ইন্টারফেসে সংযোগগুলি গ্রহণ করা। bind() পদ্ধতিতে 'ser_address'-এ তথ্য সহ সকেট দেওয়া হয়। আমরা একটি ত্রুটি মুদ্রণ করি এবং বাঁধাই ব্যর্থ হলে প্রক্রিয়াটি শেষ করি। accept() ফাংশন ক্লায়েন্টের সাথে সংযোগের জন্য একটি নতুন সকেট খোলে, যেখানে listen() ফাংশন সার্ভারকে ইনকামিং সংযোগের জন্য অপেক্ষা করার নির্দেশ দেয়। Accept() ফাংশন ব্যর্থ হলে, ত্রুটি বার্তা মুদ্রিত হয় এবং ফাংশন প্রস্থান করা হবে.

এরপরে, সার্ভার ক্লায়েন্ট বার্তাটি read() ফাংশন সহ “buf” বাফারে পড়ে এবং তারপর এটি কনসোলে প্রিন্ট করে। send() ফাংশনটি সার্ভার দ্বারা ক্লায়েন্টের প্রতিক্রিয়ায় একটি বার্তা পাঠাতে ব্যবহৃত হয়। সবশেষে, close() ব্যবহার করে সার্ভার ক্লায়েন্টের সকেট বন্ধ করে দেয়, প্রোগ্রামটি বন্ধ করে দেয় যাতে সমস্ত সংযোগ সঠিকভাবে বন্ধ থাকে এবং ডেটা লঙ্ঘনের কোনো সম্ভাবনা থাকে না।

2. ক্লায়েন্ট সাইড

এখন, ক্লায়েন্ট মডেলে কী ঘটে তা দেখা যাক:

# অন্তর্ভুক্ত করুন
# অন্তর্ভুক্ত
#include
#include

# পোর্ট 8080 সংজ্ঞায়িত করুন
#SERVER_IP '127.0.0.1' সংজ্ঞায়িত করুন

int প্রধান ( ) {
int cli_সকেট ;
গঠন sockaddr_in ser_address ;
const চর * বার্তা = 'ক্লায়েন্ট শুভেচ্ছা পাঠাচ্ছে!' ;

যদি ( ( cli_সকেট = সকেট ( AF_INET, SOCK_STREAM, 0 ) ) == - 1 ) {
ভুল ( 'সকেট তৈরিতে ত্রুটি' ) ;
প্রস্থান ( EXIT_FAILURE ) ;
}

ser_address. পাপ_পরিবার = OF_INET ;
ser_address. sin_port = htons ( পোর্ট ) ;

যদি ( inet_pton ( AF_INET, SERVER_IP, এবং ser_address. sin_addr ) <= 0 ) {
ভুল ( 'ভুল ঠিকানা' ) ;
প্রস্থান ( EXIT_FAILURE ) ;
}

যদি ( সংযোগ ( cli_সকেট, ( গঠন sockaddr * ) এবং ser_address, আকার ( ser_address ) ) == - 1 ) {
ভুল ( 'সংযোগ বিচ্ছিন্ন' ) ;
প্রস্থান ( EXIT_FAILURE ) ;
}
পাঠান ( cli_সকেট, মেসেজ, strlen ( বার্তা ) , 0 ) ;

চর buf [ 1024 ] = { 0 } ;
পড়া ( cli_সকেট, বুফ, আকার ( buf ) ) ;
std :: cout << 'সার্ভার প্রতিক্রিয়া:' << buf << std :: endl ;

বন্ধ ( cli_সকেট ) ;
ফিরে 0 ;
}

প্রোগ্রাম কিভাবে কাজ করে তা বোঝার জন্য কোডের প্রতিটি লাইন দেখি।

একই চারটি লাইব্রেরি - iostream, cstring, unistd.h, এবং arpa/inet.h - এছাড়াও ক্লায়েন্ট সাইডে অন্তর্ভুক্ত করা হয়েছে। স্থানীয় হোস্ট 127.0.0.1 এর IP ঠিকানার সাথে একটি পোর্ট নম্বরও সংজ্ঞায়িত করা হয়েছে। সার্ভারে যে মেসেজ ডেলিভারি করতে হবে তা দেওয়া আছে। ক্লায়েন্ট এবং সার্ভারকে নিম্নলিখিত পদক্ষেপ হিসাবে একটি সংযোগ স্থাপন করতে হবে:

“যদি ((ক্লায়েন্ট_সকেট = সকেট(AF_INET, SOCK_STREAM, 0)) == -1);” একটি স্ট্রিম টাইপ এবং ডিফল্ট প্রোটোকল TCP সহ IPv4 এর জন্য একটি সকেট তৈরি করে। যদি সকেট() ফাংশন সংযোগ স্থাপন করতে ব্যর্থ হয় এবং প্রোগ্রাম থেকে প্রস্থান করে তবে perror() ত্রুটির বিবরণ প্রিন্ট করে।

'server_address.sin_port = htons(PORT);' নেটওয়ার্ক বাইট অর্ডারে রূপান্তর করার পরে পোর্ট নম্বর সেট করে। এরপরে, আরেকটি ব্যর্থতার বার্তা এখানে দেওয়া হয়েছে যা হল 'ভুল ঠিকানা' যা ঠিকানায় কিছু ভুল থাকলে প্রিন্ট করা হয়। 'ser_address' এ ঠিকানাটি সনাক্ত করার মাধ্যমে, ক্লায়েন্ট সার্ভারের সাথে সংযুক্ত হবে। সংযোগ ব্যর্থ হলে, ত্রুটি বিবরণ মুদ্রিত হয়. send() ফাংশন সার্ভারে বার্তা স্থানান্তর করবে, নিশ্চিত করবে যে এতে কোনো পতাকা থাকবে না।

সার্ভার থেকে একটি প্রতিক্রিয়া গ্রহণ এবং সংরক্ষণ করতে, 'char' টাইপের 'buf' নামে একটি বাফার শুরু করা হয়। read() ফাংশন বাফারে সার্ভারের প্রতিক্রিয়া পড়ে। অবশেষে, সার্ভারের প্রতিক্রিয়া কনসোলে মুদ্রিত হয়। অবশেষে, সকেটটি বন্ধ করতে close() স্টেটমেন্ট ব্যবহার করে সংযোগ বন্ধ করা হয়। নিম্নলিখিত প্রোগ্রামের আউটপুট:

উপসংহার

সকেট প্রোগ্রামিং কম্পিউটার বিজ্ঞানে নেটওয়ার্ক যোগাযোগের একটি গুরুত্বপূর্ণ অংশ। এটি নেটওয়ার্কের মাধ্যমে যোগাযোগ করতে পারে এমন অ্যাপ্লিকেশনগুলির বিকাশকে সক্ষম করে, সাধারণ ক্লায়েন্ট-সার্ভার আর্কিটেকচার থেকে কাঠামোগত বিতরণ সিস্টেমে বিস্তৃত সম্ভাবনাকে সক্ষম করে। যখন একটি প্রোগ্রামিং প্রেক্ষাপটে একটি সকেট তৈরি করা হয়, তখন প্রোগ্রামটিকে অবশ্যই তার এন্ডপয়েন্ট বৈশিষ্ট্যগুলি যেমন প্রোটোকল, TCP বা UDP এবং IP ঠিকানা এবং পোর্ট নম্বরের মতো নেটওয়ার্ক ঠিকানা কনফিগার করতে হবে। এই সকেটগুলি সার্ভারগুলিকে ডেটা পাঠাতে এবং গ্রহণ করতে দেয়। এই নিবন্ধটি সকেট প্রোগ্রামিং-এ ক্লায়েন্ট-সার্ভার মডেল কীভাবে কাজ করে তার একটি বাস্তব উদাহরণ প্রদর্শন করে।