如何将我的服务器作为守护程序进程运行?

时间:2011-08-14 19:17:59

标签: c sockets daemon infinite-loop

有几天我一直试图将我的服务器作为持续运行的守护进程运行。现在,我的服务器关闭与客户端的连接,然后自行关闭。所以我能够将我的数据包一次发送到服务器,但是当我尝试再次发送它时,我得到了一个分段错误错误。

此外,即使我编写了守护程序进程,我也不确定它的行为以及它是否正常工作。

服务器代码:

#include <sys/socket.h>
#include <netinet/in.h>
#include "unistd.h"
#include <syslog.h>
#include <math.h>
#define MAXPROFILES  2

float Pearson(int mySum, int recSum, int multSum);

int main(int argc, char *argv[])
{
    int sockfd, newsockfd, portno, clilen;
    struct sockaddr_in serv_addr, cli_addr;
    unsigned char buf[1024];
    int myDataBinary[500] = {0};
    int myDataBinary2[500] = {0};
    int recData[500] = {0};*/
    int index1=0;

    struct profile_t
    {
        unsigned char length;
        unsigned char type;
        unsigned char *data;
    };

    typedef struct profile_datagram_t
    {
       unsigned char *src;
       unsigned char *dst;
       unsigned char ver;
       unsigned char n;
       struct profile_t profiles[MAXPROFILES];
    } header;


    header outObj;
    int j =0;
    int i =0;

    extern int daemon_proc;   /* defined in error.c */

    void daemon_init (const char *pname, int facility)
    {
   /* Our process ID and Session ID */
       pid_t pid, sid;

       /* Fork off the parent process */
       pid = fork();
       if (pid < 0) {
            exit(EXIT_FAILURE);
    }

      /* If we got a good PID, then
       we can exit the parent process. */
       if (pid > 0) {
            exit(EXIT_SUCCESS);
    }

       /* Change the file mode mask */
       umask(0);

       /* Open any logs here */        

       /* Create a new SID for the child process */
       sid = setsid();
       if (sid < 0) {
            /* Log the failure */
            exit(EXIT_FAILURE);
       }

         /* Change the current working directory */
          if ((chdir("/")) < 0) {
            /* Log the failure */
            exit(EXIT_FAILURE);
       }

         /* Close out the standard file descriptors */
          close(STDIN_FILENO);
          close(STDOUT_FILENO);
          close(STDERR_FILENO);

         /* Daemon-specific initialization goes here */

      }


         if (argc < 2) {
        fprintf(stderr,"usage: %s port_number1",argv[0]);
        exit(1);
     }
          sockfd = socket(AF_INET, SOCK_STREAM, 0);
          if (sockfd < 0)
          error("ERROR DETECTED !!! Problem in opening socket");

          bzero((char *) &serv_addr, sizeof(serv_addr));
          portno = atoi(argv[1]);

          serv_addr.sin_family = AF_INET;
          serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
          serv_addr.sin_port = htons(portno);

          if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
          error("ERROR DETECTED !!! There was a problem in binding");

          listen(sockfd, 10);
          clilen = sizeof(cli_addr);

    while (1){

      printf("Server listening on port number %d...\n", serv_addr.sin_port);

      newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);

      if (newsockfd < 0)
  error("ERROR DETECTED !!! the connection request was not accepted");

  int rc = read(newsockfd,buf,100);
  if(rc < 0){
     printf("error");
 }
 else {
     printf("success %d",rc);
 }


    outObj.src = malloc(4);
    outObj.dst = malloc(4);
            // printf(pointer);
             memcpy(outObj.src,buf+0,4);
             memcpy(outObj.dst,buf+4,4);
             memcpy(&outObj.ver,buf+8,1);
             memcpy(&outObj.n,buf+9,1);

 printf("\nSource IP = ");
 for(int i=0;i<4;i++){
     printf("%d ",outObj.src[i]);
 }

 printf("\nDestination IP = ");
  for(int i=0;i<4;i++){
     printf("%d ",outObj.dst[i]);
 }

 printf("\nVersion = %d",outObj.ver);
 printf("\nNumber of messages = %d",outObj.n);

 int k = 10;

 for(i=0;i<outObj.n;i++){
            memcpy(&outObj.profiles[i].length,buf+k,1);
            memcpy(&outObj.profiles[i].type,buf+k+1,1);
            outObj.profiles[i].data = malloc(outObj.profiles[i].length);
            memcpy(outObj.profiles[i].data,buf+k+2,5);
            k +=7;
}

for(int i=0;i<outObj.n;i++){
        printf("\n------- Message %d --------",i+1);
        printf("\nLength : %d",outObj.profiles[i].length);
        printf("\nType : %d\n",outObj.profiles[i].type);
        for(int j=0;j<5;j++){
            printf(" Data[%d] : %d",j,outObj.profiles[i].data[j]);
        }
    }

      float rho;

for(int i=0;i<outObj.n;i++){
    printf("\n\n---------- Values for Data Profile %d ------------",i+1);
    index1=0;
    int sumRecievedData = 0;
    int sumMyData = 0;
    int sumMultpliedData = 0;
    int my_data[10] = {0};//  = {1,2,3,4,5};
    int myDataBinary[500] = {0};
    int recData[500] = {0};


    if(i==0){
        my_data[0] = 1;
        my_data[1] = 3;
        my_data[2] = 9;
        my_data[3] = 10;
    } else if(i==1){
        my_data[0] = 1;
        my_data[1] = 2;
        my_data[2] = 3;
        my_data[3] = 4;
        my_data[4] = 5;
    }



    for(int i=0; i<sizeof(my_data)/sizeof(int);i++)
        {
            if(my_data[i] > 0){
                index1 = my_data[i];
                myDataBinary[index1] = 1;
                //printf("my data %d = %d\n",index1,myDataBinary[index1]);
            }
    }

    for (int j=0; j<outObj.profiles[i].length;j++) {

        if(outObj.profiles[i].data[j] > 0){
            index1 = outObj.profiles[i].data[j];
            recData[index1] = 1;
            //printf("rec data %d = %d\n",index1,recData[index1]);
        }
    }

    for(int i=0;i<500;i++){
        sumRecievedData += recData[i];
        sumMyData += myDataBinary[i];
        sumMultpliedData += recData[i] * myDataBinary[i];
    }

    printf("\nrecSum = %d, \nmySum = %d, \nmultSum = %d\n",sumRecievedData,sumMyData,sumMultpliedData);

    rho = Pearson(sumMyData,sumRecievedData,sumMultpliedData);
    printf("\nPearson Coefficient for Data Profile %d= %f\n",i+1,rho);
}


return 0;
   }
    //exit(EXIT_SUCCESS);
   }


float Pearson(int mySum, int recSum, int multSum)
{
float Cov =0;
float sdMyData = 0;
float sdRecievedData =0;
float rho;
int n = 500;

Cov = (1.0/(n-1))*(multSum - (1.0/n)*mySum*recSum);
sdMyData = sqrt((1.0/(n-1))*(mySum - (1.0/n)*mySum*mySum));
sdRecievedData = sqrt((1.0/(n-1))*(recSum - (1.0/n)*recSum*recSum));
printf("\nCovariance = %f, \nVarianceMyData = %f, \nVarianceRecData = %f",Cov,sdMyData,sdRecievedData);
if (sdMyData == 0.0 || sdRecievedData == 0.0){
    rho = 0.0;
}else{
    rho = Cov/(sdMyData*sdRecievedData);
}

return(rho);
}

1 个答案:

答案 0 :(得分:1)

服务器在所谓的无限循环的底部执行return(0);,从而退出main()并终止。

如评论中所述,您的代码包含一个永远不会被调用的嵌套函数daemon_init()。嵌套函数是仅限GCC的功能;你应该避免使用它们。如果您确实调用它,服务器将会出现问题,因为它会关闭stdoutstderr,但您的代码会尝试写入已关闭的文件。

如果没有客户端代码,通过网络发送什么信息还远远不够清楚。有一个read()电话:

int rc = read(newsockfd,buf,100);

应该使用sizeof(buf)代替100;当你只使用100个字节时,使用char buf[1024];是浪费的。你检查你有一些数据;你没有检查你是否得到了你期望的所有数据。因此,您可能正在阅读未初始化的数据。

代码中还有许多其他类似的问题,特别是使用的常量有些不合适。正如评论中所指出的,代码没有正确模块化。

代码似乎没有响应客户端;其输出仅转到其标准输出(或错误)。

此代码编译得相当干净,但由于前面提到的原因,仍然不会调用daemon_init()

#include <errno.h>
#include <math.h>
#include <netinet/in.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>     /* exit() */
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>   /* umask() */
#include <syslog.h>
#include <unistd.h>

#define MAXPROFILES  2

static void error(const char *fmt, ...)
{
    va_list args;
    int errnum = errno;
    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);
    fprintf(stderr, ": %d %s\n", errnum, strerror(errnum));
    exit(1);
}

static float Pearson(int mySum, int recSum, int multSum);

static void daemon_init(void)
{
    /* Our process ID and Session ID */
    pid_t pid, sid;

    /* Fork off the parent process */
    pid = fork();
    if (pid < 0)
        error("failed to fork");

    /* If we got a good PID, then
       we can exit the parent process. */
    if (pid > 0)
        exit(EXIT_SUCCESS);

    /* Change the file mode mask */
    umask(0);

    /* Open any logs here */        

    /* Create a new SID for the child process */
    sid = setsid();
    if (sid < 0)
        error("failed to set session ID");

    /* Change the current working directory */
    if ((chdir("/")) < 0)
        error("failed to chdir to root");

    /* Close out the standard file descriptors */
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);

    /* Daemon-specific initialization goes here */
}

int main(int argc, char *argv[])
{
    int sockfd, newsockfd, portno;
    socklen_t clilen;
    struct sockaddr_in serv_addr, cli_addr;
    unsigned char buf[1024];

    struct profile_t
    {
        unsigned char length;
        unsigned char type;
        unsigned char *data;
    };

    typedef struct profile_datagram_t
    {
        unsigned char *src;
        unsigned char *dst;
        unsigned char ver;
        unsigned char n;
        struct profile_t profiles[MAXPROFILES];
    } header;

    header outObj;

    if (argc != 2)
        error("usage: %s port", argv[0]);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        error("ERROR DETECTED !!! Problem in opening socket");

    bzero((char *) &serv_addr, sizeof(serv_addr));
    portno = atoi(argv[1]);

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(portno);

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
        error("ERROR DETECTED !!! There was a problem in binding");

    listen(sockfd, 10);

    while (1)
    {
        clilen = sizeof(cli_addr);
        printf("Server listening on port number %d...\n", serv_addr.sin_port);
        newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);

        if (newsockfd < 0)
            error("ERROR DETECTED !!! the connection request was not accepted");

        int rc = read(newsockfd,buf,100);
        if (rc < 0)
            error("read error");
        else
            printf("read: success %d", rc);

        outObj.src = malloc(4);
        outObj.dst = malloc(4);
        // printf(pointer);
        memcpy(outObj.src,buf+0,4);
        memcpy(outObj.dst,buf+4,4);
        memcpy(&outObj.ver,buf+8,1);
        memcpy(&outObj.n,buf+9,1);

        printf("\nSource IP = ");
        for (int i=0;i<4;i++)
            printf("%d ",outObj.src[i]);

        printf("\nDestination IP = ");
        for (int i=0;i<4;i++)
            printf("%d ",outObj.dst[i]);

        printf("\nVersion = %d",outObj.ver);
        printf("\nNumber of messages = %d",outObj.n);

        int k = 10;

        for (int i=0;i<outObj.n;i++)
        {
            memcpy(&outObj.profiles[i].length,buf+k,1);
            memcpy(&outObj.profiles[i].type,buf+k+1,1);
            outObj.profiles[i].data = malloc(outObj.profiles[i].length);
            memcpy(outObj.profiles[i].data,buf+k+2,5);
            k +=7;
        }

        for (int i=0;i<outObj.n;i++)
        {
            printf("\n------- Message %d --------",i+1);
            printf("\nLength : %d",outObj.profiles[i].length);
            printf("\nType : %d\n",outObj.profiles[i].type);
            for (int j=0;j<5;j++)
            {
                printf(" Data[%d] : %d",j,outObj.profiles[i].data[j]);
            }
        }

        for (int i=0;i<outObj.n;i++)
        {
            printf("\n\n---------- Values for Data Profile %d ------------",i+1);
            int index1=0;
            int sumReceivedData = 0;
            int sumMyData = 0;
            int sumMultpliedData = 0;
            int my_data[10] = {0};
            int myDataBinary[500] = {0};
            int recData[500] = {0};

            if (i==0)
            {
                my_data[0] = 1;
                my_data[1] = 3;
                my_data[2] = 9;
                my_data[3] = 10;
            }
            else if (i==1)
            {
                my_data[0] = 1;
                my_data[1] = 2;
                my_data[2] = 3;
                my_data[3] = 4;
                my_data[4] = 5;
            }

            for (int i=0; i<sizeof(my_data)/sizeof(int);i++)
            {
                if (my_data[i] > 0)
                {
                    index1 = my_data[i];
                    myDataBinary[index1] = 1;
                    //printf("my data %d = %d\n",index1,myDataBinary[index1]);
                }
            }

            for (int j=0; j<outObj.profiles[i].length;j++)
            { 
                if (outObj.profiles[i].data[j] > 0)
                {
                    index1 = outObj.profiles[i].data[j];
                    recData[index1] = 1;
                    //printf("rec data %d = %d\n",index1,recData[index1]);
                }
            }

            for (int i=0;i<500;i++)
            {
                sumReceivedData += recData[i];
                sumMyData += myDataBinary[i];
                sumMultpliedData += recData[i] * myDataBinary[i];
            }

            printf("\nrecSum = %d, \nmySum = %d, \nmultSum = %d\n",sumReceivedData,sumMyData,sumMultpliedData);

            float rho = Pearson(sumMyData,sumReceivedData,sumMultpliedData);
            printf("\nPearson Coefficient for Data Profile %d= %f\n",i+1,rho);
        }

        return 0;
    }
    //exit(EXIT_SUCCESS);
}

static float Pearson(int mySum, int recSum, int multSum)
{
    float Cov =0;
    float sdMyData = 0;
    float sdReceivedData =0;
    float rho;
    int n = 500;

    Cov = (1.0/(n-1))*(multSum - (1.0/n)*mySum*recSum);
    sdMyData = sqrt((1.0/(n-1))*(mySum - (1.0/n)*mySum*mySum));
    sdReceivedData = sqrt((1.0/(n-1))*(recSum - (1.0/n)*recSum*recSum));
    printf("Covariance = %f\n",Cov);
    printf("VarianceMyData = %f\n",sdMyData);
    printf("VarianceRecData = %f\n",sdReceivedData);
    if (sdMyData == 0.0 || sdReceivedData == 0.0)
        rho = 0.0;
    else
        rho = Cov/(sdMyData*sdReceivedData);

    return(rho);
}

它仍然需要做很多工作。