Unix Socket - 服务器端举例

要使进程成为TCP服务器,您需要遵循下面给出的步骤

        - 使用socket()系统调用创建一个套接字。

        - 使用Bind()系统调用将套接字绑定到一个地址。对于Internet上的服务器套接字,地址由主机上的端口号组成。

        - 监听与Listen()系统调用的连接。

        - 使用read()和write()系统调用发送和接收数据。

现在让我们将这些步骤以源代码的形式呈现出来。将这段代码放到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;

}

处理多个连接

为了允许服务器同时处理多个连接,我们在上面的代码中做了以下更改:

        - 将accept语句和下面的代码放入一个无限循环中。

        - 连接建立后,调用fork()创建一个新进程。

        - 子进程将关闭sockfd并调用doprocessing函数,将新的套接字文件描述符作为参数传递。当两个进程完成它们的对话时,如doprocessing()返回所示,这个进程就会退出。

        - 父进程关闭newsockfd。由于所有这些代码都处于无限循环中,它将返回到accept语句以等待下一个连接。

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <netdb.h>

#include <netinet/in.h>

#include <string.h>

void doprocessing (int sock);

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

   }


}

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 */

}

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容