实验要求
要求使用流式套接字编程,实现时间同步服务器和客户端,该服务器能够接收客户端的查询请求,获取本地时间,并将结果发送回客户端,客户端将该时间显示出来。
实验代码
运行环境为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;
}