Programació de socket en C++

Programacio De Socket En C



La programació de socket s'ha convertit en un tema important en el camp de les xarxes d'ordinadors. Implica establir una connexió entre dos nodes, servidor i client per comunicar-se entre ells sense cap interrupció. El servidor actua com a oient al canal de comunicació i escolta el client en un port específic a una adreça IP. D'altra banda, el client actua com a comunicador en el canal de comunicació. El client contacta amb el servidor per tal de crear una connexió i establir un contacte amb el servidor. Aquest article pretén proporcionar una guia completa i detallada per a la programació de sockets en C++, que cobreix els conceptes bàsics, presenta exemples pràctics i proporciona una explicació detallada del codi.

Establiment del model client-servidor

La programació de sockets és el procés que construeix un canal de comunicació entre el servidor i el client mitjançant sockets. Al codi d'exemple següent, el client inicia un contacte amb el servidor i el servidor està configurat per acceptar les connexions del client. Entenem els segments de codi de servidor i client demostrant el seu funcionament bàsic dins de la comunicació de xarxa. El següent és el codi del costat del servidor. Vegem primer el codi i després expliquem el codi en detall, punt per punt.

1. Servidor







El codi per al costat del servidor del model es mostra a continuació. Vegem què passa al codi:



#inclou
#inclou
#include
#inclou

utilitzant espai de noms std ;

#definir el PORT 8080
#definir MAX_BUF_SIZE 1024

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

si ( ( ser_socket = endoll ( AF_INET, SOCK_STREAM, 0 ) ) == - 1 ) {
terror ( 'Error en la creació del sòcol' ) ;
sortida ( EXIT_FAILURE ) ;
}

adreça_ser. sin_família = OF_INET ;
adreça_ser. sin_addr . s_addr = INADDR_ANY ;
adreça_ser. sense_port = htons ( PORT ) ;

si ( lligar ( ser_socket, ( estructura sockaddr * ) & adreça_ser, mida de ( adreça_ser ) ) == - 1 ) {
terror ( 'Fracàs en la vinculació' ) ;
sortida ( EXIT_FAILURE ) ;
}

si ( escolta ( ser_socket, 3 ) == - 1 ) {
terror ( 'No s'ha pogut escoltar' ) ;
sortida ( EXIT_FAILURE ) ;
}

cout << 'Servidor que escolta al port' << PORT << '... \n ' ;

socklen_t cli_address_len = mida de ( adreça_cli ) ;
si ( ( cli_socket = acceptar ( ser_socket, ( estructura sockaddr * ) & adreça_cli, & cli_address_len ) ) == - 1 ) {
terror ( 'No s'ha pogut acceptar' ) ;
sortida ( EXIT_FAILURE ) ;
}

llegir ( cli_socket, buf, MAX_BUF_SIZE ) ;
cout << 'El missatge del client és:' << buf << endl ;

enviar ( cli_socket, 'Missatge del servidor' , strlen ( 'Missatge del servidor' ) , 0 ) ;

Tanca ( cli_socket ) ;
Tanca ( ser_socket ) ;

tornar 0 ;
}

L'exemple donat és el codi del servidor del programa C++. Aquest codi funciona per a un servidor TCP senzill per escoltar les connexions en un únic port específic. Quan una connexió es crea correctament, el servidor rebrà un missatge que s'envia des del client. Després d'això, l'imprimeix a la consola i envia un missatge de resposta al client. Entenem cada línia de codi.



El programa comença per incloure les biblioteques: 'iostream' per a definicions d'entrada/sortida estàndard, 'cstring' per a funcions de gestió de cadenes, 'unistd.h' per proporcionar accés a l'API del sistema operatiu POSIX i 'arpa/inet.h' per realitzar les operacions d'Internet. La sentència '#define PORT 8080' significa que defineix el número de port 8080 en què el servidor escoltarà. El '#define MAX_BUF_SIZE 1024' significa la mida màxima de la memòria intermèdia per a les dades entrants que és 1024.





A la funció principal, s'inicialitzen dues variables, 'ser_socket' i 'cli_socket', per representar tant el servidor com el client, respectivament. Les altres tres variables que són 'sockaddr_in', 'ser_address' i 'cli_address' de tipus 'struct' s'inicialitzen com a estructures d'adreces per al servidor i el client. Després d'això, s'inicialitza un buffer anomenat 'buf' que emmagatzema les dades que provenen del client.

La funció socket() en la condició 'si' crea un nou socket TCP. AF_INET denota IPv4, SOCK_STREAM representa el sòcol TCP fiable i orientat a la connexió, l'últim argument que és 0 es dóna per seleccionar el protocol TCP predeterminat, INADDR_ANY accepta les connexions a qualsevol adreça IP i htons (PORT) converteix el número de port del ordre de bytes de l'amfitrió a l'ordre de bytes de xarxa.



Com que tot està definit correctament, el següent pas és configurar el servidor com a llista al port donat i acceptar les connexions a qualsevol interfície de xarxa. El sòcol es dóna amb la informació a “ser_address” pel mètode bind(). Imprimim un error i finalitzem el procés si falla l'enquadernació. La funció accept() obre un nou sòcol per a la connexió amb el client, mentre que la funció listen() indica al servidor que espere les connexions entrants. Si la funció accept() falla, s'imprimeix el missatge d'error i la funció sortirà.

A continuació, el servidor llegeix el missatge del client amb la funció read() al buffer 'buf' i després l'imprimeix a la consola. El servidor utilitza la funció send() per enviar un missatge en resposta al client. Finalment, utilitzant close(), el servidor tanca el sòcol del client, finalitzant el programa de manera que totes les connexions es tanquin correctament i no hi hagi probabilitat de violació de dades.

2. Client

Ara, vegem què passa en el model de client:

#inclou
#inclou
#include
#inclou

#definir el PORT 8080
#define SERVER_IP '127.0.0.1'

int principal ( ) {
int cli_socket ;
estructura sockaddr_in ser_address ;
const char * missatge = 'El client està enviant salutacions!' ;

si ( ( cli_socket = endoll ( AF_INET, SOCK_STREAM, 0 ) ) == - 1 ) {
terror ( 'Error en la creació del sòcol' ) ;
sortida ( EXIT_FAILURE ) ;
}

adreça_ser. sin_família = OF_INET ;
adreça_ser. sense_port = htons ( PORT ) ;

si ( inet_pton ( AF_INET, SERVER_IP, & adreça_ser. sin_addr ) <= 0 ) {
terror ( 'Adreça incorrecta' ) ;
sortida ( EXIT_FAILURE ) ;
}

si ( connectar ( cli_socket, ( estructura sockaddr * ) & adreça_ser, mida de ( adreça_ser ) ) == - 1 ) {
terror ( 'Falla de connexió' ) ;
sortida ( EXIT_FAILURE ) ;
}
enviar ( cli_socket, missatge, strlen ( missatge ) , 0 ) ;

char buf [ 1024 ] = { 0 } ;
llegir ( cli_socket, buf, mida de ( buf ) ) ;
std :: cout << 'Resposta del servidor:' << buf << std :: endl ;

Tanca ( cli_socket ) ;
tornar 0 ;
}

Vegem cada línia de codi per entendre com funciona el programa.

Les mateixes quatre biblioteques (iostream, cstring, unistd.h i arpa/inet.h) també s'inclouen al costat del client. També es defineix un número de port juntament amb l'adreça IP de l'amfitrió local 127.0.0.1. Es dóna el missatge que s'ha de lliurar al servidor. El client i el servidor han d'establir una connexió com el següent pas:

El 'si ((client_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1);' crea un sòcol per a IPv4 amb un tipus de flux i el protocol TCP per defecte. El perror() imprimeix els detalls de l'error si la funció socket() no aconsegueix establir una connexió i surt del programa.

El 'server_address.sin_port = htons(PORT);' estableix el número de port després de convertir a l'ordre de bytes de xarxa. Després, aquí es dóna un altre missatge d'error que és 'Adreça incorrecta' que s'imprimeix si hi ha alguna cosa malament amb l'adreça. En localitzar l'adreça a 'ser_address', el client es connectarà al servidor. Si la connexió falla, s'imprimeixen els detalls de l'error. La funció send() transferirà el missatge al servidor, assegurant-se que no conté cap marca.

Per rebre i emmagatzemar una resposta del servidor, s'inicia un buffer anomenat 'buf' de tipus 'char'. La funció read() llegeix la resposta del servidor a la memòria intermèdia. Finalment, la resposta del servidor s'imprimeix a la consola. Finalment, la connexió es tanca utilitzant la instrucció close() per finalitzar el sòcol. El següent és el resultat del programa:

Conclusió

La programació de socket és una part important de la comunicació en xarxa en informàtica. Permet el desenvolupament d'aplicacions que es puguin comunicar a través de la xarxa, permetent un ampli ventall de possibilitats, des d'arquitectures simples client-servidor fins a sistemes distribuïts estructurats. Quan es crea un sòcol en un context de programació, el programa ha de configurar les característiques del seu punt final, com ara els protocols, TCP o UDP, i l'adreça de xarxa com l'adreça IP i el número de port. Aquests sòcols permeten als servidors enviar i rebre dades. Aquest article mostra un exemple pràctic de com funciona el model client-servidor a la programació de socket.