logo

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:



podreťazec metódy java

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




prevod reťazca na dátum
// 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


previesť znak na reťazec



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