logo

Programarea socketului în C

Ce este programarea prin socket?

Programarea socketului este o modalitate de a conecta două noduri dintr-o rețea pentru a comunica între ele. Un socket (nod) ascultă pe un anumit port la un IP, în timp ce celălalt soclu ajunge la celălalt pentru a forma o conexiune. Serverul formează soclul de ascultător în timp ce clientul ajunge la server.

Diagrama de stare pentru modelul server și client

Diagrama de stare pentru modelul de server și client al Socket

Etape pentru Server

Serverul este creat folosind următorii pași:



instanță java a

1. Crearea prizei

int sockfd = socket(domain, type, protocol)>
    sockfd: descriptor de socket, un număr întreg (ca un mâner de fișier) domeniu: întreg, specifică domeniul de comunicare. Folosim AF_LOCAL așa cum este definit în standardul POSIX pentru comunicarea între procesele de pe aceeași gazdă. Pentru comunicarea între procese pe diferite gazde conectate prin IPV4, folosim AF_INET și AF_I NET 6 pentru procesele conectate prin IPV6. tip: tip de comunicare
    SOCK_STREAM: TCP (fiabil, orientat spre conexiune)
    SOCK_DGRAM: Protocol UDP (nefiabil, fără conexiune): Valoarea protocolului pentru Internet Protocol (IP), care este 0. Acesta este același număr care apare în câmpul de protocol din antetul IP al unui pachet. (man protocoale pentru mai multe detalii)

2. Setsockopt

Acest lucru ajută la manipularea opțiunilor pentru socket la care se face referire de descriptorul de fișier sockfd. Acest lucru este complet opțional, dar ajută la reutilizarea adresei și a portului. Previne erori precum: adresa deja utilizată.

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

3. Leagă

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

După crearea socket-ului, funcția bind leagă socket-ul la adresa și numărul portului specificate în addr (structură de date personalizată). În exemplul de cod, legăm serverul de localhost, prin urmare folosim INADDR_ANY pentru a specifica adresa IP.

4. Ascultă

int listen(int sockfd, int backlog);>

Acesta pune socket-ul serverului într-un mod pasiv, unde așteaptă ca clientul să se apropie de server pentru a realiza o conexiune. Backlog, definește lungimea maximă la care poate crește coada de conexiuni în așteptare pentru sockfd. Dacă o solicitare de conectare sosește când coada este plină, clientul poate primi o eroare cu indicația ECONNREFUSED.

5. Acceptați

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

Extrage prima cerere de conexiune din coada de conexiuni în așteptare pentru sock-ul de ascultare, sockfd, creează un nou soclu conectat și returnează un nou descriptor de fișier care se referă la acel socket. În acest moment, se stabilește conexiunea între client și server, iar aceștia sunt gata să transfere date.

Etape pentru Client

1. Conexiune priză: Exact la fel ca cel al creării socket-ului serverului

2. Conectați: Apelul de sistem connect() conectează socket-ul la care se face referire de descriptorul de fișier sockfd la adresa specificată de addr. Adresa și portul serverului sunt specificate în addr.

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

Implementarea

Aici schimbăm un mesaj de salut între server și client pentru a demonstra modelul client/server.

C Program pentru a crea server

Server.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;> }>

>

>

C Program pentru a crea client

client.c

afișați aplicațiile ascunse

C




// 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;> }>

>

>

Ieșire

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

Compilarea

număr în șir java
gcc client.c -o client gcc server.c -o server>

Următorul: Programarea socketului în C/C++: Gestionarea mai multor clienți pe server fără mai multe thread-uri