यूनिक्स सॉकेट - सर्वर उदाहरण

एक टीसीपी सर्वर को प्रोसेस करने के लिए, आपको नीचे दिए गए चरणों का पालन करना होगा -

  • सॉकेट () सिस्टम कॉल के साथ एक सॉकेट बनाएं ।

  • बाइंड () सिस्टम कॉल का उपयोग करके सॉकेट को एक पते पर बांधें । इंटरनेट पर एक सर्वर सॉकेट के लिए, एक पता होस्ट मशीन पर एक पोर्ट नंबर होता है।

  • सुनो () सिस्टम कॉल के साथ कनेक्शन के लिए सुनो

  • कनेक्शन () सिस्टम कॉल के साथ कनेक्शन स्वीकार करें। यह कॉल आम तौर पर तब तक ब्लॉक होती है जब तक कोई क्लाइंट सर्वर से कनेक्ट नहीं होता है।

  • रीड () और राइट () सिस्टम कॉल का उपयोग करके डेटा भेजें और प्राप्त करें ।

अब हम इन चरणों को स्रोत कोड के रूप में रखते हैं। इस कोड को फ़ाइल server.c में डालें और इसे gcc कंपाइलर के साथ संकलित करें ।

#include <stdio.h>
#include <stdlib.h>

#include <netdb.h>
#include <netinet/in.h>

#include <string.h>

int main( int argc, char *argv[] ) {
   int sockfd, newsockfd, portno, clilen;
   char buffer[256];
   struct sockaddr_in serv_addr, cli_addr;
   int  n;
   
   /* First call to socket() function */
   sockfd = socket(AF_INET, SOCK_STREAM, 0);
   
   if (sockfd < 0) {
      perror("ERROR opening socket");
      exit(1);
   }
   
   /* Initialize socket structure */
   bzero((char *) &serv_addr, sizeof(serv_addr));
   portno = 5001;
   
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_addr.s_addr = INADDR_ANY;
   serv_addr.sin_port = htons(portno);
   
   /* Now bind the host address using bind() call.*/
   if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
      perror("ERROR on binding");
      exit(1);
   }
      
   /* Now start listening for the clients, here process will
      * go in sleep mode and will wait for the incoming connection
   */
   
   listen(sockfd,5);
   clilen = sizeof(cli_addr);
   
   /* Accept actual connection from the client */
   newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
	
   if (newsockfd < 0) {
      perror("ERROR on accept");
      exit(1);
   }
   
   /* If connection is established then start communicating */
   bzero(buffer,256);
   n = read( newsockfd,buffer,255 );
   
   if (n < 0) {
      perror("ERROR reading from socket");
      exit(1);
   }
   
   printf("Here is the message: %s\n",buffer);
   
   /* Write a response to the client */
   n = write(newsockfd,"I got your message",18);
   
   if (n < 0) {
      perror("ERROR writing to socket");
      exit(1);
   }
      
   return 0;
}

एकाधिक कनेक्शन संभालें

सर्वर को एक साथ कई कनेक्शनों को संभालने की अनुमति देने के लिए, हम उपरोक्त कोड में निम्नलिखित बदलाव करते हैं -

  • रखो स्वीकार अनंत लूप में बयान और निम्नलिखित कोड।

  • एक कनेक्शन स्थापित होने के बाद, एक नई प्रक्रिया बनाने के लिए कांटा () को कॉल करें ।

  • चाइल्ड प्रोसेस, सॉक्सड को बंद कर देगा और डोप्रोसेसिंग फ़ंक्शन को कॉल करेगा , नए सॉकेट फ़ाइल डिस्क्रिप्टर को एक तर्क के रूप में पास करेगा । जब दो प्रक्रियाओं ने अपनी बातचीत पूरी कर ली है, जैसा कि डॉप्रोसेसिंग () लौटने से संकेत मिलता है , यह प्रक्रिया बस बाहर निकल जाती है।

  • मूल प्रक्रिया newsockfd को बंद कर देती है । जैसा कि यह सभी कोड एक अनंत लूप में है, यह अगले कनेक्शन के लिए प्रतीक्षा करने के लिए स्वीकार किए जाते हैं।

#include <stdio.h>
#include <stdlib.h>

#include <netdb.h>
#include <netinet/in.h>

#include <string.h>

void doprocessing (int sock);

int main( int argc, char *argv[] ) {
   int sockfd, newsockfd, portno, clilen;
   char buffer[256];
   struct sockaddr_in serv_addr, cli_addr;
   int n, pid;
   
   /* First call to socket() function */
   sockfd = socket(AF_INET, SOCK_STREAM, 0);
   
   if (sockfd < 0) {
      perror("ERROR opening socket");
      exit(1);
   }
   
   /* Initialize socket structure */
   bzero((char *) &serv_addr, sizeof(serv_addr));
   portno = 5001;
   
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_addr.s_addr = INADDR_ANY;
   serv_addr.sin_port = htons(portno);
   
   /* Now bind the host address using bind() call.*/
   if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
      perror("ERROR on binding");
      exit(1);
   }
   
   /* Now start listening for the clients, here
      * process will go in sleep mode and will wait
      * for the incoming connection
   */
   
   listen(sockfd,5);
   clilen = sizeof(cli_addr);
   
   while (1) {
      newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
		
      if (newsockfd < 0) {
         perror("ERROR on accept");
         exit(1);
      }
      
      /* Create child process */
      pid = fork();
		
      if (pid < 0) {
         perror("ERROR on fork");
         exit(1);
      }
      
      if (pid == 0) {
         /* This is the client process */
         close(sockfd);
         doprocessing(newsockfd);
         exit(0);
      }
      else {
         close(newsockfd);
      }
		
   } /* end of while */
}

निम्नलिखित कोड seqment doprocessing फ़ंक्शन का एक सरल कार्यान्वयन दिखाता है।

void doprocessing (int sock) {
   int n;
   char buffer[256];
   bzero(buffer,256);
   n = read(sock,buffer,255);
   
   if (n < 0) {
      perror("ERROR reading from socket");
      exit(1);
   }
   
   printf("Here is the message: %s\n",buffer);
   n = write(sock,"I got your message",18);
   
   if (n < 0) {
      perror("ERROR writing to socket");
      exit(1);
   }
	
}