logo

Programování socketů v C

Co je Socket Programming?

Soketové programování je způsob propojení dvou uzlů v síti za účelem vzájemné komunikace. Jeden soket (uzel) naslouchá na konkrétním portu na IP, zatímco druhý soket zasahuje do druhého, aby vytvořil spojení. Server tvoří soket posluchače, zatímco klient oslovuje server.

Stavový diagram pro model serveru a klienta

Stavový diagram pro serverový a klientský model Socketu

Fáze pro server

Server se vytvoří pomocí následujících kroků:



linuxové chybové kódy

1. Vytvoření zásuvky

int sockfd = socket(domain, type, protocol)>
    sockfd: deskriptor soketu, celé číslo (jako popisovač souboru) doména: celé číslo, určuje komunikační doménu. Pro komunikaci mezi procesy na stejném hostiteli používáme AF_ LOCAL, jak je definováno ve standardu POSIX. Pro komunikaci mezi procesy na různých hostitelích připojených přes IPV4 používáme AF_INET a AF_I NET 6 pro procesy připojené přes IPV6. typ: typ komunikace
    SOCK_STREAM: TCP(spolehlivý, orientovaný na připojení)
    SOCK_DGRAM: UDP (unreliable, connectionless) protocol: Hodnota protokolu pro internetový protokol (IP), která je 0. Toto je stejné číslo, které se objevuje v poli protokolu v hlavičce IP paketu. (další podrobnosti naleznete v protokolech man)

2. Setsockopt

To pomáhá při manipulaci s volbami pro soket, na který odkazuje deskriptor souboru sockfd. Toto je zcela volitelné, ale pomáhá při opětovném použití adresy a portu. Zabraňuje chybám, jako je: adresa se již používá.

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

3. Svázat

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

Po vytvoření soketu funkce bind sváže soket s adresou a číslem portu zadaným v addr (vlastní datová struktura). V ukázkovém kódu vážeme server k localhost, proto používáme INADDR_ANY k určení IP adresy.

4. Poslouchejte

int listen(int sockfd, int backlog);>

Uvádí serverový soket do pasivního režimu, kde čeká, až se klient přiblíží k serveru a naváže spojení. Nevyřízené položky definuje maximální délku, na kterou může narůst fronta čekajících připojení pro sockfd. Pokud požadavek na připojení dorazí, když je fronta plná, může klient obdržet chybu s označením ECONNREFUSED.

5. Přijměte

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

Extrahuje první požadavek na připojení z fronty čekajících připojení pro naslouchající soket, sockfd, vytvoří nový připojený soket a vrátí nový deskriptor souboru odkazující na tento soket. V tomto okamžiku je navázáno spojení mezi klientem a serverem a jsou připraveni k přenosu dat.

Fáze pro klienta

1. Zásuvkové připojení: Přesně stejné jako při vytváření soketu serveru

2. Připojte: Systémové volání connect() připojí soket, na který odkazuje deskriptor souboru sockfd, na adresu zadanou addr. Adresa a port serveru jsou uvedeny v addr.

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

Implementace

Zde si vyměňujeme jednu pozdravnou zprávu mezi serverem a klientem, abychom demonstrovali model klient/server.

C Program pro vytvoření serveru

Server.c

C


převod z řetězce na int v jazyce Java



// 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 pro vytvoření 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;> }>

>

gimp jak zrušit výběr

>

Výstup

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

Kompilace

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

Další: Programování soketů v C/C++: Obsluha více klientů na serveru bez více vláken