Chinaunix首页 | 论坛 | 博客
  • 博客访问: 425769
  • 博文数量: 116
  • 博客积分: 7087
  • 博客等级: 少将
  • 技术积分: 1175
  • 用 户 组: 普通用户
  • 注册时间: 2005-02-19 23:32
文章分类

全部博文(116)

文章存档

2012年(1)

2011年(2)

2010年(10)

2009年(21)

2008年(18)

2007年(12)

2006年(21)

2005年(31)

我的朋友

分类:

2005-12-14 09:58:58

一个良好的服务程序,应该写成daemon的方式.这样就可以脱离终端,而独立在后台运行了.

具体的原理这里就不写了,就是贴个源代码,做个备忘吧.

点评几句:

写日志的时候,如果用fprintf来输出,别忘了用fflush将缓冲清空一下.

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include


#define HOSTLEN    20
#define PORTLEN    5
#define WSNADDLEN  HOSTLEN+PORTLEN+11
#define FILEURLLEN 128
#define WZSFCFG    "WZSFCFG"
#define LOG    "/ipp/log/wzsfTrans.log"
#define TUXEDORETURN 256

#define SERV_PORT  9970
#define LISTENQ  10
#define MAXDATASIZE 204800

#define NCHAR_SYSDATE_BUFFER 256

extern void sysdate( char sysdate_buffer[], size_t nchar_sysdate_buffer );

size_t nchar_sysdate_buffer = NCHAR_SYSDATE_BUFFER;

char sysdate_buffer[NCHAR_SYSDATE_BUFFER];

struct struct_tuxedo_conn_param
{
       char * host;
       char * port;
       char * wsnadd;
       };
      
struct struct_tianzheng_msg_head
{
  char length[6];
  char rows[4];
  char transcode[4];
  char domainname[30];
  char servicename[30];
  char temp1[12];
  char temp2[30];
  char temp3[14];
};
int checkParam(char * buf,struct struct_tianzheng_msg_head **p)
{
 *p=(struct struct_tianzheng_msg_head *)buf;
 return atoi((*p)->length);
}

int GetConn(struct struct_tuxedo_conn_param *p,FILE *finfo)
{
 char * strConfigFile;
 
 strConfigFile=getenv(WZSFCFG);
 
 if (strConfigFile==NULL)
 {
  fprintf(finfo,"取环境变量WZSFCFG失败! ");
  return -1;
 }
 
 PROF_GetString("WZSF","HOST","10.8.189.53",p->host,HOSTLEN,strConfigFile);
 
 PROF_GetString("WZSF","PORT","6667",p->port,PORTLEN,strConfigFile);
 
 sprintf(p->wsnadd,"WSNADDR=//%s:%s",p->host,p->port);
 
 putenv(p->wsnadd);
 
 fflush(finfo);
 
 return 0; 
}

int ConnectWU(
 char *servicename,
 char *sendmsg,
 int sendmsglen,
 char *recvmsg,
 int recvmsglen,
 FILE * finfo
 )
{
 struct struct_tuxedo_conn_param a;
 char * strInBuf,* strOutBuf;
 long oBufLen;
 
 a.host=(char *)malloc(HOSTLEN);
 a.port=(char *)malloc(PORTLEN);
 a.wsnadd=(char *)malloc(WSNADDLEN);
 memset(a.host,0,HOSTLEN);
 memset(a.port,0,PORTLEN);
 memset(a.wsnadd,0,WSNADDLEN);
 
 if(GetConn(&a,finfo)!=0)
 {
  free(a.host);
  free(a.port);
  free(a.wsnadd);
  return -1;
  }


 if(tpinit((TPINIT *)NULL) == -1)
 {
  fprintf(finfo,"tpinit error! ");
  return -2;
 }

 strInBuf = (char *)tpalloc("STRING",NULL,sendmsglen);
 
 if ( strInBuf == (char *)NULL)
 {
  if(tpterm()== -1)
  {
   fprintf(finfo,"tpterm failed ");
  } 
  return -3;
 }

 strOutBuf = (char *)tpalloc("STRING",NULL,TUXEDORETURN);
 
 if ( strOutBuf == (char *)NULL)
 {
  if(tpterm()== -1)
  {
   fprintf(finfo,"tpterm failed ");
  } 
  return -2;
 }
 
 strncpy(strInBuf,sendmsg,sendmsglen);
 
 if (tpcall((char *)servicename, (char *)strInBuf, 0, (char **)&strOutBuf, (long *)&oBufLen, (long)0)< 0 )
 {
  tpfree(strInBuf);
  tpfree(strOutBuf);
  if(tpterm()== -1)
  {
   fprintf(finfo,"tpterm failed ");
  } 
  return -2;
 }
 
 strncpy(recvmsg,strOutBuf,oBufLen);
 
 
   
 tpfree(strInBuf);
 
 tpfree(strOutBuf);
  
 if(tpterm()== -1)
 {
  fprintf(finfo,"tpterm failed! ");
 }
  
 free(a.host);
 free(a.port);
 free(a.wsnadd); 
 fflush(finfo);
 return 0;
}  

int main(void) {
 int i_listen_fd,i_client_fd; 
 size_t st_sin_size;  
 struct sockaddr_in  struct_server_addr,struct_client_addr;
       
        /* Our process ID and Session ID */
        pid_t pid, sid;
       
        FILE * fp;

        /* 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 */       
 fp=fopen(LOG,"w+");
 if(fp==NULL)
 {
  perror("failed to create log file");
  exit(EXIT_FAILURE);
 }
               
        /* 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 */
        signal(SIGCHLD,SIG_IGN);
       
 /*
  建立socket handle
 */
 if(
  (i_listen_fd = socket(AF_INET,SOCK_STREAM,0) ) == -1
  )
 {
   sysdate( sysdate_buffer, nchar_sysdate_buffer );
   fprintf(fp,"[%s] socket create error! ",sysdate_buffer);
   exit(1);
 }
 struct_server_addr.sin_family   = AF_INET;
 struct_server_addr.sin_addr.s_addr  = htonl(INADDR_ANY);
 struct_server_addr.sin_port   = htons(SERV_PORT);
 bzero(&(struct_server_addr.sin_zero),8);
 
 /*
  端口绑定
 */
 if(
  bind(i_listen_fd,(struct sockaddr *)&struct_server_addr,sizeof(struct_server_addr)) == -1
  )
 {
   sysdate( sysdate_buffer, nchar_sysdate_buffer );
   fprintf(fp,"[%s] bind error! ",sysdate_buffer);
   exit(1);
 }
 
 if(listen(i_listen_fd,LISTENQ) == -1)
 {
   sysdate( sysdate_buffer, nchar_sysdate_buffer);
   fprintf(fp,"[%s] listen error! ",sysdate_buffer);
   exit(1);
 }       
        /* The Big Loop */
        while (1) {
           /* Do some task here ... */
           st_sin_size = sizeof(struct sockaddr_in );
  
  if (
   ( i_client_fd = accept(i_listen_fd, (struct sockaddr *)&struct_client_addr, &st_sin_size)) == -1
  )
  {
   sysdate( sysdate_buffer, nchar_sysdate_buffer);
   fprintf(fp,"[%s] accept error! ",sysdate_buffer);
   continue;
  }
  if (!fork())
  {
   char str_input_buf[MAXDATASIZE];
   char str_output_buf[MAXDATASIZE];
   int i_input_len,i_sentbytes;
   int i_param_len;
   
   struct struct_tianzheng_msg_head *struct_p;
   
   memset(str_input_buf, 0, sizeof(str_input_buf));
   
   if ((i_input_len=recv(i_client_fd, str_input_buf, MAXDATASIZE, 0)) ==-1)
   {
    sysdate( sysdate_buffer, nchar_sysdate_buffer);
    fprintf(fp,"[%s] recv error! ",sysdate_buffer);
    exit(1);
   }
   
   str_input_buf[i_input_len] = '';
   
   sysdate( sysdate_buffer, nchar_sysdate_buffer);
   
   fprintf(fp,"[%s] Data Received: %s ",sysdate_buffer,str_input_buf);   
   
   if(i_input_len<130)
   {
    sysdate(sysdate_buffer, nchar_sysdate_buffer);
    fprintf(fp,"[%s] Incomplete data received! ",sysdate_buffer);
    exit(2);
   }   
   
   if((i_param_len=checkParam(str_input_buf,&struct_p)) > 0)
   {
    /*
     i_output_len:水司返回信息的长度
     str_param:提交参数
     str_p:临时字符串指针
    */
    int  i_output_len;
    char * str_param;
    char * str_p;
    
    str_p=struct_p->servicename;
    
    while(str_p[0]!=32)
     str_p++;
    
    str_p[0]='';   
    
    
    str_param=(char *)malloc(i_param_len+1);
    
    memset(str_param,0,i_param_len+1);
    
    strncpy(str_param,str_input_buf+sizeof(struct struct_tianzheng_msg_head),i_param_len);
    
    sysdate(sysdate_buffer, nchar_sysdate_buffer);
    
    fprintf(fp,"[%s] Service name is %s, Param is %s. ",sysdate_buffer,struct_p->servicename,str_param);
    
    ConnectWU(struct_p->servicename,str_param,i_param_len,str_output_buf,MAXDATASIZE,fp);
    
    //strncpy(str_output_buf,struct_p->servicename,strlen(struct_p->servicename));
    
    free(str_param);
    
    i_sentbytes = send(i_client_fd, str_output_buf, strlen(str_output_buf) , 0);
    
    sysdate(sysdate_buffer, nchar_sysdate_buffer);
    
    fprintf(fp,"[%s] Message Returned: %s ",sysdate_buffer,str_output_buf);    
    
    fflush(fp);
   }
   
   shutdown(i_client_fd, 2);
   
   close(i_client_fd);
   

  } 

        }
   fclose(fp);
   exit(EXIT_SUCCESS);
}

-----------------------------------------------------------------------------------------

#include
#include
#include
#include
#include

void sysdate( char sysdate_buffer[], size_t nchar_sysdate_buffer )
{
  /*    DESCRIPTION: Returns the system date as a null terminated character string. */
  /*           FILE: sysdate.c                                                      */
  /*         AUTHOR: David Stepaniak, NCAR/CGD/CAS                                  */
  /* DATE INITIATED: July 2002                                                      */
  /*  LAST MODIFIED: July 2002                                                      */

  /* Commented declaratons follow Chapter 17, "Date and Time" of
    "GNU C library manual", especially 17.2.3, "Broken-down Time". */

  time_t curtime;
    /* type defintion time_t is equivalent to long int */

  struct tm *loctime;
    /* Data Type: struct tm
       This is the data type used to represent a broken-down time.
       The structure contains at least the following members, which
       can appear in any order:
       int tm_sec
              This is the number of seconds after the minute,
              normally in the range 0 through 59. (The actual
              upper limit is 60, to allow for leap seconds if
              leap second support is available.)
       int tm_min
              This is the number of minutes after the hour, in
              the range 0 through 59.
       int tm_hour
              This is the number of hours past midnight, in the
              range 0 through 23.
       int tm_mday
              This is the day of the month, in the range 1 through 31.
       int tm_mon
              This is the number of months since January, in the
              range 0 through 11.
       int tm_year
              This is the number of years since 1900.
       int tm_wday
              This is the number of days since Sunday, in the range
              0 through 6.
       int tm_yday
              This is the number of days since January 1, in the
              range 0 through 365.
       int tm_isdst
              This is a flag that indicates whether Daylight Saving Time
              is (or was, or will be) in effect at the time described. The
              value is positive if Daylight Saving Time is in effect, zero
              if it is not, and negative if the information is not available.
       long int tm_gmtoff
              This field describes the time zone that was used to compute
              this broken-down time value, including any adjustment for
              daylight saving; it is the number of seconds that you must
              add to UTC to get local time. You can also think of this as
              the number of seconds east of UTC. For example, for U.S. Eastern
              Standard Time, the value is -5*60*60. The tm_gmtoff field is
              derived from BSD and is a GNU library extension; it is not
              visible in a strict ISO C environment.
       const char *tm_zone
              This field is the name for the time zone that was used to compute
              this broken-down time value. Like tm_gmtoff, this field is a BSD
              and GNU extension, and is not visible in a strict ISO C environment. */

  size_t status;
    /* Integer to store return value of strftime function. */

  /* Get the current time. */
  curtime = time(NULL);
  /* Function: time_t time (time_t *result)
       The time function returns the current time as a value of type time_t.
       If the argument result is not a null pointer, the time value is also stored
       in *result. If the calendar time is not available, the value (time_t)(-1)
       is returned. */

  /* Convert curtime to local time representation. */
  loctime = localtime(&curtime);
  /* Function: struct tm * localtime (const time_t *time)
       The localtime function converts the calendar time pointed to by time to
       broken-down time representation, expressed relative to the user's specified
       time zone.
       The return value is a pointer to a static broken-down time structure, which
       might be overwritten by subsequent calls to ctime, gmtime, or localtime.
       (But no other library function overwrites the contents of this object.)
       Calling localtime has one other effect: it sets the variable tzname with
       information about the current time zone. (See section 17.2.6 Functions and
       Variables for Time Zones.) */
   if (loctime == NULL)
   {
    printf("localtime has returned a NULL pointer in sysdate() ");
    exit(EXIT_FAILURE);
   }

  /* Write formatted members of loctime into the sysdate_buffer. */
  status = strftime( sysdate_buffer, nchar_sysdate_buffer, "%a %b %d %H:%M:%S %Z %Y", loctime );
  /* Function: size_t strftime (char *s, size_t size, const char *template,
       const struct tm *brokentime)
       This function is similar to the sprintf function (see section 7.12 Formatted
       Input), but the conversion specifications that can appear in the format template
       template are specialized for printing components of the date and time brokentime
       according to the locale currently specified for time conversion (see section 19.
       Locales and Internationalization).
       Ordinary characters appearing in the template are copied to the output string s;
       this can include multibyte character sequences. Conversion specifiers are
       introduced by a `%' character, followed by an optional flag which can be one of
       the following. These flags, which are GNU extensions, affect only the output of
       numbers:
       _ The number is padded with spaces.
       - The number is not padded at all.
       0 The number is padded with zeros even if the format specifies padding with spaces.
       ^ The output uses uppercase characters, but only if this is possible (see section
         4.2 Case Conversion).
       The default action is to pad the number with zeros to keep it a constant width.
       Numbers that do not have a range indicated below are never padded, since there is
       no natural width for them.
       Following the flag an optional specification of the width is possible. This is
       specified in decimal notation. If the natural size of the output is of the field
       has less than the specified number of characters, the result is written right
       adjusted and space padded to the given size.
       An optional modifier can follow the optional flag and width specification. The
       modifiers, which are POSIX.2 extensions, are:
       E Use the locale's alternate representation for date and time. This modifier
         applies to the %c, %C, %x, %X, %y and %Y format specifiers. In a Japanese
         locale, for example, %Ex might yield a date format based on the Japanese
         Emperors' reigns.
       O Use the locale's alternate numeric symbols for numbers. This modifier applies
         only to numeric format specifiers.
       If the format supports the modifier but no alternate representation is available,
       it is ignored.
       The conversion specifier ends with a format specifier taken from the following
       (abbreviated) list. The whole `%' sequence is replaced in the output string as
       follows:
       %a The abbreviated weekday name according to the current locale.
       %b The abbreviated month name according to the current locale.
       %d The day of the month as a decimal number (range 01 through 31).
       %H The hour as a decimal number, using a 24-hour clock (range 00 through 23).
       %M The minute as a decimal number (range 00 through 59).
       %S The second as a decimal number (range 00 through 60).
       %Y The year as a decimal number, using the Gregorian calendar. Years before
          the year 1 are numbered 0, -1, and so on.
       %Z The time zone abbreviation (empty if the time zone can't be determined).
       The size parameter can be used to specify the maximum number of characters to
       be stored in the array s, including the terminating null character. If the
       formatted time requires more than size characters, the excess characters are
       discarded. The return value from strftime is the number of characters placed
       in the array s, not including the terminating null character. If the value
       equals size, it means that the array s was too small; you should repeat the
       call, providing a bigger array.
       If s is a null pointer, strftime does not actually write anything, but instead
       returns the number of characters it would have written.
       According to POSIX.1 every call to strftime implies a call to tzset. So the
       contents of the environment variable TZ is examined before any output is produced.
       For an example of strftime, see section 17.2.7 Time Functions Example. */

}

阅读(1667) | 评论(0) | 转发(0) |
0

上一篇:安装vmware+linux心得

下一篇:用java访问web

给主人留下些什么吧!~~