客户端
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#include <chrono>
#include <sstream>
#include <iomanip>
using namespace std;
using namespace chrono;
int main(int argc, char *argv[])
{
// 创建socket
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd < 0)
{
cerr << "Failed to create socket.\n";
exit(1);
}
// 连接服务器
struct sockaddr_in serv_addr;
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器IP地址
serv_addr.sin_port = htons(8000);
if (connect(sock_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
cerr << "Failed to connect to server.\n";
exit(1);
}
while (true)
{
// 获取当前时间
auto now = std::chrono::system_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
std::stringstream ss;
ss << std::put_time(std::localtime(&now_c), "%Y-%m-%d %H:%M:%S") << "." << std::setfill('0') << std::setw(3) << ms.count();
std::string time_str = ss.str();
// 发送数据
std::string send_buf = time_str + "I am client, 时间发给你了";
int send_len = send(sock_fd, send_buf.c_str(), send_buf.size(), 0);
if (send_len <= 0)
{
cerr << "Failed to send data.\n";
exit(1);
}
// 接收数据
char recv_buf[1024];
int recv_len = recv(sock_fd, recv_buf, 1024, 0);
if (recv_len < 0)
{
cerr << "Failed to receive data.\n";
exit(1);
}
else if (recv_len == 0)
{
cerr << "Connection closed by server.\n";
break;
}
// 处理数据
recv_buf[recv_len] = '\0';
cout << time_str << " 客户端收到的响应: " << recv_buf << endl;
// 延时
sleep(1);
}
close(sock_fd);
return 0;
}
服务端
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#include <chrono>
#include <sstream>
#include <iomanip>
using namespace std;
using namespace chrono;
int main(int argc, char *argv[])
{
// 创建socket
int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0)
{
cerr << "Failed to create socket.\n";
exit(1);
}
// 绑定IP和port
struct sockaddr_in serv_addr;
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 任意IP地址
serv_addr.sin_port = htons(8000);
if (bind(listen_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
cerr << "Failed to bind IP and port.\n";
exit(1);
}
// 监听
if (listen(listen_fd, 20) < 0)
{
cerr << "Failed to listen.\n";
exit(1);
}
cout << "Waiting for incoming connections...\n";
// 接受连接
struct sockaddr_in cli_addr;
socklen_t cli_len = sizeof(cli_addr);
int conn_fd = accept(listen_fd, (struct sockaddr *)&cli_addr, &cli_len);
if (conn_fd < 0)
{
cerr << "Failed to accept connection.\n";
exit(1);
}
char recv_buf[1024];
while (true)
{
// 接收数据
int recv_len = recv(conn_fd, recv_buf, 1024, 0);
if (recv_len < 0)
{
cerr << "Failed to receive data.\n";
exit(1);
}
else if (recv_len == 0)
{
cout << "Connection closed by client.\n";
break;
}
// 获取当前时间
auto now = std::chrono::system_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
std::stringstream ss;
ss << std::put_time(std::localtime(&now_c), "%Y-%m-%d %H:%M:%S") << "." << std::setfill('0') << std::setw(3) << ms.count();
std::string time_str = ss.str();
// 处理数据
recv_buf[recv_len] = '\0';
cout << time_str << "服务端收到的消息: " << recv_buf << endl;
// 发送数据
std::string send_buf = "服务端发送数据";
send_buf = time_str + send_buf;
int send_len = send(conn_fd, send_buf.c_str(), send_buf.size(), 0);
if (send_len <= 0)
{
cerr << "Failed to send data.\n";
exit(1);
}
}
close(listen_fd);
close(conn_fd);
return 0;
}
Makefile文件
CXX = g++ # 指定编译器
CXXFLAGS = -Wall # 编译参数
CXXFLAGS += -std=c++11
# 服务端可执行文件
SERVER = server
# 客户端可执行文件
CLIENT = client
all: $(SERVER) $(CLIENT)
$(SERVER): server.o
$(CXX) $(CXXFLAGS) -o $@ $^
$(CLIENT): client.o
$(CXX) $(CXXFLAGS) -o $@ $^
server.o: server.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
client.o: client.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -rf *.o $(SERVER) $(CLIENT)
编译执行情况:
编译:
$ make clean;make;ls;
rm -rf *.o server client
g++ -Wall -std=c++11 -c server.cpp -o server.o
g++ -Wall -std=c++11 -o server server.o
g++ -Wall -std=c++11 -c client.cpp -o client.o
g++ -Wall -std=c++11 -o client client.o
执行
服务端
$ ./server
Waiting for incoming connections...
客户端
$ ./client
2023-07-04 14:10:54.811 客户端收到的响应: 2023-07-04 14:10:54.812服务端发送数据
2023-07-04 14:10:55.812 客户端收到的响应: 2023-07-04 14:10:55.813服务端发送数据
2023-07-04 14:10:56.813 客户端收到的响应: 2023-07-04 14:10:56.814服务端发送数据
2023-07-04 14:10:57.815 客户端收到的响应: 2023-07-04 14:10:57.815服务端发送数据
2023-07-04 14:10:58.815 客户端收到的响应: 2023-07-04 14:10:58.815服务端发送数据
2023-07-04 14:10:59.816 客户端收到的响应: 2023-07-04 14:10:59.816服务端发送数据
服务端待客户端执行后
$ ./server
Waiting for incoming connections...
2023-07-04 14:10:54.812服务端收到的消息: 2023-07-04 14:10:54.811I am client, 时间发给你了
2023-07-04 14:10:55.813服务端收到的消息: 2023-07-04 14:10:55.812I am client, 时间发给你了
2023-07-04 14:10:56.814服务端收到的消息: 2023-07-04 14:10:56.813I am client, 时间发给你了
2023-07-04 14:10:57.815服务端收到的消息: 2023-07-04 14:10:57.815I am client, 时间发给你了
2023-07-04 14:10:58.815服务端收到的消息: 2023-07-04 14:10:58.815I am client, 时间发给你了
2023-07-04 14:10:59.816服务端收到的消息: 2023-07-04 14:10:59.816I am client, 时间发给你了
Connection closed by client.