TCP-palvelin
Hyväksy yhteyksiä.
TCP-palvelin on ilmainen C Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu C Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C Academy-kurssilla on yhteensä 4 oppituntia.
TCP-palvelimen rakentaminen
TCP-palvelin odottaa asiakkaita ja hyväksyy niiden yhteydet. Elinkaari on seuraava: luodaan socket, sidotaan se porttiin, aloitetaan kuuntelu ja hyväksytään yhteyksiä silmukassa.
Vaihe 1: Luo socket
Luokaa IPv4-TCP:tä varten stream-tyyppinen socket. Negatiivinen tulos tarkoittaa virhettä.
#include <sys/socket.h>
#include <stdio.h>
int make_server_socket(void) {
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) { perror("socket"); }
return fd;
}Vaihe 2: Salli osoitteen uudelleenkäyttö
Oletusarvoisesti portti jää palvelimen pysäyttämisen jälkeen TIME_WAIT-tilaan, mikä estää uudelleenkäynnistyksen. Asettakaa SO_REUSEADDR funktion setsockopt avulla, jotta voitte sitoa portin uudelleen heti.
#include <sys/socket.h>
void allow_reuse(int fd) {
int yes = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
}Vaihe 3: Sido socket porttiin
bind() liittää socketin paikalliseen osoitteeseen ja porttiin. INADDR_ANY kuuntelee kaikissa verkkoliitännöissä.
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
int bind_port(int fd, unsigned short port) {
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port);
if (bind(fd, (struct sockaddr *)&addr, sizeof addr) < 0) {
perror("bind"); return -1;
}
return 0;
}Vaihe 4: Aloita kuuntelu
listen() merkitsee socketin passiiviseksi eli valmiiksi hyväksymään yhteyksiä. backlog-argumentti määrittää, kuinka monta odottavaa yhteyttä ydin voi jonottaa.
#include <sys/socket.h>
#include <stdio.h>
int start_listen(int fd) {
if (listen(fd, 16) < 0) { /* backlog of 16 */
perror("listen"); return -1;
}
return 0;
}Vaihe 5: Hyväksy yhteydet
accept() estää suorituksen, kunnes asiakas yhdistää, ja palauttaa sitten uuden socketin kyseistä asiakasta varten. Alkuperäinen socket jatkaa kuuntelua.
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
int accept_one(int listen_fd) {
struct sockaddr_in cli;
socklen_t len = sizeof cli;
int conn = accept(listen_fd, (struct sockaddr *)&cli, &len);
if (conn < 0) perror("accept");
return conn;
}Kaksi socketia, kaksi roolia
accept-kutsun jälkeen käytettävissä on kaksi socketia:
- Kuunteleva socket hyväksyy uusia asiakkaita
- Yhteyssocket viestii yhden tietyn asiakkaan kanssa
Sulkeakaa yhteyssocket, kun kyseisen asiakkaan käsittely on valmis.
Pyynnön lukeminen
Käyttäkää funktiota recv lukeaksenne asiakkaan tiedot puskuriin. Paluuarvo 0 tarkoittaa, että asiakas katkaisi yhteyden; -1 tarkoittaa virhettä.
#include <sys/socket.h>
#include <stdio.h>
void handle(int conn) {
char buf[256];
ssize_t n = recv(conn, buf, sizeof buf - 1, 0);
if (n > 0) { buf[n] = 0; printf("got: %s\n", buf); }
}Vastauksen lähettäminen
Vastatkaa funktiolla send. Suurten tietomäärien tapauksessa lähettäkää kaikki tavut silmukassa, koska yksi kutsu voi kirjoittaa vain osan puskurista.
#include <sys/socket.h>
#include <string.h>
void reply(int conn) {
const char *msg = "hello from server\n";
size_t left = strlen(msg);
const char *p = msg;
while (left > 0) {
ssize_t n = send(conn, p, left, 0);
if (n <= 0) break;
p += n; left -= (size_t)n;
}
}Hyväksymissilmukka
Yksinkertainen iteratiivinen palvelin hyväksyy yhden asiakkaan, palvelee sitä, sulkee yhteyden ja palaa sitten silmukan alkuun hyväksymään seuraavan. Se käsittelee asiakkaita yksi kerrallaan.
#include <unistd.h>
void serve_loop(int listen_fd, int (*accept_one)(int), void (*handle)(int)) {
for (;;) {
int conn = accept_one(listen_fd);
if (conn < 0) continue;
handle(conn);
close(conn); /* done with this client */
}
}Hallittu sammutus
Sulkeakaa kuunteleva socket palvelimen pysähtyessä ja käsitelkää SIGINT, jotta silmukasta voidaan poistua hallitusti. Sulkekaa aina kuvaajat ytimen resurssien vapauttamiseksi.
Pikatarkistus
Testatkaa, miten hyvin ymmärrätte TCP-palvelimia.
Kertaus
Rakensitte TCP-palvelimen vaihe vaiheelta.
- socket, sitten SO_REUSEADDR, sitten bind, listen ja accept
acceptpalauttaa uuden asiakaskohtaisen socketin- Viestikää funktioilla recv/send ja sulkekaa yhteys sen jälkeen
- Käsitelkää asiakkaat silmukassa ja tarkistakaa jokainen paluuarvo
Opi C tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 39
- Oppitunnit
- 144
Usein kysytyt kysymykset
Onko oppitunti ”TCP-palvelin” ilmainen?
Kyllä – oppitunnin ”TCP-palvelin” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko C Academy-kurssin, päivitä CoddyKit PROhon. C Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”TCP-palvelin”?
Hyväksy yhteyksiä. Harjoittelet C Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni C Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin C Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.
Kuinka kauan ”TCP-palvelin”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä C Academy-oppitunnilla?
Kyllä. Jokainen C Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.