现在的位置: 首页 > 综合 > 正文

网络同步校时UDP服务器端SDK代码(RFC868/C++/WIN32/SOCKET/UDP)

2013年10月24日 ⁄ 综合 ⁄ 共 3401字 ⁄ 字号 评论关闭

#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;
}

抱歉!评论已关闭.