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

实验要求

要求使用流式套接字编程,实现时间同步服务器和客户端,该服务器能够接收客户端的查询请求,获取本地时间,并将结果发送回客户端,客户端将该时间显示出来。

请求
当前时间
客户
服务器

实验代码

运行环境为vs2017

客户端(client)

#include "pch.h"
#include <iostream>
#include<stdio.h>
#include<winsock2.h>

#pragma comment(lib,"ws2_32.lib")//引入动态链接库

#define MAXLINE 4096//最大缓冲区
#define SEVER_PORT 13131//目标端口
#define sever_ip "127.0.0.1"//本机ip


int main()
{

	int res;
	char recv_data[MAXLINE + 1];//接收缓冲区

	//初始化socket
	WORD w_version = MAKEWORD(2, 2);
	WSADATA wsa_data;
	res = WSAStartup(w_version, &wsa_data);
	if (res != 0)
	{
		printf("%d WSAStartup Error!\n", WSAGetLastError());
		WSACleanup();
		return -1;
	}
	if (LOBYTE(wsa_data.wVersion) != 2 || HIBYTE(wsa_data.wVersion) != 2)
	{
		printf("Version Error!\n");
		WSACleanup();
		return -1;
	}

	//设置套接字的类型、目的ip、目的端口
	sockaddr_in sever_addr;
	memset(&sever_addr, 0, sizeof(sever_addr));
	sever_addr.sin_family = AF_INET;
	sever_addr.sin_addr.S_un.S_addr = inet_addr(sever_ip);
	sever_addr.sin_port = htons(SEVER_PORT);

	//创建流式套接字
	SOCKET sock_conn = socket(AF_INET, SOCK_STREAM,0);
	if (sock_conn == INVALID_SOCKET)
	{
		printf("%d Socket Error!\n", WSAGetLastError());
		WSACleanup();
		return -1;
	}

	//发送链接请求
	res = connect(sock_conn, (sockaddr*)&sever_addr, sizeof(sever_addr));
	if (res == SOCKET_ERROR)
	{
		printf("%d Connect Error!\n", WSAGetLastError());
		WSACleanup();
		return -1;
	}

	//缓冲区清空
	memset(recv_data, 0, sizeof(recv_data));
	//数据发送结束,调用shutdown()函数生命不再发送数据,此时客户端仍可以接收数据
	res = shutdown(sock_conn, SD_SEND);
	if (res == SOCKET_ERROR)
	{
		printf("%d Shutdown Error!\n", WSAGetLastError());
		closesocket(sock_conn);
		WSACleanup();
		return -1;
	}
	printf("Recv Data Is:");

	//循环接收
	do
	{
		res = recv(sock_conn, recv_data, MAXLINE, 0);
		if (res > 0)
		{
			printf("%s\n", recv_data);
		}
		else
		{
			if (res == 0)
			{
				printf("Sever is closed!\n");
			}
			else
			{
				printf("%d Recv Error!\n", WSAGetLastError());
			}
		}

	} while (res > 0);

	closesocket(sock_conn);
	WSACleanup();

	system("pause");
	return 0;

}

服务器(sever)

#include "pch.h"//vs中自带的头文件,其他编译器可去掉
#include <iostream>
#include<stdio.h>
#include<stdlib.h>
#include<winsock2.h>
#include<time.h>
#include<string.h>

#pragma comment(lib,"ws2_32.lib")//引入动态链接库

#define MAXLINE 4096//接收缓冲区长度
#define LISTENQ 1024//监听队列的长度
#define SEVER_PORT 13131//服务器端口

int main()
{
	SOCKET sock_conn=INVALID_SOCKET;
	char buff[MAXLINE];//定义接收缓冲区
	time_t ticks;
	int res;
	//初始化套接字、协议版本号
	WORD w_version = MAKEWORD(2, 2);
	WSADATA wsa_data;

	res = WSAStartup(w_version, &wsa_data);
	if (res != 0)
	{
		printf("%d WSAStartup Error!\n", WSAGetLastError());
		WSACleanup();
		return -1;
	}
	if (LOBYTE(wsa_data.wVersion) != 2 || HIBYTE(wsa_data.wVersion) != 2)
	{
		printf("%d Version Error!\n", WSAGetLastError());
		WSACleanup();
		return -1;
	}

	//设置地址
	sockaddr_in sever_addr;
	memset(&sever_addr, 0, sizeof(sever_addr));
	sever_addr.sin_family = AF_INET;
	sever_addr.sin_addr.s_addr = htonl(INADDR_ANY);//转为网络字节序,32位
	sever_addr.sin_port = htons(SEVER_PORT);//转为网络字节序,16位

	//创建套接字
	SOCKET sock_listen = socket(AF_INET, SOCK_STREAM, 0);
	if (sock_listen == INVALID_SOCKET)
	{
		printf("%d Socket Error!\n",WSAGetLastError());
		closesocket(sock_listen);
		WSACleanup();
		return -1;
	}
	//绑定本机地址和端口号
	res = bind(sock_listen, (struct sockaddr*)&sever_addr, sizeof(sever_addr));
	if (res == SOCKET_ERROR)
	{
		printf("%d Bind Error!\n", WSAGetLastError());
		closesocket(sock_listen);
		WSACleanup();
		return -1;
	}

	//设置监听套接字,最长队列是LISTENQ
	res = listen(sock_listen, LISTENQ);
	if (res == SOCKET_ERROR)
	{
		printf("%d Listen Error!\n", WSAGetLastError());
		closesocket(sock_listen);
		WSACleanup();
		return -1;
	}
	
	//循环服务器
	while (true)
	{
		//接受客户端请求
		sock_conn = accept(sock_listen, nullptr, nullptr);
		if (sock_conn == INVALID_SOCKET)
		{
			printf("%d Accept Error!\n", WSAGetLastError());
			closesocket(sock_listen);
			WSACleanup();
			return -1;
		}

		ticks = time(nullptr);
		time(&ticks);
		memset(buff, 0, sizeof(buff));//清空缓冲区
		strcpy(buff, ctime(&ticks));
		printf("Now time is: %s", buff);

		//发送数据
		res = send(sock_conn, buff, (int)strlen(buff), 0);
		if (res == SOCKET_ERROR)
		{
			printf("%d Send Error!\n", WSAGetLastError());
			closesocket(sock_conn);
			WSACleanup();
			return -1;
		}
		printf("Send Time Data Successfully!\n");

		res = shutdown(sock_conn, SD_SEND);
		if (res == SOCKET_ERROR)
		{
			printf("%d Shutdown Error!\n", WSAGetLastError());
			closesocket(sock_conn);
			WSACleanup();
			return -1;
		}

		closesocket(sock_conn);
		printf("Server Disconnect!\n");
	}
	closesocket(sock_listen);
	WSACleanup();

	return 0;
}
发布了17 篇原创文章 · 获赞 16 · 访问量 1188

猜你喜欢

转载自blog.csdn.net/XYshaonianhaofang/article/details/103154367