Onion Information
Programiranje mrežnih aplikacija u programskim jezicima C i C++ - GASERI
BSD sockets, poznati i kao "Berkeley sockets" i kao "Unix sockets", su de facto standardno sučelje za međuprocesnu komunikaciju lokalno i preko računalne mreže. Oni koriste klijent-poslužitelj model komunikacije
Onion Details
Page Clicks: 1
First Seen: 03/15/2024
Last Indexed: 10/23/2024
Onion Content
Preskoči na sadržaj Programiranje mrežnih aplikacija u programskim jezicima C i C++ BSD sockets , poznati i kao "Berkeley sockets" i kao "Unix sockets", su de facto standardno sučelje za međuprocesnu komunikaciju lokalno i preko računalne mreže. Oni koriste klijent-poslužitelj model komunikacije. Nastaju 1983. kada Bill Joy i ekipa s UCB-a izbacuje 4.2BSD koji prvi puta uvodi mrežne utičnice, a 2008. godine preimenovani su u POSIX sockets i standardizirani; osnovne razlike između tog standarda i ranijih su u imenovanju funkcija. Prema adresiranju mogu se podijeliti na: Unix domain sockets -- AF_UNIX formalno koriste datotečni sustav kao prostor adresa (sama komunikacija ne ide preko datoteka) procesi međusobno mogu slati podatke i opisnike datoteka Unix network sockets -- AF_INET (IP verzija 4) i AF_INET6 (IP verzija 6) adresa je uređeni par oblika (ip, port) komunikacija se može vršiti lokalno ili putem Interneta Prema pouzdanosti mogu se podijeliti na: datagramski -- SOCK_DGRAM omogućuju jednosmjernu komunikaciju kod koje klijent šalje podatke, a poslužitelj prima nema mogućnosti baratanja s više klijenata, svi podaci stižu na jednu utičnicu bez obzira koji od klijenata ih šalje nema osiguranja da će poslani podaci stići tokovni -- SOCK_STREAM imaju stvarnu konekciju dvije strane, garantiraju dostavu poruka omogućuju dvosmjernu komunikaciju češće korištene Zaglavlje sys/socket.h ( dokumentacija ) nudi pristup POSIX socket sučelju pod operacijskim sustavima sličnim Unixu. Poslužiteljska strana U ovom primjeru napisat ćemo poslužiteljsku stranu mrežne aplikacije. Pored zaglavlja uobičajenih za programski jezik C koja nude često korištene pomoćne funkcije, uključujemo i sys/socket.h za baratanje socketima i netinet/in.h za baratanje internetskim adresama. #include #include #include #include #include #include Definiramo pomoćnu funkciju error() koja prima dani niz znakova i ispisuje ga na ekran kao grešku korištenjem funkcije perror() , a zatim završava izvođenje programa korištenjem funkcije exit() i argumentom različitim od 0, koji označava da program nije završio izvođenje na uobičajen način. void error ( const char * msg ) { perror ( msg ); exit ( 1 ); } Unutar funkcije main() provjerava se je li korisnik unio dovoljan broj argumenata; u slučaju da nije, program završava izvođenje. int main ( int argc , char * argv []) { if ( argc #include #include #include #include #include void error ( const char * msg ) { perror ( msg ); exit ( 1 ); } int main ( int argc , char * argv []) { if ( argc #include #include #include #include #include #include Funkcija za ispis greške ista je kao kod poslužitelja. void error ( const char * msg ) { perror ( msg ); exit ( 1 ); } Kao i kod poslužitelja, unutar funkcije main() provjerava se je li korisnik unio dovoljan broj argumenata; u slučaju da nije, program završava izvođenje. int main ( int argc , char * argv []) { if ( argc h_addr , server -> h_length ); portno = atoi ( argv [ 2 ]); serv_addr . sin_port = htons ( portno ); Povezivanje na server vrši se funkcijom connect() ; ako je rezultat koji ona vrati manji od 0, došlo je do pogreške i informacija o tome ispisuje se na ekran. if ( connect ( sockfd , ( struct sockaddr * ) & serv_addr , sizeof ( serv_addr )) #include #include #include #include #include #include void error ( const char * msg ) { perror ( msg ); exit ( 1 ); } int main ( int argc , char * argv []) { if ( argc h_addr , server -> h_length ); serv_addr . sin_port = htons ( portno ); if ( connect ( sockfd , ( struct sockaddr * ) & serv_addr , sizeof ( serv_addr )) < 0 ) error ( "ERROR connecting" ); printf ( "Please enter the message: " ); memset ( buffer , 0 , 256 ); fgets ( buffer , 255 , stdin ); n = write ( sockfd , buffer , strlen ( buffer )); if ( n < 0 ) error ( "ERROR writing to socket" ); memset ( buffer , 0 , 256 ); n = read ( sockfd , buffer , 255 ); if ( n < 0 ) error ( "ERROR reading from socket" ); printf ( "%s \n " , buffer ); close ( sockfd ); return 0 ; } Pregled korištenih funkcija Srž programa je, kronološki poredano: poslužitelj: bind() poslužitelj: listen() klijent: connect() poslužitelj: accept() klijent: write() poslužitelj: read() poslužitelj: write() klijent: read() klijent: close() poslužitelj: close() socketa koji je pripadao klijentu, close() socketa za povezivanje klijenata Prevođenje i pokretanje programa Spremite li kod programa u datoteke server.c i client.c unutar kućnog direktorija, tada u terminalu možete naredbom: $ gcc -o server.c $ gcc -o client.c izvesti prevođenje oba programa. Zatim ćemo pokrenuti poslužitelj i klijent u dva odvojena terminala i pritom odabrati TCP vrata preko kojih će komunicirati (u našem primjeru 5000). U prvom terminalu pokrećemo poslužitelj naredbom: $ ./server 5000 U drugom terminalu pokrećemo klijent naredbom: $ ./client localhost 5000 Umjesto vrata 5000 možete koristiti bilo koja u rasponu 1024--65535 dostupna običnim korisnicima; vrata 0--1023 može otvoriti samo korisnik root . Author: Vedran Miletić