Programovanie soketov v C

Programovanie soketov v C

Čo je to Socket Programovanie?

Programovanie soketov je spôsob prepojenia dvoch uzlov v sieti, aby spolu komunikovali. Jeden soket (uzol) počúva na konkrétnom porte na IP, zatiaľ čo druhý soket siaha k druhému, aby vytvoril spojenie. Server vytvára soket načúvania, zatiaľ čo klient oslovuje server.

Stavový diagram pre model servera a klienta

Stavový diagram pre serverový a klientsky model Socketu

Etapy pre server

Server sa vytvorí pomocou nasledujúcich krokov:

1. Vytvorenie zásuvky

int sockfd = socket(domain, type, protocol) 
    sockfd: deskriptor zásuvky, celé číslo (ako popisovač súboru) doména: celé číslo, špecifikuje komunikačnú doménu. Na komunikáciu medzi procesmi na rovnakom hostiteľovi používame AF_ LOCAL, ako je definované v štandarde POSIX. Na komunikáciu medzi procesmi na rôznych hostiteľoch pripojených cez IPV4 používame AF_INET a AF_I NET 6 pre procesy pripojené cez IPV6. typ: typ komunikácie
    SOCK_STREAM: TCP (spoľahlivý, orientovaný na pripojenie)
    SOCK_DGRAM: Protokol UDP (nespoľahlivý, bez pripojenia): Hodnota protokolu pre internetový protokol (IP), ktorá je 0. Toto je rovnaké číslo, aké sa zobrazuje v poli protokolu v hlavičke IP paketu. (ďalšie podrobnosti nájdete v protokoloch man)

2. Setsockopt

Pomáha to pri manipulácii s voľbami pre soket, na ktorý odkazuje deskriptor súboru sockfd. Toto je úplne voliteľné, ale pomáha pri opätovnom použití adresy a portu. Zabraňuje chybám, ako napríklad: adresa sa už používa.

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

3. Zviazať

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

Po vytvorení soketu funkcia bind naviaže soket na adresu a číslo portu špecifikované v addr (vlastná dátová štruktúra). Vo vzorovom kóde naviažeme server na localhost, preto na špecifikáciu IP adresy používame INADDR_ANY.

4. Počúvajte

int listen(int sockfd, int backlog); 

Uvádza soket servera do pasívneho režimu, kde čaká, kým sa klient priblíži k serveru, aby vytvoril spojenie. Backlog definuje maximálnu dĺžku, do ktorej môže narásť front čakajúcich pripojení pre sockfd. Ak žiadosť o pripojenie príde, keď je front plný, klient môže dostať chybu s označením ECONNREFUSED.

5. Prijmite

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

Extrahuje prvú požiadavku na pripojenie z frontu čakajúcich pripojení pre počúvajúci soket, sockfd, vytvorí nový pripojený soket a vráti nový deskriptor súboru odkazujúci na tento soket. V tomto bode sa vytvorí spojenie medzi klientom a serverom a sú pripravení na prenos údajov.

Etapy pre klienta

1. Zásuvkové pripojenie: Presne to isté ako pri vytváraní soketu servera

2. Pripojiť: Systémové volanie connect() spája soket, na ktorý odkazuje deskriptor súboru sockfd, na adresu zadanú addr. Adresa a port servera sú uvedené v adr.

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

Implementácia

Tu si vymieňame jednu pozdravnú správu medzi serverom a klientom, aby sme demonštrovali model klient/server.

C Program na vytvorenie servera

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 na vytvorenie klienta

klient.c

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

Výkon

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

Zostavovanie

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

Ďalej: Programovanie soketov v C/C++: Obsluha viacerých klientov na serveri bez viacerých vlákien