c - Linux C 套接字 - 保持服务器处于事件状态

标签 c linux

我正在使用 C 语言通过 Linux 套接字实现一个简单的客户端-服务器检索系统。我现在已经成功连接远程服务器,但是当我关闭连接时,服务器宕机了,即服务器程序停止了。 我应该怎样做才能避免这种情况?

这是我的代码示例:

服务器:

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>

int main(void)
{
   int optval;
   socklen_t optlen = sizeof(optval);

   char str[100] = "";
   int listen_fd, conn_fd;
   struct sockaddr_in servaddr;

   listen_fd = socket(AF_INET, SOCK_STREAM, 0);

   // check if on
   getsockopt(listen_fd, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen);
   printf("keep alive is %s\n", (optval? "ON" : "OFF"));

   // set it on
   optval = 1;
   optlen = sizeof(optval);
   setsockopt(listen_fd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen);
   printf("done, check again.\n");

   printf("keep alive is %s\n", (optval? "ON" : "OFF"));

   bzero( &servaddr, sizeof(servaddr));

   // set appropriate protocol and port number (15792)
   // the htons() function converts the unsigned short integer
   // from host byte order to network byte order.
   servaddr.sin_family = AF_INET;
   servaddr.sin_addr.s_addr = htons(INADDR_ANY);
   servaddr.sin_port = htons(15792);

   // Bind a name to a socket
   bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));

   // listening for incoming connection
   listen(listen_fd, 10);

   // accept a connection on a socket
   conn_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL);

   do
   {

      // set str to null
      bzero(str, 100);


      // Read from a file descriptor (linux all)
      read(conn_fd,str,100);

      // print the received message
      // printf("Received: %s\n",str);

      if (!strcmp(str, "GET TIME\n"))
      {
         bzero(str, 100);

         time_t clocks;
         clocks = time(NULL);
         sprintf(str, "%s", ctime(&clocks));
         write(conn_fd, str, strlen(str));
         //close(conn_fd);
      }
      else
      {
         bzero(str, 100);
         strcpy(str, "ERROR: No such command.\n");
         write(conn_fd, str, strlen(str));
         //close(conn_fd);
      }
   } while (1);
}

客户:

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc,char **argv)
{
   // declare necessary variables
   int sockfd;
   char recv[1024] = "";
   char command[100] = "";
   struct sockaddr_in servaddr;

   if (argc != 2)
   {
      printf("usage: %s <ip address>\n", argv[0]);
      exit(EXIT_FAILURE);
   }


      // create a socket with the appropriate protocol
      if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
      {
         printf("ERROR: Failed create cosket.\n");
         exit(EXIT_FAILURE);
      }

      // Set all the socket structures with null values.
      bzero(&servaddr, sizeof servaddr);

      // set appropriate protocol and port number (1999)
      // The htons() function converts the unsigned short integer 
      // hostshort from host byte order to network byte order.
      servaddr.sin_family = AF_INET;
      servaddr.sin_port = htons(15792);

      // Convert IPv4 and IPv6 addresses from text to binary form
      if (inet_pton(AF_INET, argv[1], &(servaddr.sin_addr)) <= 0)
      {
         printf("ERROR: Wrong ip address.\n");
         exit(EXIT_FAILURE);
      }

      // attempt to connect to a socket
      if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
      {
         printf("ERROR: Failed at connect.\n");
         exit(EXIT_FAILURE);
      }
      else
      {
         printf("------ connect successfull ------\n");
      }

   do
   {

      printf("> ");
      fgets(command, 100, stdin);
      write(sockfd, command, strlen(command));

      if (!strcmp(command, "QUIT\n"))
      {
         close(sockfd);
         break;
      }

      // print the receive stuff
      read(sockfd, recv, sizeof(recv));
      fputs(recv, stdout);
      bzero(recv, 1024);

   } while (1);
}

最佳答案

在服务器代码中,必须在 do-while 循环中调用 accept() 函数:

// listening for incoming connection
listen(listen_fd, 10);

do
{ 
    // accept a connection on a socket
    conn_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL);

    ...

    close(conn_fd);
} while(1);

关于c - Linux C 套接字 - 保持服务器处于事件状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34150492/

相关文章:

将 2 字节十六进制数转换回十进制

c++ - dlopen() 返回 0

linux - Node 和 NPM linux 二进制安装

c - 当数据到达时从 FIFO 读取数据 (linux)

c - 释放字符指针数组(字符串文字)?

java - C 代码到 Java——字符操作

c - 我使用埃拉托色尼筛作为素性测试。为什么我得到 2297 是复合数?

C:指针数组与指针到指针

linux - 缺少推荐库 : libGLU. 所以

json - 如何使用 blueprint.json 文件重新配置 Ambari 服务值