邪恶八进制信息安全团队技术讨论组's Archiver

白色猎人 2006-6-28 11:35

[原创]C/S版的时间校验程序

原创作者:Unicorn (白色猎人)
信息来源:邪恶八进制团队(EST)
                                  C/S版的时间校验程序

昨天有一MM加我QQ让我帮她调试个课程设计,一个时间校验程序。由于她自己写的代码有如天女散花,我实在看不懂,呵呵,所以只好自己重新帮她写了个,由于时间仓促,就简单的写了个,代码非常简单,纯粹练手。
本程序在windows2000 + VC6.0下测试通过

客户端代码:
[code]
/*
* 时间校验程序客户端 V1.0
*
* 使用协议:TCP
*
* 监听端口:1984
*
* 代码编写:Unicorn
*
* 编写时间:2006/6/28 00:00:00
*/

#include <Winsock2.h>
#include <stdio.h>
#include <time.h>

#pragma comment (lib, "ws2_32.lib")

void main(int argc, char *argv[])
{
  WSADATA wsaData;
  int nRet;
  char szDestIp[1024];
  char szPort[1024];
  char sendBuf[1024];
  SYSTEMTIME revst;

  //判断输入的参数是否是3个,如果不是,将出现使用帮助
  if (argc != 3)
  {
    printf("Usage: %s [DestIP] [Port]\n", argv[0]);
    return;
  }
  
  strcpy(szDestIp, argv[1]);  //把第2个参数存入变量szDestIp中
  strcpy(szPort, argv[2]);  //把第3个参数存入变量szPort中

  nRet = WSAStartup(MAKEWORD(1, 1), &wsaData); //初始化套接字,如果成功返回0,否则返回个错误代码
  
  if (nRet != 0)
  {
    return;
  }
  
  if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
  {
    WSACleanup();
    return;
  }
  
  SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);  //创建一个套接字

  SOCKADDR_IN addrSrv;
  addrSrv.sin_addr.S_un.S_addr = inet_addr(szDestIp);
  addrSrv.sin_family = AF_INET;
  addrSrv.sin_port = htons(atoi(szPort));

  connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); //连接

  recv(sockClient, (char*)&revst, 100, 0);  //接收数据包
  sprintf(sendBuf, "IP地址为:%s的客户进行了1次时间校验请求!", inet_ntoa(addrSrv.sin_addr));
  send(sockClient,sendBuf,strlen(sendBuf)+1,0); //发送数据包

  SYSTEMTIME st;
   GetSystemTime(&st);   //获得系统时间

  st.wYear = revst.wYear;
  st.wMonth = revst.wMonth;
  st.wDay = revst.wDay;
   st.wHour = revst.wHour;     
   st.wMinute = revst.wMinute;
  st.wSecond =revst.wSecond;
   if (!SetLocalTime(&st))  //设置系统时间
  {
    printf("%s\n", "设置时间失败,请重试!");
  }
  else
  {
    printf("%s\n", "设置时间成功!");
  }

  closesocket(sockClient);  //关闭套接字
  WSACleanup();
}
[/code]

服务端代码:
[code]
/*
* 时间校验程序服务端 V1.0
*
* 使用协议:TCP
*
* 监听端口:1984
*
* 代码编写:Unicorn
*
* 编写时间:2006/6/28 00:00:00
*/

#include <Winsock2.h>
#include <stdio.h>
#include <Time.h>

#pragma comment (lib, "ws2_32.lib")  //连接Winsock的lib库

void main()
{
  WSADATA wsaData;
  int nRet;

  nRet = WSAStartup(MAKEWORD(1, 1), &wsaData); //初始化套接字,如果成功则返回0,否则返回个错误代码

  if (nRet != 0)
  {
    printf("%s\n", "初始化套接字失败,请重试!");
    return;
  }
  
  if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
  {
    WSACleanup();
    return;
  }

  printf("服务器监听端口为:%s\n", "1984");
  
  SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0); //创建一个套接字

  SOCKADDR_IN addrSrv;
  addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
  addrSrv.sin_family = AF_INET;
  addrSrv.sin_port = htons(1984);

  bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));   //在套接字上绑定一个IP和Port

  listen(sockSrv, 5);  //监听

  SOCKADDR_IN addrClient;
  int len = sizeof(SOCKADDR);

  while(1)
  {
    char recvBuf[100];
    SYSTEMTIME st;

    GetLocalTime(&st);  //获得系统当前时间
   
    SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);
   
    send(sockConn, (char*)&st, sizeof(st), 0);  //发送数据包
    recv(sockConn, recvBuf, 100, 0);  //接收数据包
   
    printf("%s\n", recvBuf);
    closesocket(sockConn);  //关闭套接字
  }
}
[/code]

avder 2006-6-28 16:32

客户里面的
  sprintf(sendBuf, "IP地址为:%s的客户进行了1次时间校验请求!", inet_ntoa(addrSrv.sin_addr));
  send(sockClient,sendBuf,strlen(sendBuf)+1,0); //发送数据包


应该在服务端吧

白色猎人 2006-6-29 08:54

[quote][b]这里是引用第[/b][color=#ff0000][1 楼][/color][b]的[color=#000066]avder[/color]于[/b]2006-06-28 16:32[b]发表的:[/b]
客户里面的
  sprintf(sendBuf, "IP地址为:%s的客户进行了1次时间校验请求!", inet_ntoa(addrSrv.sin_addr));
  send(sockClient,sendBuf,strlen(sendBuf)+1,0); //发送数据包


.......[/quote]
这个是客户端发往服务端的,类似于日志记录……

avder 2006-6-29 09:58

[quote][b]这里是引用第[/b][color=#ff0000][2 楼][/color][b]的[color=#000066]白色猎人[/color]于[/b]2006-06-29 08:54[b]发表的:[/b]

这个是客户端发往服务端的,类似于日志记录……[/quote]
我知道,但是你这样纪录的是本身的地址,是把服务端的地址发回服务端了,呵呵,你可能没有细看;)
我改了服务端一点点

[code]    while(1)
  {
     char recvBuf[100];
     SYSTEMTIME st;

     GetLocalTime(&st);  //获得系统当前时间
     
     SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);
     
     send(sockConn, (char*)&st, sizeof(st), 0); //发送数据包
     //recv(sockConn, recvBuf, 100, 0); //接收数据包


  sprintf(recvBuf, "IP地址为:%s的客户进行了1次时间校验请求!", inet_ntoa(addrClient.sin_addr));

     printf("%s\n", recvBuf);
     closesocket(sockConn); //关闭套接字
  }
}
[/code]

同样客户端要把
[code]
sprintf(sendBuf, "IP地址为:%s的客户进行了1次时间校验请求!", inet_ntoa(addrSrv.sin_addr));
send(sockClient,sendBuf,strlen(sendBuf)+1,0); //发送数据包

[/code]

去掉

zhouzhen 2006-6-29 11:07

建议使用ntp 协议.. 准确.. 弄个定时器. 呵呵..

白色猎人 2006-6-29 13:17

NTP协议的程序我做过一个,代码也发过来过了,HOHO……<<一个VC写的时间校验程序>>[url]http://forum.eviloctal.com/read-htm-tid-17675-fpage-5.html[/url]

avder 2006-6-29 15:19

[quote][b]这里是引用第[/b][color=#ff0000][5 楼][/color][b]的[color=#000066]白色猎人[/color]于[/b]2006-06-29 13:17[b]发表的:[/b]
NTP协议的程序我做过一个,代码也发过来过了,HOHO……<<一个VC写的时间校验程序>>[url]http://forum.eviloctal.com/read-htm-tid-17675-fpage-5.html[/url][/quote]

看到了阿,谢谢
我对GetSystemTime 和GetLocalTime 感觉挺迷糊的:(
那个简易的Win32hlp里面说

The GetSystemTime function retrieves the current system date and time. The system time is expressed in Coordinated Universal Time (UTC).

VOID GetSystemTime(

   LPSYSTEMTIME lpSystemTime    // address of system time structure  
  );   
===============
The GetLocalTime function retrieves the current local date and time.

VOID GetLocalTime(

   LPSYSTEMTIME lpSystemTime    // address of system time structure  
  );

可是我还是不懂;(

感觉两个好像是一样的 [s:42]

白色猎人 2006-6-29 17:16

GetLocalTime 获得的时间就是你电脑屏幕右下角的时间

GetSystemTime 获得的时间是UTC,也称为格林威治时间,若要获得本地时间,必须加上或减去您所在的时区与 UTC 之间相差的小时数。例如,UTC 中的 24:00(午夜)是纽约的 19:00 -- 负 5 小时的偏移量 (UTC–5)。

这样说容易明白不?呵呵……

avder 2006-6-30 00:53

懂了,谢谢 [s:45]
还有个问题
是不是两者取时间的机制不太一样啊
下面 分别是local 和system的,后面的分钟和秒怎么不一阿
2006年6月30日
1时11分56秒
2006年6月29日
17时12分16秒

页: [1]
© 1999-2008 EvilOctal Security Team