📄 main.cpp
字号:
#include "stdhdr.h"
#include "service.h"
#include "svc.h"
#include "slot.h"
#define SVCPORT 0x6E74 // NT (29806)
volatile BOOL g_bStop;
volatile BOOL g_bStopped;
extern "C" BOOL bDebug; // defined in SERVICE.C
// This is the main thread routine. It receives a user slot pointer.
int thread(CSlot *pSlot)
{
int i = 0;
pSlot->Send("Welcome! /QUIT or /BYE are the commands to quit.\n\n");
while (1)
{
char buf[1001];
int n;
n = pSlot->Recv(buf + i, 999 - i);
if (g_bStop || n <= 0)
{
delete pSlot;
return 0;
}
if (n > 0)
{
if (i + n == 999) buf[i + (n++)] = '\n';
for (int j = i; j < i + n; j++)
{
if (buf[j] == '\n')
{
buf[j] = '\0';
if (j > 0 && buf[j - 1] == '\r') buf[j - 1] = '\0';
if (!stricmp(buf, "/quit") || !stricmp(buf, "/bye"))
{
delete pSlot;
return 0;
}
else pSlot->m_pSvc->SendAll(buf, pSlot, false);
if (g_bStop) return 0;
memmove(buf, buf + j + 1, i + n - j - 1);
i -= j + 1;
break;
}
}
i += n;
}
}
// Neverreach
}
// Main service entry point. We wait for incoming connections, spawn threads.
// We shut down if the global (volatile) variable nStop is true. We assume that
// threads will stop within a finite amount of time.
void ServiceStart(unsigned long argc, char *argv[])
{
WSADATA wsaData;
SOCKET sockfd;
SOCKADDR_IN sin;
CSvc *pSvc;
int id;
// We are under Windows NT so I am not worried about too LOW a version number.
if (WSAStartup(MAKEWORD(1, 1), &wsaData)) return;
pSvc = new CSvc;
if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 3000))
goto cleanup;
id = 1;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == INVALID_SOCKET) goto cleanup;
sin.sin_family = AF_INET;
sin.sin_port = SVCPORT;
sin.sin_addr.s_addr = 0;
if (bind(sockfd, (LPSOCKADDR)&sin, sizeof(sin))) goto cleanup;
if (listen(sockfd, 5) < 0) goto cleanup;
if (!ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0))
goto cleanup;
while (1)
{
unsigned long ul;
SOCKET newsockfd = accept(sockfd, NULL, NULL);
if (g_bStop)
{
if (newsockfd != INVALID_SOCKET) closesocket(newsockfd);
break;
}
if (newsockfd == INVALID_SOCKET)
{
if (bDebug) cout << "Socket error " << WSAGetLastError() << endl;
}
else
{
struct linger l;
l.l_onoff = TRUE;
l.l_linger = 1;
setsockopt(newsockfd, SOL_SOCKET, SO_LINGER, (LPSTR)&l, sizeof(l));
CSlot *pSlot = new CSlot(pSvc, newsockfd, id++);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread, pSlot, 0, &ul);
}
}
cleanup:
delete pSvc;
if (sockfd != INVALID_SOCKET) closesocket(sockfd);
WSACleanup();
g_bStopped = TRUE;
}
// When the service is stopped, we must interrupt any blocking calls. We do
// that by setting g_bStop and then connecting to ourselves.
void ServiceStop()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(1, 1), &wsaData)) return;
g_bStop = TRUE;
SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN sin;
sin.sin_family = AF_INET;
sin.sin_port = SVCPORT;
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(s, (LPSOCKADDR)&sin, sizeof(sin));
while (!g_bStopped);
closesocket(s);
WSACleanup();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -