|
|
@ -1,6 +1,8 @@
|
|
|
|
#include <iostream>
|
|
|
|
#include <iostream>
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
#include <thread>
|
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
#include <mutex>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <unistd.h>
|
|
|
@ -8,65 +10,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
#define BUFFER_SIZE 1024
|
|
|
|
#define BUFFER_SIZE 1024
|
|
|
|
|
|
|
|
|
|
|
|
void connect_to_gateway(const std::string& ip, int port) {
|
|
|
|
std::vector<std::thread> threads; // 存储所有连接线程
|
|
|
|
|
|
|
|
std::map<int, int> sockets; // 存储套接字
|
|
|
|
|
|
|
|
std::mutex sockets_mutex; // 用于同步访问 sockets
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 维护连接的函数
|
|
|
|
|
|
|
|
void KeepConnection(int sock) {
|
|
|
|
|
|
|
|
char buffer[BUFFER_SIZE];
|
|
|
|
|
|
|
|
int nbytes;
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
|
|
|
nbytes = recv(sock, buffer, BUFFER_SIZE, 0);
|
|
|
|
|
|
|
|
if (nbytes <= 0) {
|
|
|
|
|
|
|
|
std::cout << "Gateway disconnected" << std::endl;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cout << "Received from gateway (Socket " << sock << "): " << buffer << std::endl;
|
|
|
|
|
|
|
|
// 可以添加更多的处理逻辑
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
std::lock_guard<std::mutex> lock(sockets_mutex);
|
|
|
|
|
|
|
|
sockets.erase(sock); // 从集合中移除套接字
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
close(sock);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 连接到网关的函数
|
|
|
|
|
|
|
|
void ConnectToGateway(const std::string& ip, int port) {
|
|
|
|
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
|
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
|
if (sock == -1) {
|
|
|
|
if (sock < 0) {
|
|
|
|
std::cerr << "Could not create socket" << std::endl;
|
|
|
|
perror("Could not create socket");
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct sockaddr_in server_addr;
|
|
|
|
struct sockaddr_in server_addr;
|
|
|
|
server_addr.sin_family = AF_INET;
|
|
|
|
server_addr.sin_family = AF_INET;
|
|
|
|
server_addr.sin_port = htons(port);
|
|
|
|
server_addr.sin_port = htons(port);
|
|
|
|
|
|
|
|
if (inet_pton(AF_INET, ip.c_str(), &server_addr.sin_addr) <= 0) {
|
|
|
|
if (inet_aton(ip.c_str(), &server_addr.sin_addr) == 0) {
|
|
|
|
perror("Invalid address");
|
|
|
|
std::cerr << "Invalid IP address" << std::endl;
|
|
|
|
|
|
|
|
close(sock);
|
|
|
|
close(sock);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
|
|
|
|
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
|
|
|
|
std::cerr << "Connection to the server failed" << std::endl;
|
|
|
|
perror("Connection to the server failed");
|
|
|
|
close(sock);
|
|
|
|
close(sock);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::cout << "Connected to gateway at " << ip << ":" << port << std::endl;
|
|
|
|
{
|
|
|
|
|
|
|
|
std::lock_guard<std::mutex> lock(sockets_mutex);
|
|
|
|
char buffer[BUFFER_SIZE];
|
|
|
|
sockets[sock] = 1; // 将套接字添加到集合中
|
|
|
|
// 发送测试消息
|
|
|
|
|
|
|
|
std::string message = "Hello, Gateway!";
|
|
|
|
|
|
|
|
if (send(sock, message.c_str(), message.size(), 0) < 0) {
|
|
|
|
|
|
|
|
std::cerr << "Send failed" << std::endl;
|
|
|
|
|
|
|
|
close(sock);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 接收网关响应
|
|
|
|
std::cout << "Connected to gateway at " << ip << ":" << port << " (Socket " << sock << ")" << std::endl;
|
|
|
|
int nbytes = recv(sock, buffer, BUFFER_SIZE, 0);
|
|
|
|
|
|
|
|
if (nbytes < 0) {
|
|
|
|
|
|
|
|
std::cerr << "Recv failed" << std::endl;
|
|
|
|
|
|
|
|
} else if (nbytes == 0) {
|
|
|
|
|
|
|
|
std::cout << "Gateway disconnected" << std::endl;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
std::cout << "Gateway said: " << buffer << std::endl;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
close(sock);
|
|
|
|
// 在新线程中维护连接
|
|
|
|
|
|
|
|
threads.emplace_back(KeepConnection, sock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
int main() {
|
|
|
|
std::string ip;
|
|
|
|
std::string command, ip;
|
|
|
|
int port;
|
|
|
|
int port;
|
|
|
|
|
|
|
|
bool connecting = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
|
|
|
std::cout << "Enter command (connect/exitconnect/exit): ";
|
|
|
|
|
|
|
|
std::cin >> command;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (command == "connect") {
|
|
|
|
|
|
|
|
connecting = true;
|
|
|
|
std::cout << "Enter the gateway IP address: ";
|
|
|
|
std::cout << "Enter the gateway IP address: ";
|
|
|
|
std::cin >> ip;
|
|
|
|
std::cin >> ip;
|
|
|
|
std::cout << "Enter the gateway port: ";
|
|
|
|
std::cout << "Enter the gateway port: ";
|
|
|
|
std::cin >> port;
|
|
|
|
std::cin >> port;
|
|
|
|
|
|
|
|
ConnectToGateway(ip, port);
|
|
|
|
|
|
|
|
} else if (command == "exitconnect") {
|
|
|
|
|
|
|
|
connecting = false;
|
|
|
|
|
|
|
|
std::cout << "Exiting connect mode." << std::endl;
|
|
|
|
|
|
|
|
} else if (command == "exit") {
|
|
|
|
|
|
|
|
if (connecting) {
|
|
|
|
|
|
|
|
// 等待所有连接线程结束
|
|
|
|
|
|
|
|
for (auto& thread : threads) {
|
|
|
|
|
|
|
|
thread.join();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 清空线程向量
|
|
|
|
|
|
|
|
threads.clear();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cout << "Exiting program." << std::endl;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
std::cout << "Unknown command" << std::endl;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 多线程连接网关
|
|
|
|
// 关闭所有套接字
|
|
|
|
std::thread client_thread(&connect_to_gateway, ip, port);
|
|
|
|
for (auto& sock_pair : sockets) {
|
|
|
|
client_thread.join(); // 等待连接完成
|
|
|
|
close(sock_pair.first);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
sockets.clear();
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|