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

📄 main.cpp

📁 WIN NT/2000 聊天服务程序样例
💻 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 + -