logo

Sockelprogrammering i C

Programmering av uttag är ett sätt att koppla samman 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 bilda en anslutning. Servern bildar lyssnarsocket medan klienten når ut till servern.
Socket-programmering används ofta i snabbmeddelandeapplikationer binär streaming och dokumentsamarbete online streaming-plattformar etc.

Exempel

I detta C-program utbyter vi ett hej-meddelande mellan server och klient för att demonstrera klient/server-modellen.

server.c

C
#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);  }    // subtract 1 for the null  // terminator at the end  valread = read(new_socket buffer  1024 - 1);   printf('%sn' buffer);  send(new_socket hello strlen(hello) 0);  printf('Hello message sentn');  // closing the connected socket  close(new_socket);    // closing the listening socket  close(server_fd);  return 0; } 

klient.c

C
#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('n Socket creation error n');  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(  'nInvalid address/ Address not supported n');  return -1;  }  if ((status  = connect(client_fd (struct sockaddr*)&serv_addr  sizeof(serv_addr)))  < 0) {  printf('nConnection Failed n');  return -1;  }    // subtract 1 for the null  // terminator at the end  send(client_fd hello strlen(hello) 0);  printf('Hello message sentn');  valread = read(client_fd buffer  1024 - 1);   printf('%sn' buffer);  // closing the connected socket  close(client_fd);  return 0; } 


Sammanställning



gcc client.c -o clientgcc server.c -o server


Produktion

Client:Hello message sentHello from serverServer:Hello from clientHello message sent

Komponenter i Socket Programmering

1. Uttag

Uttag är en av kärnkomponenterna som används av programmet för att komma åt nätverket för att kommunicera med andra processer/noder över nätverket. Det är helt enkelt en kombination av en IP-adress och ett portnummer som fungerar som en slutpunkt för kommunikation.
Exempel: 192.168.1.1:8080 där de två delarna separerade av kolon representerar IP-adress ( 192.168.1.1 ) och den portnummer (8080).

Sockeltyper:

  • TCP Socket (Stream Socket): Ger pålitlig anslutningsbaserad kommunikation (dvs. TCP-protokoll ).
  • UDP Socket (Datagram Socket): Ger anslutningslös kommunikation snabbare men opålitlig (dvs. UDP-protokoll ).

2. Klient-servermodell

De klient-server-modell hänvisar till den arkitektur som används i socketprogrammering där en klient och en server interagerar med varandra för att utbyta information eller tjänster. Denna arkitektur tillåter klienten att skicka serviceförfrågningar och servern att bearbeta och skicka svar på dessa serviceförfrågningar.

Statusdiagram för server- och klientmodell

Sockelprogrammering i CTillståndsdiagram för server- och klientmodell av Socket

Socketprogrammering i C är ett kraftfullt sätt att hantera nätverkskommunikation.

Skapa en process på serversidan

Servern skapas med följande steg:

java sträng till char

1. Skapande av uttag

Det här steget innebär att socketen skapas med funktionen socket().

Parametrar:

  • 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 (tillförlitlig anslutningsorienterad)
    SOCK_DGRAM: UDP (otillförlitlig anslutningslös)
  • protokoll: Protokollvärde för Internet Protocol(IP) som är 0. Detta är samma nummer som visas i protokollfältet i IP-huvudet på ett paket.(man-protokoll för mer information)
C
sockfd = socket(domain type protocol) 

2. Ställ in socket opt

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.

C
setsockopt(sockfd level optname optval socklen_t optlen); 

3. Bind

Efter skapandet av socket binder bind()-funktionen 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 specificera IP-adressen.

C++
bind(sockfd sockaddr *addr socklen_t addrlen); 

Parametrar:

  • sockfd : socket-filbeskrivning skapad med socket()-funktionen.
  • adr : pekare till en struct sockaddr som innehåller IP-adressen och portnumret för att binda sockeln.
  • addrlen : längden på addr-strukturen.

4. Lyssna

I detta steg använder servern funktionen listen() som 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. Backloggen 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.

C
listen(sockfd backlog); 

Parametrar :

  • sockfd : socket-filbeskrivning skapad med socket()-funktionen.
  • orderstock : nummer som representerar storleken på den kö som håller de väntande anslutningarna medan servern väntar på att acceptera en anslutning.

5. Acceptera

I det här steget extraherar servern den första anslutningsbegäran från kön av väntande anslutningar för den lyssnande socket sockfd skapar en ny ansluten socket med hjälp av acceptera() funktion 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.

C
new_socket= accept(sockfd sockaddr *addr socklen_t *addrlen); 

Parametrar:

  • sockfd : socketfilbeskrivning returneras av socket() och bind().
  • adr : pekare till en struct sockaddr som kommer att hålla klientens IP-adress och portnummer.
  • addrlen : pekare till en variabel som anger längden på adressstrukturen.

6. Skicka/ta emot

I detta steg kan servern skicka eller ta emot data från klienten.

Skicka(): att skicka data till klienten

C
send(sockfd *buf len flags); 

Parametrar:

  • sockfd : socket-filbeskrivning som returneras av socket()-funktionen.
  • buff : pekare till bufferten som innehåller data som ska skickas.
  • endast : antal byte data som ska skickas.
  • flaggor : heltal som anger olika alternativ för hur data skickas, vanligtvis används 0 för standardbeteende.

Receive() : för att ta emot data från klienten.

C
recv( sockfd *buf len flags); 

Parametrar:

  • sockfd : socket-filbeskrivning som returneras av socket()-funktionen.
  • buff : pekare till bufferten som innehåller data som ska lagras.
  • endast : antal byte data som ska skickas.
  • flaggor : heltal som anger olika alternativ för hur data skickas, vanligtvis används 0 för standardbeteende.

6. Stäng

Efter att informationsutbytet är klart stänger servern socket med funktionen close() och släpper systemresurserna.

C
close(fd); 

Parametrar:

  • fd: filbeskrivning för socket.

Skapa process på klientsidan

Följ stegen nedan för att skapa en process på klientsidan:

1. Uttagsanslutning

Detta steg involverar skapandet av socket, vilket görs på samma sätt som serverns socketskapande

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.

C++
connect(sockfd sockaddr *addr socklen_t addrlen); 

Parametrar

  • sockfd : socket-filbeskrivning som returneras av socket()-funktionen.
  • adr : pekare till struct sockaddr som innehåller serverns IP-adress och portnummer.
  • addrlen : storlek på adress.

3. Skicka/ta emot

I detta steg kan klienten skicka eller ta emot data från servern vilket görs med funktionerna send() och recieve() som liknar hur servern skickar/tar emot data från klienten.

4. Stäng

När informationsutbytet är klart måste klienten också stänga den skapade socket och släpper systemresurserna med funktionen close() på samma sätt som servern gör.

Vanliga problem och deras korrigeringar i socketprogrammering

  • Anslutningsfel: För att undvika anslutningsfel bör vi se till att klienten försöker ansluta till rätt IP-adress och port .
  • Portbindningsfel: Dessa fel uppstår när en port redan används av ett annat program i detta scenario kommer bindningen till den porten att misslyckas. Försök att använda en annan port eller stäng det tidigare programmet med porten.
  • Blockerande uttag: Som standard blockerar uttagen. Det betyder att anrop som accept() eller recv() kommer att vänta på obestämd tid om det inte finns någon klientanslutning eller data. Du kan ställa in uttaget till icke-blockerande läge om det behövs.
Skapa frågesport