logo

Programació de socket en C

Què és la programació de socket?

La programació de socket és una manera de connectar dos nodes en una xarxa per comunicar-se entre ells. Un sòcol (node) escolta en un port determinat a una IP, mentre que l'altre sòcol s'acosta a l'altre per formar una connexió. El servidor forma el sòcol d'escolta mentre el client s'acosta al servidor.

Diagrama d'estats per al model de servidor i client

Diagrama d'estat per al model de servidor i client de Socket



Etapes per al servidor

El servidor es crea seguint els passos següents:

str.replace a Java

1. Creació de sòcols

int sockfd = socket(domain, type, protocol)>
    sockfd: descriptor de socket, un nombre enter (com un controlador de fitxer) domini: enter, especifica el domini de comunicació. Utilitzem AF_LOCAL tal com es defineix a l'estàndard POSIX per a la comunicació entre processos del mateix host. Per comunicar-nos entre processos en diferents hosts connectats per IPV4, utilitzem AF_INET i AF_I NET 6 per als processos connectats per IPV6. tipus: tipus de comunicació
    SOCK_STREAM: TCP (fiable, orientat a la connexió)
    SOCK_DGRAM: protocol UDP (no fiable, sense connexió): valor del protocol per al protocol d'Internet (IP), que és 0. Aquest és el mateix número que apareix al camp del protocol a la capçalera IP d'un paquet. (protocols man per a més detalls)

2. Setsockopt

Això ajuda a manipular les opcions per al sòcol a què fa referència el descriptor de fitxers sockfd. Això és completament opcional, però ajuda a reutilitzar l'adreça i el port. Evita errors com ara: adreça que ja està en ús.

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);>

3. Lligar

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);>

Després de la creació del sòcol, la funció bind lliga el sòcol a l'adreça i el número de port especificats a addr (estructura de dades personalitzada). En el codi d'exemple, lliguem el servidor al host local, per tant, utilitzem INADDR_ANY per especificar l'adreça IP.



4. Escolta

int listen(int sockfd, int backlog);>

Posa el sòcol del servidor en un mode passiu, on espera que el client s'acosti al servidor per establir una connexió. L'endarreriment, defineix la longitud màxima a la qual pot créixer la cua de connexions pendents de sockfd. Si arriba una sol·licitud de connexió quan la cua està plena, el client pot rebre un error amb una indicació de ECONNREFUSED.

5. Acceptar

int new_socket= accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);>

Extreu la primera sol·licitud de connexió a la cua de connexions pendents per al sòcol d'escolta, sockfd, crea un nou sòcol connectat i retorna un descriptor de fitxer nou que fa referència a aquest sòcol. En aquest punt, s'estableix la connexió entre el client i el servidor, i estan preparats per transferir dades.

Etapes per al client

1. Connexió de presa: Exactament el mateix que el de la creació del sòcol del servidor



2. Connecta: La crida al sistema connect() connecta el sòcol al qual fa referència el descriptor del fitxer sockfd amb l'adreça especificada per addr. L'adreça i el port del servidor s'especifiquen a addr.

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);>

Implementació

Aquí estem intercanviant un missatge de salutació entre servidor i client per demostrar el model client/servidor.

C Programa per crear servidors

Servidor.c

C




// Server side C program to demonstrate Socket> // programming> #include> #include> #include> #include> #include> #include> #define PORT 8080> int> main(>int> argc,>char> const>* argv[])> {> >int> server_fd, new_socket;> >ssize_t valread;> >struct> sockaddr_in address;> >int> opt = 1;> >socklen_t addrlen =>sizeof>(address);> >char> buffer[1024] = { 0 };> >char>* hello =>'Hello from server'>;> >// Creating socket file descriptor> >if> ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) <0) {> >perror>(>'socket failed'>);> >exit>(EXIT_FAILURE);> >}> >// Forcefully attaching socket to the port 8080> >if> (setsockopt(server_fd, SOL_SOCKET,> >SO_REUSEADDR | SO_REUSEPORT, &opt,> >sizeof>(opt))) {> >perror>(>'setsockopt'>);> >exit>(EXIT_FAILURE);> >}> >address.sin_family = AF_INET;> >address.sin_addr.s_addr = INADDR_ANY;> >address.sin_port = htons(PORT);> >// Forcefully attaching socket to the port 8080> >if> (bind(server_fd, (>struct> sockaddr*)&address,> >sizeof>(address))> ><0) {> >perror>(>'bind failed'>);> >exit>(EXIT_FAILURE);> >}> >if> (listen(server_fd, 3) <0) {> >perror>(>'listen'>);> >exit>(EXIT_FAILURE);> >}> >if> ((new_socket> >= accept(server_fd, (>struct> sockaddr*)&address,> >&addrlen))> ><0) {> >perror>(>'accept'>);> >exit>(EXIT_FAILURE);> >}> >valread = read(new_socket, buffer,> >1024 - 1);>// subtract 1 for the null> >// terminator at the end> >printf>(>'%s '>, buffer);> >send(new_socket, hello,>strlen>(hello), 0);> >printf>(>'Hello message sent '>);> >// closing the connected socket> >close(new_socket);> >// closing the listening socket> >close(server_fd);> >return> 0;> }>

>

operador java
>

C Programa per crear client

client.c

C




Kat timpf
// Client side C program to demonstrate Socket> // programming> #include> #include> #include> #include> #include> #define PORT 8080> int> main(>int> argc,>char> const>* argv[])> {> >int> status, valread, client_fd;> >struct> sockaddr_in serv_addr;> >char>* hello =>'Hello from client'>;> >char> buffer[1024] = { 0 };> >if> ((client_fd = socket(AF_INET, SOCK_STREAM, 0)) <0) {> >printf>(>' Socket creation error '>);> >return> -1;> >}> >serv_addr.sin_family = AF_INET;> >serv_addr.sin_port = htons(PORT);> >// Convert IPv4 and IPv6 addresses from text to binary> >// form> >if> (inet_pton(AF_INET,>'127.0.0.1'>, &serv_addr.sin_addr)> ><= 0) {> >printf>(> >' Invalid address/ Address not supported '>);> >return> -1;> >}> >if> ((status> >= connect(client_fd, (>struct> sockaddr*)&serv_addr,> >sizeof>(serv_addr)))> ><0) {> >printf>(>' Connection Failed '>);> >return> -1;> >}> >send(client_fd, hello,>strlen>(hello), 0);> >printf>(>'Hello message sent '>);> >valread = read(client_fd, buffer,> >1024 - 1);>// subtract 1 for the null> >// terminator at the end> >printf>(>'%s '>, buffer);> >// closing the connected socket> >close(client_fd);> >return> 0;> }>

>

>

Sortida

Client:Hello message sent Hello from server Server:Hello from client Hello message sent>

Compilant

gcc client.c -o client gcc server.c -o server>

Següent: Programació de sòcols en C/C++: maneig de diversos clients al servidor sense fils múltiples