在Windows中创建服务一般需要先编写服务程序的代码,然后使用SCM注册这个服务。
手动注册一个Windows服务的方法是:
1 2 3 4 5 6 7 8 9
| sc create TestService binpath= D:\\Programs\\TestService\\main.exe
sc delete TestService
net start TestService
net stop TestService
|
这里实现了一个最基本的Windows服务程序,服务启动之后监听本地TCP 8888端口,接收和发送数据。
service.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
#include <stdio.h> #include <Windows.h>
#include "service.h"
#define SLEEP_TIME 5000
SERVICE_STATUS ServiceStatus; SERVICE_STATUS_HANDLE hStatus;
void ServiceMain(int argc, char** argv); void ControlHandler(DWORD request); int InitService(); int WriteToLog(char* str); int main(int argc, char* argv[]){ SERVICE_TABLE_ENTRY ServiceTable[2]; ServiceTable[0].lpServiceName = "ServiceExample1"; ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; ServiceTable[1].lpServiceName = NULL; ServiceTable[1].lpServiceProc = NULL; StartServiceCtrlDispatcher(ServiceTable); return 0; }
void ServiceMain(int argc, char** argv){ int error; ServiceStatus.dwServiceType = SERVICE_WIN32; ServiceStatus.dwCurrentState = SERVICE_START_PENDING; ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwServiceSpecificExitCode = 0; ServiceStatus.dwCheckPoint = 0; ServiceStatus.dwWaitHint = 0; hStatus = RegisterServiceCtrlHandler("ServiceExample1", (LPHANDLER_FUNCTION)ControlHandler); if (hStatus == (SERVICE_STATUS_HANDLE)0){ return; } error = InitService(); if (!error){ ServiceStatus.dwCurrentState = SERVICE_STOPPED; ServiceStatus.dwWin32ExitCode = -1; SetServiceStatus(hStatus, &ServiceStatus); return; } ServiceStatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus (hStatus, &ServiceStatus); int server = start_server(8888);
return; }
void ControlHandler(DWORD request){ switch(request) { case SERVICE_CONTROL_STOP: WriteToLog("服务已停止"); ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwCurrentState = SERVICE_STOPPED; SetServiceStatus (hStatus, &ServiceStatus); return; case SERVICE_CONTROL_SHUTDOWN: WriteToLog("服务已关闭"); ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwCurrentState = SERVICE_STOPPED; SetServiceStatus (hStatus, &ServiceStatus); return; default: break; } SetServiceStatus (hStatus, &ServiceStatus); return; }
int InitService(){ WriteToLog("服务已启动"); return true; }
|
server.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| #include <winsock2.h> #include <windows.h> #include <stdio.h> #include <stdlib.h>
#include "service.h"
#pragma comment(lib,"ws2_32.lib")
int start_server(int bind_port){ WORD sockVersion = MAKEWORD(2, 2); WSADATA wsaData; if (WSAStartup(sockVersion, &wsaData) != 0){ return 0; } SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (slisten == INVALID_SOCKET){ WriteToLog("Socket创建失败!"); return 0; } struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(bind_port); sin.sin_addr.S_un.S_addr = INADDR_ANY; if (bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR){ WriteToLog("Socket绑定失败!"); } if (listen(slisten, 5) == SOCKET_ERROR) { WriteToLog("Socket监听失败!"); return 0; } SOCKET sClient; struct sockaddr_in remoteAddr; int nAddrlen = sizeof(remoteAddr); WriteToLog("Socket监听成功,等待连接..."); sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen); while (1){ char revData[255];
char * client_address = inet_ntoa(remoteAddr.sin_addr); if (sClient == INVALID_SOCKET){ WriteToLog("数据接收错误!"); continue; } WriteToLog( client_address ); int ret = recv(sClient, revData, 255, 0); if (ret > 0){ WriteToLog(revData); }
char * sendData = revData; send(sClient, sendData, strlen(sendData), 0);
} closesocket(sClient); closesocket(slisten); WSACleanup(); return 0; }
|
utils.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
#include <time.h> #include <stdio.h> #include <stdlib.h>
#define LOGFILE "C://service_example_1_log.txt"
int WriteToLog(char* str){ FILE* log; log = fopen(LOGFILE, "a+"); if (log == NULL) return -1;
time_t rawtime; struct tm * timeinfo; char time_buffer [128];
time (&rawtime);
timeinfo = localtime (&rawtime); strftime (time_buffer,sizeof(time_buffer),"%Y/%m/%d %H:%M:%S",timeinfo);
fprintf(log, "%s\t%s\n", time_buffer, str); fclose(log); return 0; }
|
service.h
1 2 3 4 5 6
|
extern int WriteToLog(char* str); extern int start_server(int bind_port);
|
参考资料
开发 Windows 服务应用
C语言开发Windows服务
C++编写Windows服务
C++编写Windows服务
Windows 服务程序(一)
Windows 服务程序(二)
windows环境下C语言socket编程