#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" //见网络同步校时TCP服务器端SDK代码末尾
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 RFC868UDPServer : public Thread { long _lWorkCount; //发送时间计数 bool _fRunFlag; //循环运行标志 SOCKET _S37; //socket u_long _uIP; //ip public: RFC868UDPServer() : _S37(INVALID_SOCKET), _lWorkCount(0), _fRunFlag(true) { _uIP = htonl(INADDR_ANY);//默认绑定本地IP } ~RFC868UDPServer() { if(_S37 != INVALID_SOCKET) closesocket(_S37); } //结束线程 inline bool End() { _fRunFlag = false; Sleep(100); return Thread::End(); } inline bool WaitEnd(DWORD dwWaitTime = INFINITE) { _fRunFlag = false; return !Wait(dwWaitTime) ? Thread::End() : true; } //打印信息 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; } //设置绑定的ip inline void SetIP(char *szIPStr) { _uIP = inet_addr(szIPStr); } inline void SetIP(u_long ip) { _uIP = ip; } inline virtual bool Begin() { 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_DGRAM, 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; return Thread::Begin(); } //线程工作函数 virtual void WorkProc() //if error return 1 { char Buffer[256];
struct sockaddr_in client; int c_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(_S37, &read_set); //select模型 if(select(0, &read_set, NULL, NULL, &tv) == SOCKET_ERROR) { LogMessage(GetErrorMessage(Buffer, 256)); continue; }
if(FD_ISSET(_S37, &read_set))//等到客户端 { if(recvfrom(_S37, NULL, 0, 0, (struct sockaddr *)&client, &c_len) != SOCKET_ERROR) { 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(sendto(_S37, s_buf, 4, 0, (struct sockaddr *)&client, c_len) == SOCKET_ERROR) { LogMessage(GetErrorMessage(Buffer, 256)); continue; }
sprintf(Buffer, "udp recvfrom client %s (%d) a null datagram \n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); LogMessage(Buffer); InterlockedIncrement(&_lWorkCount); } else LogMessage(GetErrorMessage(Buffer, 256)); } } } };
int main(int argc, char *argv[]) { try { char buf[256]; WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(2, 2); if(WSAStartup(wVersionRequested, &wsaData)) { cout << GetErrorMessage(buf, sizeof(buf)) << endl; return 1; } RFC868UDPServer udp; udp.Begin(); for(int i=0; ; i++) { Sleep(200); if(udp.GetWorkCount() >= 5)//完成5客户端的时间发送就退出 break; } udp.WaitEnd(200); WSACleanup(); } catch(exception &e) { cout << e.what() << endl; } return 0; }

|