gpt4 book ai didi

c++ - 多连接套接字c++

转载 作者:行者123 更新时间:2023-11-30 03:26:46 25 4
gpt4 key购买 nike

我正在尝试实现我自己的服务器端和客户端,它们使用套接字发送和接收数据。但是我在实现多线程方面遇到了一些问题。我的server.cpp:

#include <iostream>
#include <netinet/in.h>
#include <cstring>
#include <arpa/inet.h>
#include <unistd.h>
#include <thread>
using namespace std;

void connection_handler(int socket) {
char client_message[256];
memset(&client_message, 0, 256);
size_t message_size = 0;

while ((message_size = recv(socket, client_message, sizeof(client_message) - 1, 0)) > 0) {
client_message[message_size] = '\0';
cout << "[Server] Client message accepted" << endl;
cout << "[Server] Client message: " << client_message << endl;

if (write(socket, client_message, message_size) == -1) {
cout << "[Client] Message sending failed" << endl;
return;
}
cout << "[Server] Message sent to client" << endl << endl;
cout << "============================" << endl << endl;
cout.flush();

memset(&client_message, 0, 256);
}
}

int main() {
unsigned short int PORT = 8080;
int listener, client_socket;
socklen_t client_len;

struct sockaddr_in server_address{};

memset(&server_address, 0, sizeof(server_address));

listener = socket(AF_INET, SOCK_STREAM, 0);

server_address.sin_family = AF_INET;
server_address.sin_port = htons(PORT);
if (inet_aton("127.0.0.1", &server_address.sin_addr) == 0) {
cout << "[Server] Invalid IP address" << endl;
return -1;
}

if (bind(listener, (struct sockaddr*) &server_address, sizeof(server_address)) == -1) {
cout << "[Server] Binding failed" << endl;
return -1;
}
cout << "[Server] All setting are done" << endl;
cout << "[Server] Server enabled" << endl;

if (listen(listener, 100) == -1) {
cout << "[Server] Listening failed" << endl;
return -1;
}
cout << "[Server] Waiting for connection..." << endl;

for (; ;) {
client_socket = accept(listener, (struct sockaddr*) &server_address, &client_len);
cout << "[Server] Connection accepted" << endl << endl;
cout << "----------------------------" << endl << endl;

int new_socket = client_socket;

thread handling_thread(connection_handler, new_socket);
handling_thread.detach();
}
}

我的client.cpp:

#include <iostream>
#include <netinet/in.h>
#include <cstring>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;

int main() {
unsigned short int PORT = 8080;
int sockfd;
char buffer[256] = {0};
struct sockaddr_in server_address{};

sockfd = socket(AF_INET, SOCK_STREAM, 0);

memset(&server_address, '0', sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_port = htons(PORT);
server_address.sin_addr.s_addr = INADDR_ANY;

if (connect(sockfd, (struct sockaddr*) &server_address, sizeof(server_address)) < 0) {
cout << "[Client] Connection failed" << endl;
return -1;
}
cout << "[Client] All setting are done" << endl;
cout << "[Client] Succefully connected to server" << endl << endl;
cout << "----------------------------" << endl << endl;

while (true) {
string client_request;
cout << "[Client] Enter a message: ";
getline(cin, client_request);

if (client_request == "-1") {
write(sockfd, client_request.c_str(), client_request.size());
close(sockfd);
cout << endl << "[Client] Client exited" << endl;
return 0;
}

if (write(sockfd, client_request.c_str(), client_request.size()) == -1) {
cout << "[Client] Message sending failed" << endl;
}
cout << "[Client] Message sent to server" << endl;

memset(&buffer, 0, 256);
read(sockfd, buffer, 256);

cout << "[Client] Server message: " << buffer << endl << endl;
cout << "============================" << endl << endl;
cout.flush();
}
}

在我再创建一个到服务器的连接之前它一直工作正常,然后第二个客户端可以发送和接收数据,但是此时第一个变得不工作了。我这样编译我的程序:g++ server.cpp -lpthread -o server -std=c++11 然后在其他控制台选项卡中运行我编译的 client.cpp:./client。为了检查多线程工作,我再次运行客户端(再次在另一个选项卡中)并尝试同时在两个选项卡中发送请求。我想在我的程序中实现多线程。我该怎么做?

UPD:我正在使用 Linux

UPD2:问题已解决。固定代码。

最佳答案

    int new_socket = client_socket;

thread handling_thread(connection_handler, &new_socket);
handling_thread.detach();
}

这会初始化 new_socket,它会在此 for 循环内的本地范围内声明,然后将指向此 new_socket 的指针传递给开始的新线程,然后分离。紧随其后,此 for 循环迭代结束,这会在开始此循环的下一次迭代之前销毁 new_socket 对象。

与此同时,执行线程反复尝试取消引用它接收到的 int *,它现在指向一个已销毁的对象。这会导致未定义的行为,并且可能是您的程序“不工作”的原因。

最简单的解决方案是使用new 在动态范围内创建int 套接字值,然后将指针传递给这个new ed 套接字值到执行线程。当然,执行线程将负责检索套接字值,然后适本地删除它,以避免内存泄漏。

对于这个简单的程序来说,这应该足够了。为了可靠性,更复杂的程序可能需要稍微复杂一些的套接字和动态范围处理逻辑。

关于c++ - 多连接套接字c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48053306/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com