时间同步服务器之网络编程

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验名称时间同步服务器设计
实验报告要求: 1.实验目的 2.实验要求 3.实验环境 4.实验作业 5.问题及解决
6.思考问题
7.实验体会
【实验目的】
一、实验目的
1、熟悉流式套接字的基本流程。

2、掌握TCP连接建立过程。

3、掌握基于TCP协议的数据发送与接收的编程。

4、掌握服务器本地时间获取与格式转换功能的编程。

二、实验内容
使用流式套接字编程,实现时间同步服务器,该服务器能够接受客户端的查询请求,
获取本地时间,并将结果发送回客户端,同时开发与服务器通信的客户端,以验证
双方交互的功能。

【实验要求】
使用流式套接字编程,实现时间同步服务器,该服务器能够接受客户端的查询请求,获取本地时间,并将结果发送回客户端,同时开发与服务器通信的客户端,以验证双方交互的功能。

具体要求如下:
1熟悉流式套接字编程的基本流程。

2完成TCP连接建立过程。

3完成基于TCP的数据发送与接收功能。

4完成服务器本地时间获取与格式转换功能。

【实验环境】
1、VC 6.0++
2、windows 7
3、以太网
【实验作业】
系统中客户方与服务器从建立连接,发送同步请求到同步系统时间的流程为:在整个时间同步过程中服务器必须要处于工作状态,时刻监听着网络中客户方的请求信息,监听到客户方的时间同步请求时,根据客户方的需求,来进行服务器响应,客户方在接收到服务器的响应报文后,根据服务器发送过来的时间,以及算出的网络延时来同步系统的时间。

套接字基础概念实现一个最基本的流式套接字客户端/服务器通信程序。

在该程序中,客户端和服务器将按照如下步骤交互:
1.服务器程序:
#include <stdio.h>
#include <time.h>
#include <stdafx.h>
#include <Winsock2.h>
#define MAXLINE 4096
#define LISTENQ 1024
#define SERVER_PORT 13
int main(int argc, char* argv[])
{
SOCKET ListenSocket = INVALID_SOCKET, ClientSocket = INVALID_SOCKET;
int iResult;
struct sockaddr_in servaddr;
char buff[MAXLINE];
time_t ticks;
int iSendResult;
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(2, 2);
iResult = WSAStartup(wVersionRequested, &wsaData);
if (iResult != 0) {
printf("WSAStartup 调用错误,错误号: %d\n", WSAGetLastError());
return -1;
}
wsaData.wVersion
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { printf("无法找到可用的Winsock.dll版本\n");
WSACleanup();
return -1;
}
else
printf("Winsock 2.2 dll初始化成功\n");
if((ListenSocket = socket(AF_INET, SOCK_STREAM, 0))<0){
printf("socket 函数调用错误,错误号: %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERVER_PORT); /* daytime server */
iResult = bind( ListenSocket, (struct sockaddr *) & servaddr, sizeof (servaddr));
if (iResult == SOCKET_ERROR) {
printf("bind 函数调用错误,错误号: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return -1;
}
iResult = listen(ListenSocket, LISTENQ);
if (iResult == SOCKET_ERROR){
printf("listen 函数调用错误,错误号: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return -1;
}
for ( ; ; )
{
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET){
printf("accept 函数调用错误,错误号: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return -1;
}
ticks = time(NULL);
memset(buff,0,sizeof(buff));
sprintf(buff, "%.24s\r\n", ctime(&ticks));
printf("获取当前系统时间: %s\n",buff );
iSendResult = send( ClientSocket, buff, strlen(buff), 0 );
if (iSendResult == SOCKET_ERROR) {
printf("send 函数调用错误,错误号: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return -1;
}
printf("向客户端发送时间成功\n");
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown 函数调用错误,错误号: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return -1;
}
closesocket(ClientSocket);
printf("主动关闭连接\n");
}
closesocket(ListenSocket);
WSACleanup();
return 0;
}
先是执行服务器程序进行Winsock 2.2 dll初始化:
即有截图:
客户端程序:
#include <stdio.h>
#include <Winsock2.h>
#include <stdafx.h>
#define MAXLINE 4096
#define SERVER_PORT 13
int main(int argc, char* argv[])
{
SOCKET ConnectSocket = INVALID_SOCKET;
int iResult;
char recvline[MAXLINE + 1];
struct sockaddr_in servaddr;
if (argc != 2){
printf("usage: DayTime <IPaddress>");
return 0;
}
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(2, 2);
iResult = WSAStartup(wVersionRequested, &wsaData);
if (iResult != 0) {
printf("WSAStartup 函数调用错误,错误号: %d\n", WSAGetLastError());
return -1;
}
wsaData.wVersion
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { printf("无法找到可用的Winsock.dll版本\n");
WSACleanup();
return -1;
}
else
printf("Winsock 2.2 dll初始化成功\n");
if((ConnectSocket = socket(AF_INET, SOCK_STREAM, 0))<0){
printf("socket 函数调用错误,错误号: %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERVER_PORT);
servaddr.sin_addr.s_addr=inet_addr(argv[1]);
iResult = connect( ConnectSocket, (LPSOCKADDR)&servaddr, sizeof(servaddr));
if (iResult == SOCKET_ERROR){
printf("connect 函数调用错误,错误号: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return -1;
}
memset(&recvline, 0, sizeof(recvline));
printf("当前时间是:");
do {
Sleep(5000);
iResult = recv(ConnectSocket, recvline, MAXLINE, 0);
if (iResult > 0)
printf("%s", recvline);
else{
if (iResult == 0)
printf("对方连接关闭,退出\n");
else
printf("recv 函数调用错误,错误号: %d\n", WSAGetLastError());
}
memset(&recvline, 0, sizeof(recvline));
} while (iResult > 0);
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
执行完上面的服务器程序,然后在执行客户端程序:1)先是初始化,如下图:
2)再是获取时间:
3)最后是服务器关闭连接,退出:
最后:
此次实验执行过程:
服务器命令:(什么都不用输入)(并且按enter键)
出现:Winsock 2.2 dll初始化成功
客户端命令: 127.0.0.1或者10.104.164.148(并且按enter键)
出现:Winsock 2.2 dll初始化成功
当前时间是:Wed Nov 02 21:17:50 2016(若是输入127.0.0.1则时间结果为:Tue Nov 02 21:17:50) 对方连接关闭,退出
通过对系统进行一系列测试,如上图中服务器程序执行和客户端程序执行同步之前是有时间差的,然后在运行程序后时间同步,变成:Nov 02 21:17:50 2016,从测试结果来看实现了当初的设计目标,系统能够初步完成客户端与服务器的时间同步。

即同步的结果如下:
【实验中出现问题及解决方法】
1)问题1:找不到很多头文件,特别是StdAfx.h头文件?
2)解决方法1:去百度下载很多的安装包,安装plamt SDK,然后就有了这个头文件,本来这个头文件是Linux系统里的,但是windows的VC 6.0++也可以通过添加安装一些软件来添加它。

自己通过在工程里添加头文件和路径。

3)问题2:有很多函数的功能不清楚?
4)解决方法:通过课本的查找和网络资料的查找,然后获得比较清晰的答案。

【思考问题】
会不会产生时延然后使时间不同步?怎么才能缩短客户端查询时间的时间长度?
【实验体会】
在本次编写C/S模型的网络时间同步系统,包括该系统的设计原理,系统结构,实现的方法以及主要代码的编写等,在整个系统的实现过程中发现自己很多方面的不足,比如VC++中网编中的很多函数,及相关的应用场合等等知识的缺乏。

通过这次实验,比较清晰和直观的了解了最基本的流式套接字客户端/服务器通信程序的编程,这不仅仅加深了我对流式套接字的理解,也让我学习到在套接字编程
的过程中,一定要考虑到时间的变化以及影响因素,这样就有可能尽快地找出解决问题的办法,同时使程序更加清晰明了,使得时间延迟保持在一个可以接受的范围内。

成绩优良中及格不及格
教师签名:日期:。

相关文档
最新文档