logo

Socketprogrammering in C

Wat is Socket-programmering?

Socketprogrammering is een manier om twee knooppunten in een netwerk met elkaar te verbinden en met elkaar te communiceren. Eén socket(node) luistert op een bepaalde poort op een IP, terwijl de andere socket contact maakt met de andere om een ​​verbinding te vormen. De server vormt de luisteraarsocket terwijl de client contact opneemt met de server.

Toestandsdiagram voor server- en clientmodel

Toestandsdiagram voor server- en clientmodel van Socket

Fasen voor Server

De server wordt gemaakt met behulp van de volgende stappen:



converteer een string naar een datum

1. Socketcreatie

int sockfd = socket(domain, type, protocol)>
    sockfd: socketdescriptor, een geheel getal (zoals een bestandshandle) domein: geheel getal, specificeert het communicatiedomein. We gebruiken AF_LOCAL zoals gedefinieerd in de POSIX-standaard voor communicatie tussen processen op dezelfde host. Voor de communicatie tussen processen op verschillende hosts die zijn verbonden via IPV4, gebruiken we AF_INET en AF_I NET 6 voor processen die zijn verbonden via IPV6. type: communicatietype
    SOCK_STREAM: TCP (betrouwbaar, verbindingsgericht)
    SOCK_DGRAM: UDP (onbetrouwbaar, verbindingsloos) protocol: Protocolwaarde voor Internet Protocol (IP), die 0 is. Dit is hetzelfde nummer dat verschijnt in het protocolveld in de IP-header van een pakket. (man-protocollen voor meer details)

2. Stel stockopt in

Dit helpt bij het manipuleren van opties voor de socket waarnaar wordt verwezen door de bestandsdescriptor sockfd. Dit is volledig optioneel, maar het helpt bij het hergebruik van adres en poort. Voorkomt fouten zoals: adres al in gebruik.

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

3. Binden

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

Na het aanmaken van de socket bindt de bindfunctie de socket aan het adres en poortnummer gespecificeerd in addr (aangepaste datastructuur). In de voorbeeldcode binden we de server aan de localhost, daarom gebruiken we INADDR_ANY om het IP-adres op te geven.

4. Luister

int listen(int sockfd, int backlog);>

Het zet de server socket in een passieve modus, waarbij het wacht tot de client de server benadert om een ​​verbinding tot stand te brengen. De backlog definieert de maximale lengte waartoe de wachtrij van in behandeling zijnde verbindingen voor sockfd mag groeien. Als er een verbindingsverzoek binnenkomt terwijl de wachtrij vol is, kan de client een foutmelding krijgen met de indicatie ECONNREFUSED.

5. Accepteer

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

Het extraheert het eerste verbindingsverzoek uit de wachtrij met in behandeling zijnde verbindingen voor de luisterende socket, sockfd, creëert een nieuwe verbonden socket en retourneert een nieuwe bestandsdescriptor die naar die socket verwijst. Op dit punt is de verbinding tussen client en server tot stand gebracht en zijn ze klaar om gegevens over te dragen.

Fasen voor klant

1. Stopcontactaansluiting: Precies hetzelfde als dat van het maken van de socket van de server

2. Verbinden: De systeemaanroep connect() verbindt de socket waarnaar wordt verwezen door de bestandsdescriptor sockfd met het adres dat is opgegeven door addr. Het adres en de poort van de server worden gespecificeerd in addr.

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

Implementatie

Hier wisselen we een hallo-bericht uit tussen server en client om het client/server-model te demonstreren.

C Programma om server te maken

Server.c

C




Java while-lus
// 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-programma om client te maken

klant.c

C


tekenreeks n java



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

>

>

Uitvoer

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

Compileren

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

Volgende: Socketprogrammering in C/C++: meerdere clients op de server verwerken zonder multi-threading