Socket Programming sa C++

Socket Programming Sa C



Ang socket programming ay naging isang mahalagang paksa sa larangan ng computer networking. Ito ay nagsasangkot ng pagtatatag ng koneksyon sa pagitan ng dalawang node, server, at kliyente upang makipag-usap sa isa't isa nang walang anumang pagkaantala. Ang server ay kumikilos bilang isang tagapakinig sa channel ng komunikasyon at nakikinig sa kliyente sa isang partikular na port sa isang IP address. Sa kabilang banda, ang kliyente ay kumikilos bilang isang tagapagbalita sa channel ng komunikasyon. Nakikipag-ugnayan ang kliyente sa server upang makalikha ng koneksyon at makipag-ugnayan sa server. Nilalayon ng artikulong ito na magbigay ng komprehensibo at detalyadong gabay sa socket programming sa C++, na sumasaklaw sa mga pangunahing kaalaman, paglalahad ng mga praktikal na halimbawa, at pagbibigay ng detalyadong paliwanag ng code.

Pagtatatag ng Client-Server Model

Ang socket programming ay ang proseso na bumubuo ng channel ng komunikasyon sa pagitan ng server at ng kliyente gamit ang mga socket. Sa sumusunod na halimbawang code, ang kliyente ay magsisimula ng isang contact sa server, at ang server ay naka-set up upang tanggapin ang mga koneksyon ng kliyente. Ipaalam sa amin na maunawaan ang mga segment ng server at client code sa pamamagitan ng pagpapakita ng kanilang pangunahing gumagana sa loob ng komunikasyon sa network. Ang sumusunod ay ang server-side code. Tingnan muna natin ang code at pagkatapos ay ipaliwanag ang code nang detalyado, bawat punto.

1. Gilid ng Server







Ang code para sa server side ng modelo ay ibinigay sa sumusunod. Tingnan natin kung ano ang nangyayari sa code:



#include
#include
#include
#include

gamit namespace std ;

#define PORT 8080
#define MAX_BUF_SIZE 1024

int pangunahing ( ) {
int ser_socket, cli_socket ;
struct sockaddr_in ser_address, cli_address ;
char buf [ MAX_BUF_SIZE ] = { 0 } ;

kung ( ( ser_socket = saksakan ( AF_INET, SOCK_STREAM, 0 ) ) == - 1 ) {
kaguluhan ( 'Error sa paggawa ng Socket' ) ;
labasan ( EXIT_FAILURE ) ;
}

ser_address. kasalanan_pamilya = OF_INET ;
ser_address. sin_addr . s_addr = INADDR_ANY ;
ser_address. sin_port = htons ( PORT ) ;

kung ( magbigkis ( be_socket, ( struct sockaddr * ) at ser_address, sukat ng ( ser_address ) ) == - 1 ) {
kaguluhan ( 'Kabiguan sa pagkakatali' ) ;
labasan ( EXIT_FAILURE ) ;
}

kung ( makinig ka ( be_socket, 3 ) == - 1 ) {
kaguluhan ( 'Nabigong Makinig' ) ;
labasan ( EXIT_FAILURE ) ;
}

cout << 'Nakikinig ang server sa port' << PORT << '... \n ' ;

socklen_t cli_address_len = sukat ng ( cli_address ) ;
kung ( ( cli_socket = tanggapin ( be_socket, ( struct sockaddr * ) at cli_address, at cli_address_len ) ) == - 1 ) {
kaguluhan ( 'Nabigong tanggapin' ) ;
labasan ( EXIT_FAILURE ) ;
}

basahin ( cli_socket, buf, MAX_BUF_SIZE ) ;
cout << 'Ang mensahe ng kliyente ay: ' << buf << endl ;

ipadala ( cli_socket, 'Mensahe ng server' , strlen ( 'Mensahe ng server' ) , 0 ) ;

malapit na ( cli_socket ) ;
malapit na ( ser_socket ) ;

bumalik 0 ;
}

Ang ibinigay na halimbawa ay ang server-side code ng C++ program. Gumagana ang code na ito para sa isang simpleng TCP server upang makinig ng mga koneksyon sa isang partikular na port. Kapag ang isang koneksyon ay matagumpay na nalikha, ang server ay makakatanggap ng isang mensahe na ipinadala mula sa kliyente. Pagkatapos nito, ipi-print ito sa console at magpapadala ng mensahe ng tugon sa kliyente. Ipaalam sa amin na maunawaan ang bawat linya ng code.



Ang programa ay nagsisimula sa pagsasama ng mga aklatan: 'iostream' para sa karaniwang input/output na mga kahulugan, 'cstring' para sa string handling function, 'unistd.h' upang magbigay ng access sa POSIX operating system API, at 'arpa/inet.h' sa isagawa ang mga operasyon sa internet. Ang '#define PORT 8080' na pahayag ay nangangahulugang tinutukoy nito ang port number 8080 kung saan makikinig ang server. Ang ibig sabihin ng “#define MAX_BUF_SIZE 1024” ay ang maximum na laki ng buffer para sa papasok na data na 1024.





Sa pangunahing function, dalawang variable ang sinisimulan, 'ser_socket' at 'cli_socket', upang kumatawan sa server at client, ayon sa pagkakabanggit. Ang iba pang tatlong variable na 'sockaddr_in', 'ser_address', at 'cli_address' ng uri na 'struct' ay sinisimulan bilang mga istruktura ng address para sa server at client. Pagkatapos nito, ang isang buffer na pinangalanang 'buf' ay pinasimulan na nag-iimbak ng data na nagmumula sa kliyente.

Ang socket() function sa kondisyong “if” ay lumilikha ng bagong TCP socket. Ang AF_INET ay tumutukoy sa IPv4, SOCK_STREAM ay kumakatawan sa koneksyon-oriented at maaasahang TCP socket, ang huling argumento na 0 ay ibinigay upang piliin ang default na TCP protocol, INADDR_ANY ay tumatanggap ng mga koneksyon sa anumang IP address, at htons (PORT) ay nagko-convert ng port number mula sa host byte order sa network byte order.



Dahil ang lahat ay natukoy nang maayos, ang susunod na hakbang ay i-set up ang server bilang isang lister sa ibinigay na port at tanggapin ang mga koneksyon sa anumang interface ng network. Ang socket ay ibinigay kasama ang impormasyon sa 'ser_address' sa pamamagitan ng bind() na pamamaraan. Nag-print kami ng error at tinatapos ang proseso kung nabigo ang pagbubuklod. Ang accept() function ay nagbubukas ng bagong socket para sa koneksyon sa client, samantalang ang listen() function ay nagtuturo sa server na maghintay para sa mga papasok na koneksyon. Kung nabigo ang accept() function, ipi-print ang mensahe ng error at lalabas ang function.

Susunod, binabasa ng server ang mensahe ng kliyente na may function na read() sa buffer na 'buf' at pagkatapos ay i-print ito sa console. Ang send() function ay ginagamit ng server upang magpadala ng mensahe bilang tugon sa kliyente. Panghuli, gamit ang close(), isinasara ng server ang socket ng kliyente, tinatapos ang programa upang ang lahat ng koneksyon ay sarado nang maayos at walang posibilidad na masira ang data.

2. Side ng Kliyente

Ngayon, tingnan natin kung ano ang nangyayari sa modelo ng kliyente:

#include
#include
#include
#include

#define PORT 8080
#define SERVER_IP '127.0.0.1'

int pangunahing ( ) {
int cli_socket ;
struct sockaddr_in ser_address ;
const char * mensahe = 'Nagpapadala ang kliyente ng pagbati!' ;

kung ( ( cli_socket = saksakan ( AF_INET, SOCK_STREAM, 0 ) ) == - 1 ) {
kaguluhan ( 'Error sa paggawa ng socket' ) ;
labasan ( EXIT_FAILURE ) ;
}

ser_address. kasalanan_pamilya = OF_INET ;
ser_address. sin_port = htons ( PORT ) ;

kung ( inet_pton ( AF_INET, SERVER_IP, at ser_address. sin_addr ) <= 0 ) {
kaguluhan ( 'Maling address' ) ;
labasan ( EXIT_FAILURE ) ;
}

kung ( kumonekta ( cli_socket, ( struct sockaddr * ) at ser_address, sukat ng ( ser_address ) ) == - 1 ) {
kaguluhan ( 'Pagkabigo ng koneksyon' ) ;
labasan ( EXIT_FAILURE ) ;
}
ipadala ( cli_socket, mesg, strlen ( mensahe ) , 0 ) ;

char buf [ 1024 ] = { 0 } ;
basahin ( cli_socket, buf, sukat ng ( buf ) ) ;
std :: cout << 'Tugon ng server: ' << buf << std :: endl ;

malapit na ( cli_socket ) ;
bumalik 0 ;
}

Tingnan natin ang bawat linya ng code upang maunawaan kung paano gumagana ang programa.

Ang parehong apat na aklatan - iostream, cstring, unistd.h, at arpa/inet.h - ay kasama rin sa panig ng kliyente. Ang isang numero ng port ay tinukoy din kasama ang IP address ng lokal na host 127.0.0.1. Ang mensahe na kailangang maihatid sa server ay ibinigay. Ang kliyente at server ay kailangang magtatag ng isang koneksyon bilang sumusunod na hakbang:

Ang “if ((client_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1);” lumilikha ng socket para sa IPv4 na may uri ng stream at ang default na protocol na TCP. Ang perror() ay nagpi-print ng mga detalye ng error kung ang socket() function ay nabigo na magtatag ng isang koneksyon at lumabas sa programa.

Ang 'server_address.sin_port = htons(PORT);' itinatakda ang numero ng port pagkatapos mag-convert sa network byte order. Pagkatapos, isa pang mensahe ng kabiguan na 'Maling address' ang ibibigay dito na naka-print kung may mali sa address. Sa pamamagitan ng paghahanap ng address sa 'ser_address', ang kliyente ay kumonekta sa server. Kung nabigo ang koneksyon, ang mga detalye ng error ay naka-print. Ililipat ng function na send() ang mensahe sa server, na tinitiyak na hindi ito naglalaman ng anumang flag.

Upang makatanggap at mag-imbak ng tugon mula sa server, isang buffer na pinangalanang 'buf' ng uri na 'char' ay sinisimulan. Binabasa ng function na read() ang tugon ng server sa buffer. Sa wakas, ang tugon ng server ay naka-print sa console. Sa wakas, ang koneksyon ay sarado gamit ang close() na pahayag upang wakasan ang socket. Ang sumusunod ay ang output ng programa:

Konklusyon

Ang socket programming ay isang mahalagang bahagi ng network communication sa computer science. Binibigyang-daan nito ang pagbuo ng mga application na maaaring makipag-usap sa network, na nagbibigay-daan sa malawak na hanay ng mga posibilidad mula sa mga simpleng arkitektura ng client-server hanggang sa mga structured na distributed system. Kapag ang isang socket ay ginawa sa isang konteksto ng programming, dapat i-configure ng program ang mga katangian ng endpoint nito gaya ng mga protocol, TCP o UDP, at ang address ng network tulad ng IP address at numero ng port. Hinahayaan ng mga socket na ito ang mga server na magpadala at tumanggap ng data. Ang artikulong ito ay nagpapakita ng praktikal na halimbawa kung paano gumagana ang modelo ng client-server sa socket programming.