logo

Sockelprogrammering i C

Vad är Socket Programmering?

Socketprogrammering är ett sätt att koppla ihop två noder i ett nätverk för att kommunicera med varandra. En socket(nod) lyssnar på en viss port vid en IP, medan den andra socket når ut till den andra för att skapa en anslutning. Servern bildar lyssnarsocket medan klienten når ut till servern.

Statusdiagram för server- och klientmodell

Tillståndsdiagram för server- och klientmodell av Socket

Stadier för server

Servern skapas med följande steg:



applet applet

1. Skapande av uttag

int sockfd = socket(domain, type, protocol)>
    sockfd: socket descriptor, ett heltal (som ett filhandtag) domän: heltal, anger kommunikationsdomän. Vi använder AF_ LOCAL enligt definitionen i POSIX-standarden för kommunikation mellan processer på samma värd. För att kommunicera mellan processer på olika värdar anslutna med IPV4 använder vi AF_INET och AF_I NET 6 för processer anslutna med IPV6. typ: kommunikationstyp
    SOCK_STREAM: TCP (pålitlig, anslutningsorienterad)
    SOCK_DGRAM: UDP(otillförlitligt, anslutningslöst) protokoll: Protokollvärde för Internet Protocol(IP), vilket är 0. Detta är samma nummer som visas i protokollfältet i IP-huvudet på ett paket.(man-protokoll för mer information)

2. Setsockopt

Detta hjälper till att manipulera alternativ för socket som hänvisas till av filbeskrivningen sockfd. Detta är helt valfritt, men det hjälper till vid återanvändning av adress och port. Förhindrar fel som: adress som redan används.

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

3. Bind

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

Efter skapandet av socket binder bindningsfunktionen socket till adressen och portnumret som anges i addr(anpassad datastruktur). I exempelkoden binder vi servern till den lokala värden, därför använder vi INADDR_ANY för att ange IP-adressen.

4. Lyssna

int listen(int sockfd, int backlog);>

Den sätter serversocket i ett passivt läge, där den väntar på att klienten ska närma sig servern för att göra en anslutning. Eftersläpningen definierar den maximala längden till vilken kön av väntande anslutningar för sockfd kan växa. Om en anslutningsförfrågan kommer när kön är full kan klienten få ett felmeddelande med indikationen ECONNREFUSED.

5. Acceptera

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

Den extraherar den första anslutningsbegäran i kön av väntande anslutningar för lyssningssocket, sockfd, skapar en ny ansluten socket och returnerar en ny filbeskrivning som hänvisar till den socket. Vid denna tidpunkt upprättas anslutningen mellan klient och server, och de är redo att överföra data.

Stadier för klient

1. Uttagsanslutning: Exakt samma som när serverns socket skapades

2. Anslut: Systemanropet connect() ansluter socket som refereras till av filbeskrivningen sockfd till adressen som anges av addr. Serverns adress och port anges i adr.

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

Genomförande

Här utbyter vi ett hej-meddelande mellan server och klient för att demonstrera klient/server-modellen.

C Program för att skapa server

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

>

inte
>

C Program för att skapa klient

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

>

>

Produktion

tiger jämfört med lejon
Client:Hello message sent Hello from server Server:Hello from client Hello message sent>

Sammanställning

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

Nästa: Socketprogrammering i C/C++: Hanterar flera klienter på servern utan multitrådning