Windows下基于流式套接字的时间同步服务器设计源码

使用流式套接字编程,实现时间同步服务器,该服务器能够接受客户端的查询请求,获取本地时间,并将结果发送回客户端,同时开发与服务器通信的客户端,以验证双方交互的功能。这个可以实现网络中需要时间信号的设备如计算机、控制器等与标准时间源自动、定期的同步本机标准时间。

下面分别是服务器和客户端的源码:

服务器:

// DayTimeServer.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <time.h>
#include "Winsock2.h"
#include "stdio.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;

	//初始化Windows Sockets DLL,协商版本号
    WORD wVersionRequested;
    WSADATA wsaData;
    // 使用 MAKEWORD(lowbyte, highbyte) 宏,在Windef.h 中声明
    wVersionRequested = MAKEWORD(2, 2);
    iResult = WSAStartup(wVersionRequested, &wsaData);
    if (iResult != 0) {
        //告知用户无法找到合适可用的Winsock DLL
        printf("WSAStartup 函数调用错误,错误号: %d\n", WSAGetLastError());
        return -1;
    }
    // 确认WinSock Dll支持版本2.2
    // 注意,如果DLL支持的版本比2.2更高,根据用户调用前的需求,仍然返回2.2版本号,存储于wsaData.wVersion
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
        // 告知用户无法找到可用的WinSock DLL.                              
        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;
    }

	//设置服务器为监听状态,监听队列长度为LISTENQ
    iResult = listen(ListenSocket, LISTENQ);
	if (iResult == SOCKET_ERROR){
		printf("listen 函数调用错误,错误号: %d\n", WSAGetLastError());
		closesocket(ListenSocket); 
	    WSACleanup();
        return -1;
    }

	for ( ; ; ) 
	{
		// 接受客户端连接请求,返回连接套接字ClientSocket 
		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;
}

客户端:

// DayTime.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include "Winsock2.h"
#include "stdio.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;
	}

    //初始化Windows Sockets DLL,协商版本号
    WORD wVersionRequested;
    WSADATA wsaData;
    // 使用 MAKEWORD(lowbyte, highbyte) 宏,在Windef.h 中声明
    wVersionRequested = MAKEWORD(2, 2);
    iResult = WSAStartup(wVersionRequested, &wsaData);
    if (iResult != 0) {
        //告知用户无法找到合适可用的Winsock DLL
        printf("WSAStartup 函数调用错误,错误号: %d\n", WSAGetLastError());
        return -1;
    }
    // 确认WinSock Dll支持版本2.2
    // 注意,如果DLL支持的版本比2.2更高,根据用户调用前的需求,仍然返回2.2版本号,存储于wsaData.wVersion
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
        // 告知用户无法找到可用的WinSock DLL.                              
        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;
}



  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值