此项目的目的是分别编写TCP的客户端和服务端程序并为两者建立通信,客户端收到从服务端发送的服务端本地时间。
此项目在Dev-C++ 5.11下开发,需要用到的库有winsock2.h,以及静态链接文件wsock32.lib。
需要分别创建两个项目server和client,先运行server.cpp,再运行client.cpp。
//server.cpp
#include
#include
#include
#include
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);
}
#include
#include
#include
#include
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;
}
首先运行TCPserver.exe,接着分别运行三次TCPclient.exe(每次运行相当于从服务器获取一次时间),执行结果如下: