Files
front_linux/Linux_Hello/client.cpp
2025-06-13 11:29:59 +08:00

127 lines
3.7 KiB
C++

#include <uv.h>
#include <iostream>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <thread>
#include <mutex>
#include <chrono>
#include <iomanip>
#include <sstream>
#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - offsetof(type, member)))
const int MAX_CONNECTIONS = 300;
const int MAX_MESSAGE_SIZE = 1024 * 1024; // 1MB
struct Client {
uv_tcp_t handle;
uv_connect_t connect_req;
uv_write_t write_req;
std::string server_ip;
int server_port;
bool connected;
std::mutex mutex;
};
std::vector<Client*> clients;
uv_loop_t* loop;
void on_write(uv_write_t* req, int status) {
Client* client = container_of(req, Client, write_req);
if (status < 0) {
std::cerr << "Write error: " << uv_strerror(status) << std::endl;
uv_close((uv_handle_t*)&client->handle, nullptr);
}
}
void on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
Client* client = container_of(stream, Client, handle);
if (nread < 0) {
std::cerr << "Read error: " << uv_strerror(nread) << std::endl;
uv_close((uv_handle_t*)&client->handle, nullptr);
free(buf->base);
return;
}
if (nread > 0) {
std::cout << "Received " << nread << " bytes from server" << std::endl;
}
free(buf->base);
}
void on_connect(uv_connect_t* req, int status) {
Client* client = container_of(req, Client, connect_req);
if (status < 0) {
std::cerr << "Connect error: " << uv_strerror(status) << std::endl;
uv_close((uv_handle_t*)&client->handle, nullptr);
return;
}
client->connected = true;
std::cout << "Connected to server: " << client->server_ip << ":" << client->server_port << std::endl;
// Get the client's IP and port
struct sockaddr_in addr;
int addr_len = sizeof(addr);
uv_tcp_getpeername(&client->handle, (struct sockaddr*)&addr, &addr_len);
char client_ip[INET_ADDRSTRLEN];
uv_ip4_name((const struct sockaddr_in*)&addr, client_ip, INET_ADDRSTRLEN);
int client_port = ntohs(addr.sin_port);
// Prepare message with client's IP and port
std::stringstream ss;
ss << "Client IP: " << client_ip << ", Port: " << client_port;
std::string message = ss.str();
// Send the message
uv_buf_t buf_list = uv_buf_init(const_cast<char*>(message.c_str()), message.size());
uv_write(&client->write_req, (uv_stream_t*)&client->handle, &buf_list, 1, on_write);
uv_read_start((uv_stream_t*)&client->handle, [](uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
buf->base = (char*)malloc(suggested_size);
buf->len = suggested_size;
}, on_read);
}
void start_client(Client* client) {
struct sockaddr_in addr;
uv_ip4_addr(client->server_ip.c_str(), client->server_port, &addr);
uv_tcp_init(loop, &client->handle);
uv_tcp_connect(&client->connect_req, &client->handle, (const struct sockaddr*)&addr, on_connect);
}
void run_client_thread(Client* client) {
start_client(client);
uv_run(loop, UV_RUN_DEFAULT);
}
int main2() {
loop = uv_default_loop();
// Create and start 300 clients
for (int i = 0; i < MAX_CONNECTIONS; ++i) {
Client* client = new Client;
client->server_ip = "172.22.128.1"; // Replace with your server IP
client->server_port = 8098; // Replace with your server port
client->connected = false;
std::thread client_thread(run_client_thread, client);
client_thread.detach();
clients.push_back(client);
}
// Handle shutdown or other logic here
while (true) {
// You can add logic to handle client connections, messages, etc.
// For example, sending data periodically or handling disconnects.
uv_run(loop, UV_RUN_ONCE);
}
return 0;
}