Introducción
El propósito de este proyecto es escribir programas de servidor y cliente TCP por separado y establecer comunicación entre los dos, y el cliente recibe la hora local del servidor enviada desde el servidor.
alrededores
Este proyecto se desarrolla bajo Dev-C ++ 5.11. Las bibliotecas necesarias son winsock2.hy el archivo de enlace estático wsock32.lib.
Necesita crear dos proyectos, servidor y cliente por separado, primero ejecute server.cpp y luego ejecute client.cpp.
Programa de servidor
//server.cpp
#include<winsock2.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void errexit(const char*, ...);//错误信息打印函数
void TCPdaytimed(SOCKET);//将本地时间通过连接套接字发送
SOCKET passiveTCP(const char*, int);//创建服务端的监听套接字
#define QLEN 5 //客户端请求连接队列的最大长度
#define WSVERS MAKEWORD(2, 0)
int main(int argc, char* argv[]) {
struct sockaddr_in fsin;
const char* service = "daytime";//服务名称,在此程序中只作为参考不会被使用
SOCKET msock, ssock;
int alen;
WSADATA wsadata;
switch (argc) {
case 1 :
break;
case 2:
service = argv[1];
break;
default:
errexit("usage: TCPdaytimed [port]\n");
}
if (WSAStartup(WSVERS, &wsadata) != 0) {
errexit("WSAStartup failed\n");
}
msock = passiveTCP(service, QLEN);
while (1) {
alen = sizeof(struct sockaddr);
ssock = accept(msock, (struct sockaddr*) &fsin, &alen);
if (ssock == INVALID_SOCKET) {
errexit("accept failed: error number %d\n", GetLastError());
}
TCPdaytimed(ssock);
(void)closesocket(ssock);
}
}
void TCPdaytimed(SOCKET fd) {
char* pts;
time_t now;
(void)time(&now);
pts = ctime(&now);
(void)send(fd, pts, strlen(pts), 0);
printf("%s", pts);
}
SOCKET passiveTCP(const char* service, int qlen) {
SOCKET sockfd;
struct sockaddr_in sock_address;
sockfd = socket(AF_INET, SOCK_STREAM, 0); //获得fd
sock_address.sin_family = AF_INET; //设置地址家族
sock_address.sin_port = htons(23456); //设置端口
sock_address.sin_addr.s_addr = inet_addr("127.0.0.1"); //设置地址
int temp = bind(sockfd, (struct sockaddr*) & sock_address, sizeof(struct sockaddr));
if (temp != 0) errexit("bind falied.\n");
temp = listen(sockfd, qlen);
if (temp != 0) errexit("listen falied.\n");
return sockfd;
}
void errexit(const char *format, ...) {
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
WSACleanup();
exit(1);
}
Programa cliente
#include<winsock2.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void TCPdaytime(const char*, const char*); //主程序,从指定的服务器节点获取服务器的本地时间
void errexit(const char*, ...);
SOCKET connectTCP(const char*, const char*);//被TCPdaytime调用,创建连接到服务器的套接字
#define LINELEN 128
#define WSVERS MAKEWORD(2,0)
int main(int argc, char* argv[]) {
const char * host = "127.0.0.1";
const char* service = "daytime";
WSADATA wsadata;
switch (argc) {
case 1:
host = "localhost";
break;
case 3:
service = argv[2];
case 2:
host = argv[1];
break;
default:
fprintf(stderr, "usage: TCPdaytime [host [port]]\n");
exit(1);
}
if (WSAStartup(WSVERS, &wsadata) != 0) {
errexit("WSAStartup failed\n");
}
TCPdaytime(host, service);
WSACleanup();
printf("按任意键继续...");
getchar();
return 0;
}
void TCPdaytime(const char* host, const char* service) {
char buf[LINELEN + 1];
SOCKET s;
int cc;
s = connectTCP(host, service);
cc = recv(s, buf, LINELEN, 0);
while (cc != SOCKET_ERROR && cc > 0) {
buf[cc] = '\0';
(void)fputs(buf, stdout);
cc = recv(s, buf, LINELEN, 0);
}
closesocket(s);
}
void errexit(const char* format, ...) {
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
WSACleanup();
exit(1);
}
SOCKET connectTCP(const char* host, const char* service) {
SOCKET sockfd;
struct sockaddr_in mysock;
sockfd = socket(AF_INET, SOCK_STREAM, 0); //获得fd
mysock.sin_family = AF_INET; //设置地址家族
mysock.sin_port = htons(23456); //设置端口
mysock.sin_addr.s_addr = inet_addr("127.0.0.1"); //设置地址
connect(sockfd, (struct sockaddr*) & mysock, sizeof(struct sockaddr));
return sockfd;
}
correr
Primero ejecute TCPserver.exe y luego ejecute TCPclient.exe tres veces (cada ejecución equivale a obtener tiempo del servidor), los resultados de la ejecución son los siguientes: