⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syncserver.c

📁 同步软件源码,作者 Jeroen C. Kessels Internet Engineer
💻 C
📖 第 1 页 / 共 3 页
字号:
  if (Data->ForceStop == YES) {
    i = 0;
    setsockopt(Data->ReceiveSocket,SOL_SOCKET,SO_DONTLINGER,(char *)&i,sizeof(i));
    }
  sprintf(s1,"%s Disconnected.",Data->RemoteAddress);
  LogMessage(s1);
  if (closesocket(Data->ReceiveSocket) != 0) {
    SocketErrorStr(WSAGetLastError(),s1);
    LogMessage(s1);
    }

  /* Wait for thread 4 to stop, maximum 10 seconds. */
  for (WaitCount = 0; WaitCount < 100; WaitCount++) {
    if (Data->Running == STOPPED) break;
    Sleep(100);
    }

  /* Exit. */
  free(Data);
  _endthread();
  }





/* Server thread 2: listen on the ListenSocket and start a new
   thread when somebody connects. Stop when the ServiceControl()
   subroutine sets the Running flag to STOPPING.*/
void Server2(struct ServerStruct *Data) {
  struct ServerStruct *NewData;
  char s1[BUFSIZ];

  while (1) {
    /* Wait for an incoming connection. */
    Data->ReceiveSocket = accept(Data->ListenSocket,NULL,NULL);

    /* If the service is beiing stopped then exit. */
    if (ServerRunning != RUNNING) break;

    /* If there was an error then write a message to the log and loop. */
    if (Data->ReceiveSocket == INVALID_SOCKET) {
      SocketErrorStr(WSAGetLastError(),s1);
      LogMessage(s1);
      continue;
      }

    /* Start a new thread to handle the incoming connection.
       Creating the thread takes just about no time at all, so we can
       immediately continue to listen for more incoming connections.
       The thread will be busy for some time, but that doesn't
       concern us here.
       Note: the ReceiveSocket must be passed by value, not by pointer,
       or the next connection will overwrite the socket. */
    NewData = (struct ServerStruct *)malloc(sizeof(struct ServerStruct));
    NewData->Running = RUNNING;
    NewData->ForceStop = YES;
    NewData->ListenSocket = Data->ListenSocket;
    NewData->ReceiveSocket = Data->ReceiveSocket;
    _beginthread(Server3,0,(void *)NewData);
    }

  /* Exit. */
  ServerRunning = STOPPED;
  free(Data);
  _endthread();
  }





/* Listen to the socket and if a remote server connects then spawn a
   new thread and handle the incoming data. */
void Server(void *xxx) {
  struct ServerStruct *Data;
  SOCKET ListenSocket;
  SOCKADDR_IN SocketControl;
  int WaitCount;
  char s1[BUFSIZ];

  /* Create a listen-socket for the server. */
  SocketControl.sin_addr.s_addr = INADDR_ANY;
  SocketControl.sin_port = htons(ServerPort);
  SocketControl.sin_family = AF_INET;
  ListenSocket = socket(AF_INET,SOCK_STREAM,0);
  if ((ListenSocket == INVALID_SOCKET) ||
      (bind(ListenSocket,(LPSOCKADDR)&SocketControl,sizeof(SocketControl)) != 0) ||
      (listen(ListenSocket,SOMAXCONN) != 0)) {
    SocketErrorStr(WSAGetLastError(),s1);
    LogMessage(s1);
    if (ListenSocket != INVALID_SOCKET) closesocket(ListenSocket);
    ServerRunning = STOPPED;
    _endthread();
    return;
    }

  /* Allocate a new data block in memory. */
  Data = (struct ServerStruct *)malloc(sizeof(struct ServerStruct));
  Data->ListenSocket = ListenSocket;

  /* Start thread 2 and wait until the Running flag is STOPPING. */
  if (_beginthread(Server2,0,(void *)Data)== -1) {
      LogMessage("Cannot start thread 2.");
      ServerRunning = STOPPED;
      free(Data);
    } else {
      while (ServerRunning == RUNNING) Sleep(1000);
      }

  /* Shutdown the socket. This should cause thread 2 to unblock from
     the accept() system call. */
  if (closesocket(ListenSocket) != 0) {
    SocketErrorStr(WSAGetLastError(),s1);
    LogMessage(s1);
    }

  /* Wait for thread 2 to stop, maximum 10 seconds. */
  for (WaitCount = 0; WaitCount < 100; WaitCount++) {
    if (ServerRunning == STOPPED) break;
    Sleep(100);
    }

  ServerRunning = STOPPED;
  _endthread();
  }





/**** Service ***************************************************************/




/* This function is called by the Windows Service Control Manager
   when it wants the service to perform certain tasks (see
   ControlService()). We don't care about most tasks, only
   stopping the service is needed/implemented. */
VOID WINAPI ServiceControl(DWORD Control) {
  char s1[BUFSIZ];
  char s2[BUFSIZ];

  if (Control = SERVICE_CONTROL_STOP) {
    /* Signal the SCM that we are stopping. */
    ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
    ServiceStatus.dwWin32ExitCode = NO_ERROR;
    ServiceStatus.dwServiceSpecificExitCode = 0;
    SetServiceStatus(ServiceHandle,&ServiceStatus);

    /* Stop the listener. */
    ServerRunning = STOPPING;
    while (ServerRunning != STOPPED) Sleep(1000);

    LogMessage("Service has stopped.");

    /* Signal the SCM that we have stopped. */
    ServiceStatus.dwCurrentState = SERVICE_STOPPED;
    SetServiceStatus(ServiceHandle,&ServiceStatus);

    return;
    }

  /* In all other cases give a signal to the SCM that we're still
     alive and well. */
  ServiceStatus.dwWin32ExitCode = NO_ERROR;
  ServiceStatus.dwServiceSpecificExitCode = 0;
  if (SetServiceStatus(ServiceHandle,&ServiceStatus) == 0) {
    SystemErrorStr(GetLastError(),s1);
    sprintf(s2,"ServiceControl(): %s",s1);
    LogMessage(s2);
    }
  }





/* The main Service loop. This function is called by the Windows
   Service Control Manager to start running the service. It will
   load the configuration file from disk, initialize Winsock,
   start the Listener and Watchdog threads, and then wait
   forever. */
void WINAPI RunService(DWORD dwArgc, LPTSTR *lpszArgv) {
  WSADATA WsaData;
  int Status;
  char s1[BUFSIZ];
  char s2[BUFSIZ];

  if (Console == NO) {
    /* Register our service control handler. */
    ServiceHandle = RegisterServiceCtrlHandler(SZSERVICENAME,ServiceControl);
    if (ServiceHandle == 0) {
      SystemErrorStr(GetLastError(),s1);
      sprintf(s2,"RunService(1): %s",s1);
      LogMessage(s2);
      return;
      }

    /* Signal the Service Control Manager that we're starting. */
    ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
    ServiceStatus.dwControlsAccepted = 0;
    ServiceStatus.dwWin32ExitCode = NO_ERROR;
    ServiceStatus.dwServiceSpecificExitCode = 0;
    ServiceStatus.dwWaitHint = 3000;
    ServiceStatus.dwCheckPoint = 0;
    if (SetServiceStatus(ServiceHandle,&ServiceStatus) == 0) {
      SystemErrorStr(GetLastError(),s1);
      sprintf(s2,"RunService(2): %s",s1);
      LogMessage(s2);
      return;
      }
    }

  LogMessage("Starting service.");

  /* Initialize winsock. */
  Status = WSAStartup(WS_VERSION_REQD,&WsaData);
  if (Status != 0) {
    SocketErrorStr(WSAGetLastError(),s1);
    sprintf(s2,"RunService(3): %s",s1);
    LogMessage(s2);
    if (Console == YES) return;
    ServiceStatus.dwCurrentState = SERVICE_STOPPED;
    ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    ServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
    ServiceStatus.dwServiceSpecificExitCode = Status;
    SetServiceStatus(ServiceHandle,&ServiceStatus);
    return;
    }

  /* Report SERVICE_RUNNING to the service control manager. */
  if (Console == NO) {
    ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    if (SetServiceStatus(ServiceHandle,&ServiceStatus) == 0) {
      SystemErrorStr(GetLastError(),s1);
      sprintf(s2,"RunService(5): %s",s1);
      LogMessage(s2);
      WSACleanup();
      return;
      }
    }

  /* Start new thread for the Listener. */
  ServerRunning = RUNNING;
  _beginthread(Server,0,(void *)0);

  while(1) {
    Sleep(10000);
    }

  /* Should never get here. */
  }





/* Install the service. This function will add this program to the
   list of services. The service is not yet started. */
void InstallService(void) {
  SC_HANDLE ServiceHandle;
  SC_HANDLE ManagerHandle;
  int Result;
  char s1[BUFSIZ];

  ManagerHandle = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
  if (ManagerHandle == NULL) {
    SystemErrorStr(GetLastError(),s1);
    fprintf(stdout,"Unable to install, %s\n",s1);
    return;
    }

  /* Create the service. */
  ServiceHandle = CreateService(
    ManagerHandle,              // SCManager database
    SZSERVICENAME,              // name of service
    SZSERVICEDISPLAYNAME,       // name to display
    SERVICE_ALL_ACCESS,         // desired access
    SERVICE_WIN32_OWN_PROCESS,  // service type
    SERVICE_AUTO_START,         // start type
    SERVICE_ERROR_NORMAL,       // error control type
    MyName,                     // service's binary
    NULL,                       // no load ordering group
    NULL,                       // no tag identifier
    SZDEPENDENCIES,             // dependencies
    NULL,                       // LocalSystem account
    NULL);                      // no password

  /* If the service could not be created then return an error. */
  if (ServiceHandle == NULL) {
    Result = GetLastError();
    if (Result != 1073) {
      SystemErrorStr(Result,s1);
      fprintf(stdout,"Unable to install, %s\n",s1);
      CloseServiceHandle(ManagerHandle);
      return;
      }
    }

  /* Everything is fine. */
  fprintf(stdout,"%s is now installed and can be started with\nthe Services control panel (see Windows administrative tools).\n",
    SZSERVICEDISPLAYNAME,SZSERVICEDISPLAYNAME);

  CloseServiceHandle(ServiceHandle);
  CloseServiceHandle(ManagerHandle);
  }




/* Stop and uninstall the service. The service is stopped (if
   running) and removed from the list of services. */
void RemoveService(void) {
  SC_HANDLE ServiceHandle;
  SC_HANDLE ManagerHandle;
  char s1[BUFSIZ];

  /* Open a handle to the Service Control Manager. */
  ManagerHandle = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
  if (ManagerHandle == NULL) {
    SystemErrorStr(GetLastError(),s1);
    fprintf(stdout,"Unable to uninstall, %s\n",s1);
    return;
    }

  /* Open a handle to the service. */
  ServiceHandle = OpenService(ManagerHandle,SZSERVICENAME,SERVICE_ALL_ACCESS);
  if (ServiceHandle == NULL) {
    SystemErrorStr(GetLastError(),s1);
    fprintf(stdout,"Unable to uninstall, %s\n",s1);
    CloseServiceHandle(ManagerHandle);
    return;
    }

  /* If the service is running then stop it. */
  if (ControlService(ServiceHandle,SERVICE_CONTROL_STOP,&ServiceStatus) != 0) {
    fprintf(stdout,"Stopping %s...\n",SZSERVICEDISPLAYNAME);
    do {
      Sleep(1000);
      if (QueryServiceStatus(ServiceHandle,&ServiceStatus) == 0) break;
      } while (ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING);
    if (ServiceStatus.dwCurrentState == SERVICE_STOPPED) {
        fprintf(stdout,"%s stopped.\n",SZSERVICEDISPLAYNAME);
      } else {
        fprintf(stdout,"%s failed to stop.\n",SZSERVICEDISPLAYNAME);
        }
    }

  /* Now remove the service. */
  if (DeleteService(ServiceHandle) != 0) {
      fprintf(stdout,"%s removed.\n",SZSERVICEDISPLAYNAME);
    } else {
      SystemErrorStr(GetLastError(),s1);
      fprintf(stdout,"DeleteService failed - %s\n",s1);
      }

  CloseServiceHandle(ServiceHandle);
  CloseServiceHandle(ManagerHandle);
  }




/**** Main ******************************************************************/




int main(int argc,char **argv) {
  SERVICE_TABLE_ENTRY dispatchTable[] = {
    {SZSERVICENAME,(LPSERVICE_MAIN_FUNCTION)RunService},
    {NULL,NULL}
    };
  SC_HANDLE ServiceHandle;
  SC_HANDLE ManagerHandle;
  SERVICE_STATUS ServiceStatus;
  char s1[BUFSIZ];
  char *p1;
  int i;

  /* Determine the paths to the executable, configuration file, and
     logfile. */
  GetModuleFileName(NULL,MyName,BUFSIZ);
  strcpy(CfgPath,MyName);
  p1 = stristr(CfgPath,".exe");
  if (p1 == NULL) *CfgPath = '\0';
  strcpy(p1,".cfg");
  strcpy(LogPath,MyName);
  p1 = stristr(LogPath,".exe");
  if (p1 == NULL) *LogPath = '\0';
  strcpy(p1,".log");

  /* If the program was started in a DOS box (not the Windows Service
     Control Manager) then write all output to stdout (instead of the
     logfile) and run as a program (instead of a service) that can be
     stopped with Ctrl-Break. */
  if (isatty(fileno(stdin)) != 0) Console = YES;

  /* Accept commandline parameters. */
  if (argc > 1) {
    for (i = 1; i < argc; i++) {
      if (stricmp("-install",argv[i]) == 0) {
        InstallService();
        return(0);
        }
      if ((stricmp("-remove",argv[i]) == 0) ||
          (stricmp("-uninstall",argv[i]) == 0)) {
        RemoveService();
        return(0);
        }
      fprintf(stdout,"%s -install     Install the service\n",argv[0]);
      fprintf(stdout,"%s -uninstall   Uninstall the service\n",argv[0]);
      return(0);
      }
    }

  /* If the program is started in a DOS box (not the Windows Service
     Control Manager) then run as a normal program (instead of a
     service). The program can be stopped by CTRL-Break. */
  if (Console == YES) {
    /* If the server has been installed as a service and is
       running, then shut it down. */
    ManagerHandle = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
    if (ManagerHandle != NULL) {
      ServiceHandle = OpenService(ManagerHandle,SZSERVICENAME,SERVICE_ALL_ACCESS);
      if (ServiceHandle != NULL) {
        if (ControlService(ServiceHandle,SERVICE_CONTROL_STOP,&ServiceStatus) != 0) {
          fprintf(stdout,"Stopping %s (is running as a service)...\n",SZSERVICEDISPLAYNAME);
          do {
            Sleep(1000);
            if (QueryServiceStatus(ServiceHandle,&ServiceStatus) == 0) break;
            } while (ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING);
          if (ServiceStatus.dwCurrentState != SERVICE_STOPPED) {
            fprintf(stdout,"Failed to stop. Cannot continue.\n",SZSERVICEDISPLAYNAME);
            return(0);
            }
          fprintf(stdout,"Stopped.\n",SZSERVICEDISPLAYNAME);
          }
        CloseServiceHandle(ServiceHandle);
        }
      CloseServiceHandle(ManagerHandle);
      }

    /* Run as a normal program. */
    RunService(0,NULL);
    return(0);
    }

  /* Test if the service has been installed. */
  ManagerHandle = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
  if (ManagerHandle == NULL) {
    SystemErrorStr(GetLastError(),s1);
    fprintf(stdout,"Cannot start service, %s\n",s1);
    return(0);
    }
  ServiceHandle = OpenService(ManagerHandle,SZSERVICENAME,SERVICE_ALL_ACCESS);
  if (ServiceHandle == NULL) {
    SystemErrorStr(GetLastError(),s1);
    fprintf(stdout,"Cannot start service, %s\n",s1);
    CloseServiceHandle(ManagerHandle);
    return(0);
    }
  CloseServiceHandle(ServiceHandle);
  CloseServiceHandle(ManagerHandle);

  /* Run as a Windows Service. */
  if (StartServiceCtrlDispatcher(dispatchTable) == 0) {
    SystemErrorStr(GetLastError(),s1);
    fprintf(stdout,"main(): %s\n",s1);
    }

  return(0);
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -