logo

Socket programavimas C

Kas yra Socket programavimas?

Lizdų programavimas yra būdas sujungti du tinklo mazgus, kad būtų galima bendrauti tarpusavyje. Vienas lizdas (mazgas) klausosi tam tikro IP prievado, o kitas lizdas pasiekia kitą, kad sukurtų ryšį. Serveris sudaro klausytojo lizdą, o klientas pasiekia serverį.

Serverio ir kliento modelio būsenos diagrama

Socket serverio ir kliento modelio būsenos diagrama



Serverio etapai

Serveris sukuriamas atliekant šiuos veiksmus:

oi java

1. Lizdų kūrimas

int sockfd = socket(domain, type, protocol)>
    sockfd: lizdo deskriptorius, sveikasis skaičius (kaip failo rankena) domenas: sveikasis skaičius, nurodo ryšio domeną. Mes naudojame AF_ LOCAL, kaip apibrėžta POSIX standarte, ryšiui tarp procesų tame pačiame pagrindiniame kompiuteryje. Norėdami susisiekti tarp procesų skirtinguose pagrindiniuose kompiuteriuose, sujungtuose IPV4, naudojame AF_INET ir AF_I NET 6 procesams, sujungtiems IPV6. tipas: komunikacijos tipas
    SOCK_STREAM: TCP (patikimas, orientuotas į ryšį)
    SOCK_DGRAM: UDP (nepatikimas, be ryšio) protokolas: interneto protokolo (IP) protokolo reikšmė, kuri yra 0. Tai yra tas pats skaičius, kuris rodomas paketo IP antraštės protokolo lauke. (daugiau informacijos rasite žmogaus protokoluose)

2. Setsockopt

Tai padeda manipuliuoti lizdo parinktimis, nurodytomis failo deskriptoriumi sockfd. Tai visiškai neprivaloma, tačiau tai padeda pakartotinai naudoti adresą ir prievadą. Apsaugo nuo klaidų, tokių kaip: adresas jau naudojamas.

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

3. Surišti

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

Sukūrus lizdą, susiejimo funkcija suriša lizdą su adresu ir prievado numeriu, nurodytu addr (custom data structure). Kode pavyzdyje mes susiejame serverį su vietiniu kompiuteriu, todėl IP adresui nurodyti naudojame INADDR_ANY.



4. Klausyk

int listen(int sockfd, int backlog);>

Jis įjungia serverio lizdą pasyviuoju režimu, kuriame laukia, kol klientas priartės prie serverio ir užmegs ryšį. Atsilikimas apibrėžia maksimalų ilgį, iki kurio gali padidėti laukiančių „sockfd“ jungčių eilė. Jei prisijungimo užklausa gaunama, kai eilė yra pilna, klientas gali gauti klaidą su nuoroda ECONNREFUSED.

5. Priimk

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

Jis ištraukia pirmąją prisijungimo užklausą laukiančių jungčių eilėje klausymosi lizdui sockfd, sukuria naują prijungtą lizdą ir grąžina naują failo aprašą, nurodantį tą lizdą. Šiuo metu tarp kliento ir serverio užmezgamas ryšys ir jie yra pasirengę perduoti duomenis.

Kliento etapai

1. Kištukinio lizdo jungtis: Lygiai taip pat, kaip ir kuriant serverio lizdą



2. Prisijunkite: Connect() sistemos iškvietimas sujungia failo deskriptoriaus sockfd nurodytą lizdą su adresu, nurodytu adresu addr. Serverio adresas ir prievadas nurodyti adr.

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

Įgyvendinimas

Čia mes keičiamės vienu sveikinimo pranešimu tarp serverio ir kliento, kad parodytume kliento / serverio modelį.

C Serverio kūrimo programa

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

>

instanceof java
>

C Kliento kūrimo programa

klientas.c

C




java prioritetų eilė
// 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;> }>

>

>

Išvestis

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

Kompiliavimas

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

Kitas: Socket programavimas C/C++: kelių klientų tvarkymas serveryje be kelių gijų