套接字连接间歇性挂起

时间:2016-09-16 12:59:57

标签: sockets signal-handling

以下代码是进程的一部分,该进程接受来自客户端的确认,然后将数据写入文件。下面的文件是此进程的套接字连接。

#define DEF -32768
#include "pragma.h"
#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE
#endif
#ifndef _SOCKET_SOURCE
#define _SOCKET_SOURCE
#endif
#include <sys/types.h>
#include <stdio.h>
#include <sys/signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#ifndef SHUT_RDWR
#  define SHUT_RDWR 2
#endif
#include "wddx.h"

static volatile sig_atomic_t sigtermrcvd;
char *stopflag;
char *progname;
static int stopflagval;
FILE *saveout;

static void
sighandler(int signum)
{
  sigtermrcvd=1;
}



int
main(int argc, char **argv)
{

  void handle_request( int );
  extern int errno;
  extern char **environ;
  extern FILE *logfd;
  int pid;
  struct sockaddr cli_addr;
  int addrlen;
  int connsock;
  int saveout_fd;
  struct sigaction act;
  sigset_t newsigset;
  int icnt;

  xloadsess(argc, argv);

  pid = getpid();
  saveout_fd = dup(1);
  saveout = fdopen(saveout_fd, "w");
  /* logfd = fopen("logfile", "w"); */

  for (icnt = 0; icnt < argc; ++icnt) {
      fprintf(saveout, "argv[%d]='%s'\n", icnt, argv[icnt]);
      fflush(saveout);
  }
  progname = argv[0];
  stopflag = argv[1];

  fprintf(saveout, "progname='%s' - stopflag='%s'\n", progname, stopflag);
  fflush(saveout);

  act.sa_handler = sighandler;            /* set up signal handler */
  act.sa_flags = 0;
  if ((sigemptyset(&act.sa_mask) == -1) ||
       (sigaction(SIGHUP, &act, NULL) == -1)||
       (sigaction(SIGTERM, &act, NULL) == -1)) {
      perror("Failed to set SIG handler");
      return 1;
  }


  if ((sigemptyset(&newsigset) == -1) ||
      (sigaddset(&newsigset, SIGTERM) == -1)) {
     perror("Failed to initialize the signal set");
     return 1;
  }


  call_webinit();
  fprintf(saveout, "Child %08x (%d) did init\n", pid, pid &0xffff);
  fflush(saveout);
  fprintf(stderr, "INIT\n");
  fflush(stderr);

  while (1) {
    if (sigprocmask(SIG_UNBLOCK, &newsigset, NULL) == -1)
       perror("Failed to unblock SIGTERM");


    addrlen = sizeof cli_addr;
    memset(&cli_addr, '\0', addrlen);


    if (sigtermrcvd) {
      fprintf(saveout, "Sigterm recvd\n");
      fflush(saveout);
      break;
    }
    connsock = accept(0, &cli_addr, &addrlen);
    fprintf(saveout, "Conneect Sockect from accept = %ld\n", connsock);
    if (connsock < 0) {
      fprintf(saveout, "accept error is %d\n", errno);
      if (errno == EINTR) {
        continue;
      }
      break;
    }
    if (sigprocmask(SIG_BLOCK, &newsigset, NULL) == -1)
     perror("Failed to block SIGTERM");
    /*
    fprintf(saveout, "Child %08x (%d) accepted\n", pid, pid & 0xffff);
    */
    handle_request(connsock);
    /*
    fprintf(saveout, "Child %08x (%d) returned\n", pid, pid & 0xffff);
    */
  }
  fprintf(saveout, "Child %08x (%d) exiting\n", pid, pid & 0xffff);
  fflush(saveout);
  shutdown(0, SHUT_RDWR);
  close(0);

  TERMINATE();

  exit(0);
}

它定期工作正常,但偶尔会出现以下错误并挂起:

Conneect Sockect from accept = 36
Conneect Sockect from accept = 36
Conneect Sockect from accept = 36
Conneect Sockect from accept = 36
Conneect Sockect from accept = 36
Conneect Sockect from accept = -1
accept error is 4
Sigterm recvd
Child 00003046 (12358) exiting
Conneect Sockect from accept = 36
Conneect Sockect from accept = 36
Conneect Sockect from accept = 36
Conneect Sockect from accept = 36
Conneect Sockect from accept = 36
Conneect Sockect from accept = -1
accept error is 4
Sigterm recvd

这是别人的代码而且这个人去世了。我一直试图诊断原因,但一直无法弄清楚问题。任何帮助表示赞赏!

0 个答案:

没有答案