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

📄 time_tcp.cpp

📁 RFC686时间同步的服务器段和客户端代码 包括TCP和UDP
💻 CPP
字号:
#pragma warning(disable: 4530)
#pragma warning(disable: 4786)
#include <map>
#include <cassert>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <exception>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <tchar.h>
#include <ctime>
using namespace std;

#include <winsock2.h>
#include <windows.h>

#include "thread.h"
#include "threadpool.h"

char * GetErrorMessage(char *szBuffer, DWORD dwSize)
{
	FormatMessage( 
		FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL,
		GetLastError(),
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
		szBuffer,
		dwSize - 1,
		NULL
		);
	return szBuffer;
}

class RFC868TCPServer : public ThreadJob, public Thread
{
	SOCKET _S37;
	long _lWorkCount;
	bool _fRunFlag;
	u_long _uIP;
	ThreadPool _TP;
public:
	RFC868TCPServer(DWORD tp_num = 10) : _TP(tp_num), _S37(INVALID_SOCKET), _lWorkCount(0), _fRunFlag(true)
	{
		_uIP = htonl(INADDR_ANY); //默认监听IP为本地
	}
	~RFC868TCPServer()
	{
		if(_S37 != INVALID_SOCKET)
			closesocket(_S37);
	}
	bool Begin()//开始监听并启动线程
	{
		char Buffer[256];
		struct sockaddr_in server;
		server.sin_family = AF_INET;
		server.sin_port = htons(37);
		server.sin_addr.s_addr = _uIP;

		if((_S37 = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
			return false;

		unsigned long  NonBlock = 1;
		if(ioctlsocket(_S37, FIONBIO, &NonBlock) == SOCKET_ERROR)
			return false;

		if(bind(_S37, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
			return false;

		if(listen(_S37, 20) == SOCKET_ERROR)
			return false;
		
		return Thread::Begin();
	}
	inline bool End()
	{
		_fRunFlag = false;
		Sleep(100);
		return Thread::End();
	}
	inline bool WaitEnd(DWORD dwWaitTime = INFINITE)
	{
		_fRunFlag = false;
		return !Wait(dwWaitTime) ? Thread::End() : true;
	}
	virtual void DoJob(void *para)//线程池的作业
	{
		SOCKET s = *(SOCKET *)para;
		delete para;
		
		time_t cur_time = time(NULL) + 2208988800;
		char s_buf[4], *tp = ((char *)&cur_time) + 3;
		for(int i=0; i<4; i++)
			s_buf[i] = *tp--;

		if(send(s, s_buf, 4, 0) == SOCKET_ERROR)
		{
			LogError();
			closesocket(s);
			return;
		}

		if(shutdown(s, SD_SEND) == SOCKET_ERROR)
		{
			LogError();
			closesocket(s);	
			return;
		}
		closesocket(s);	
		InterlockedIncrement(&_lWorkCount); 
	}
	inline void LogMessage(char *szStr)
	{
		Thread::Lock();
		cout << szStr << endl;
		Thread::UnLock();
	}
	inline void LogError()
	{
		char Buffer[256];
		LogMessage(GetErrorMessage(Buffer, 256));
	}
	inline long GetWorkCount()
	{
		return 	_lWorkCount;
	}
	inline void SetIP(char *szIPStr)
	{
		_uIP = inet_addr(szIPStr);
	}
	inline void SetIP(u_long ip)
	{
		_uIP = ip;
	}
	virtual void WorkProc()
	{
		char Buffer[500];
		SOCKET ns, s = _S37;

		struct sockaddr_in client;
		int len = sizeof(client), ret;

		FD_SET read_set;
		timeval tv = {0, 100000}; //tv.tv_sec = 0, tv.tv_usec = 100000;

		while(_fRunFlag)
		{
			FD_ZERO(&read_set);
			FD_SET(s, &read_set);

			ret = select(0, &read_set, NULL, NULL, &tv);//Selet模型

			if(ret == SOCKET_ERROR)
			{
				LogMessage(GetErrorMessage(Buffer, 500));
				continue;
			}

			if(FD_ISSET(s, &read_set))//等到客户端
			{
				ns = accept(s, (struct sockaddr *)&client, &len);
				if(ns != INVALID_SOCKET)
				{
					_TP.Call(this, new SOCKET(ns));//调用线程池
					sprintf(Buffer, "Accept Client %s (%d)\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
					LogMessage(Buffer);
				}
				else
					LogMessage(GetErrorMessage(Buffer, 500));
			}
		}

		_TP.EndAndWait();
	}
};

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	try
	{
		char Buffer[256];
		WORD wVersionRequested;
		WSADATA wsaData;
		wVersionRequested = MAKEWORD(2, 2);
		if(WSAStartup(wVersionRequested, &wsaData))
		{
			cout << __LINE__ << GetErrorMessage(Buffer, 256) << endl;
			return 1;
		}
		RFC868TCPServer tcp;
		if(!tcp.Begin())
			cout << __LINE__ << GetErrorMessage(Buffer, 256) << endl;
		for(;;)
		{
			Sleep(10000);
			//if(tcp.GetWorkCount() >= 5)//完成5客户端的时间发送就退出
			//	break;
		}
		tcp.WaitEnd();
		WSACleanup();
	}
	catch(exception &e)
	{
		cout << e.what() << endl;
	}
	return 0;
}


⌨️ 快捷键说明

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