Socket-programmering i C++

Socket Programmering I C



Socket-programmering er blevet et vigtigt emne inden for computernetværk. Det involverer etablering af en forbindelse mellem to noder, server og klient for at kommunikere med hinanden uden nogen afbrydelse. Serveren fungerer som lytter i kommunikationskanalen og lytter til klienten på en bestemt port på en IP-adresse. På den anden side fungerer klienten som kommunikatør i kommunikationskanalen. Klienten kontakter serveren for at oprette en forbindelse og oprette en kontakt med serveren. Denne artikel har til formål at give en omfattende og detaljeret vejledning til socket-programmering i C++, der dækker det grundlæggende, præsenterer praktiske eksempler og giver en detaljeret forklaring af koden.

Etablering af klient-servermodellen

Socket-programmering er den proces, der opbygger en kommunikationskanal mellem serveren og klienten ved hjælp af sockets. I følgende eksempelkode starter klienten en kontakt med serveren, og serveren er sat op til at acceptere klientforbindelserne. Lad os forstå server- og klientkodesegmenterne ved at demonstrere deres kernearbejde inden for netværkskommunikationen. Følgende er koden på serversiden. Lad os først se koden og derefter forklare koden i detaljer, punkt for punkt.

1. Serverside







Koden til serversiden af ​​modellen er angivet i det følgende. Lad os se, hvad der sker i koden:



#include
#include
#include
#include

ved brug af navneområde std ;

#define PORT 8080
#define MAX_BUF_SIZE 1024

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

hvis ( ( ser_socket = stikkontakt ( AF_INET, SOCK_STREAM, 0 ) ) == - 1 ) {
fejl ( 'Fejl ved oprettelse af socket' ) ;
Afslut ( EXIT_FAILURE ) ;
}

ser_adresse. sin_familie = AF_INET ;
ser_adresse. sin_addr . s_addr = INADDR_ANY ;
ser_adresse. sin_port = htons ( HAVN ) ;

hvis ( binde ( be_socket, ( struktur sockaddr * ) & ser_adresse, størrelse på ( ser_adresse ) ) == - 1 ) {
fejl ( 'Fejl ved binding' ) ;
Afslut ( EXIT_FAILURE ) ;
}

hvis ( Hør efter ( be_socket, 3 ) == - 1 ) {
fejl ( 'Det lykkedes ikke at lytte' ) ;
Afslut ( EXIT_FAILURE ) ;
}

cout << 'Server lytter på port' << HAVN << '... \n ' ;

socklen_t cli_address_len = størrelse af ( cli_adresse ) ;
hvis ( ( cli_socket = acceptere ( be_socket, ( struktur sockaddr * ) & cli_adresse, & cli_adresse_len ) ) == - 1 ) {
fejl ( 'Kunnede ikke acceptere' ) ;
Afslut ( EXIT_FAILURE ) ;
}

Læs ( cli_socket, buf, MAX_BUF_SIZE ) ;
cout << 'Kundens besked er:' << buf << endl ;

sende ( cli_socket, 'Servers besked' , strlen ( 'Servers besked' ) , 0 ) ;

tæt ( cli_socket ) ;
tæt ( ser_socket ) ;

Vend tilbage 0 ;
}

Det givne eksempel er server-side-koden for C++-programmet. Denne kode fungerer for en simpel TCP-server til at lytte efter forbindelser på en enkelt specifik port. Når en forbindelse er oprettet, modtager serveren en besked, der sendes fra klienten. Derefter udskriver den det på konsollen og sender en svarmeddelelse til klienten. Lad os forstå hver linje kode.



Programmet starter med at inkludere bibliotekerne: 'iostream' for standard input/output definitioner, 'cstring' for strenghåndteringsfunktioner, 'unistd.h' for at give adgang til POSIX operativsystem API, og 'arpa/inet.h' til udføre internetoperationer. '#define PORT 8080'-sætningen betyder, at den definerer portnummeret 8080, som serveren vil lytte til. '#define MAX_BUF_SIZE 1024' betyder den maksimale bufferstørrelse for de indgående data, som er 1024.





I hovedfunktionen initialiseres to variable, 'ser_socket' og 'cli_socket', for at repræsentere henholdsvis serveren og klienten. De andre tre variabler, som er 'sockaddr_in', 'ser_address' og 'cli_address' af typen 'struct' initialiseres som adressestrukturer for serveren og klienten. Derefter initialiseres en buffer ved navn 'buf', som gemmer de data, der kommer fra klienten.

Socket()-funktionen i 'if'-tilstanden opretter en ny TCP-socket. AF_INET angiver IPv4, SOCK_STREAM repræsenterer den forbindelsesorienterede og pålidelige TCP-socket, det sidste argument, som er 0, gives for at vælge standard TCP-protokollen, INADDR_ANY accepterer forbindelserne på enhver IP-adresse, og htons (PORT) konverterer portnummeret fra værtsbyterækkefølge til netværksbyterækkefølgen.



Da alt er defineret korrekt, er næste trin at opsætte serveren som en liste på den givne port og acceptere forbindelserne på enhver netværksgrænseflade. Socket er givet med informationen i 'ser_address' ved bind()-metoden. Vi udskriver en fejl og afslutter processen, hvis bindingen mislykkes. Accept()-funktionen åbner en ny socket for forbindelsen med klienten, hvorimod listen()-funktionen instruerer serveren om at vente på indgående forbindelser. Hvis funktionen accept() mislykkes, udskrives fejlmeddelelsen, og funktionen afsluttes.

Derefter læser serveren klientmeddelelsen med read()-funktionen ind i 'buf'-bufferen og udskriver den derefter til konsollen. Send()-funktionen bruges af serveren til at sende en besked som svar til klienten. Til sidst, ved hjælp af close(), lukker serveren klientens socket, og afslutter programmet, så alle forbindelser lukkes korrekt, og der er ingen sandsynlighed for databrud.

2. Kundeside

Lad os nu se, hvad der sker i klientmodellen:

#include
#include
#include
#include

#define PORT 8080
#define SERVER_IP '127.0.0.1'

int vigtigste ( ) {
int cli_socket ;
struktur sockaddr_in ser_address ;
konst char * besked = 'Kunde sender hilsener!' ;

hvis ( ( cli_socket = stikkontakt ( AF_INET, SOCK_STREAM, 0 ) ) == - 1 ) {
fejl ( 'Fejl under oprettelse af socket' ) ;
Afslut ( EXIT_FAILURE ) ;
}

ser_adresse. sin_familie = AF_INET ;
ser_adresse. sin_port = htons ( HAVN ) ;

hvis ( inet_pton ( AF_INET, SERVER_IP, & ser_adresse. sin_addr ) <= 0 ) {
fejl ( 'Forkert adresse' ) ;
Afslut ( EXIT_FAILURE ) ;
}

hvis ( Opret forbindelse ( cli_socket, ( struktur sockaddr * ) & ser_adresse, størrelse af ( ser_adresse ) ) == - 1 ) {
fejl ( 'Forbindelsesfejl' ) ;
Afslut ( EXIT_FAILURE ) ;
}
sende ( cli_socket, besked, strlen ( besked ) , 0 ) ;

char buf [ 1024 ] = { 0 } ;
Læs ( cli_socket, buf, størrelse af ( buf ) ) ;
std :: cout << 'Serversvar:' << buf << std :: endl ;

tæt ( cli_socket ) ;
Vend tilbage 0 ;
}

Lad os se hver linje kode for at forstå, hvordan programmet fungerer.

De samme fire biblioteker – iostream, cstring, unistd.h og arpa/inet.h – er også inkluderet på klientsiden. Et portnummer er også defineret sammen med IP-adressen på den lokale vært 127.0.0.1. Den besked, der skal leveres til serveren, er givet. Klienten og serveren skal etablere en forbindelse som følgende trin:

'if ((client_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1);' opretter en socket til IPv4 med en stream-type og standardprotokollen TCP. Perror() udskriver fejldetaljerne, hvis socket()-funktionen ikke kan etablere en forbindelse og afslutter programmet.

'server_address.sin_port = htons(PORT);' indstiller portnummeret efter konvertering til netværkets byte-rækkefølge. Herefter vises en anden fejlmeddelelse, som er 'Forkert adresse', som udskrives, hvis der er noget galt med adressen. Ved at lokalisere adressen i 'ser_address', vil klienten oprette forbindelse til serveren. Hvis forbindelsen mislykkes, udskrives fejloplysningerne. Send()-funktionen vil overføre beskeden til serveren og sikre, at den ikke indeholder noget flag.

For at modtage og gemme et svar fra serveren initialiseres en buffer med navnet 'buf' af typen 'char'. Read()-funktionen læser serverens svar ind i bufferen. Til sidst udskrives serverens svar til konsollen. Til sidst lukkes forbindelsen ved hjælp af close()-sætningen for at afslutte socket. Følgende er output fra programmet:

Konklusion

Socket-programmering er en vigtig del af netværkskommunikation inden for datalogi. Det muliggør udvikling af applikationer, der kan kommunikere over netværket, hvilket muliggør en bred vifte af muligheder fra simple klient-server-arkitekturer til strukturerede distribuerede systemer. Når en socket oprettes i en programmeringskontekst, skal programmet konfigurere dets endepunktskarakteristika såsom protokollerne, TCP eller UDP og netværksadressen som IP-adressen og portnummeret. Disse sockets lader serverne sende og modtage data. Denne artikel demonstrerer et praktisk eksempel på, hvordan klient-server-modellen i socket-programmering fungerer.