首页 > 解决方案 > 如何使用 C++ 接受套接字中的并发请求

问题描述

假设我有五台机器(A1A2A3A4B),A1-4它们都是服务器,每台机器都在监听来自客户端的请求,例如B. 现在我只有一个客户B

首先,我使用api并发发送数据,B将并行处理数据。然后他们会将结果数据发送到.A1-4socketA1-4B

// Servers: 
// A1: 192.168.1.101:10001
// A2: 192.168.1.102:10001
// A3: 192.168.1.103:10001
// A4: 192.168.1.104:10001

// Client:
// B: 192.168.1.100

首先,连接到服务器A1-4B发送数据:

SOCKET sockets[4];
for i in range(4):
    sockets[i] = socket(servers[i], ...)
    connect(sockets[i], ...)

char bufdata[bufsize];
std::vector<std::thread> threads;
for i in range(4):
    std::thread t(send_data_and_receive_result, sockets[i], bufdata, ...)
    threads.push_back(t)
for i in range(4):
    if (threads[i].joinable())
        threads[i].join()

然后,在 中A1-4,它们将并行处理数据,例如,在它们中的每一个中:

sock = socket(...)
bind(sock, port=10001, ...)
listen(sock, ...)
while(1) {
    select(...)
    for (int i = 0; i < maxfd; i++) {
        SOCKET s = rread.fd_array[i];
        if (s == sock) {
            new_client = accept(sock, ...)
            FD_SET(new_client, ...)
        } else {
            char recvbuf[bufsize];
            recv(s, recvbuf, ...)
            
            char resultbuf[bufsize];
            process_data(recvbuf, resultbuf);

            // send the resultbuf back to `B` using `s`
            // Error here !!!!!!!!!!!!!!!!
            // `B` cannot obtain the data
            send(s, resultbuf, ...)
        }
    }
}

这样,期望resultbuf在每个线程中都会收到数据B,即期望在send_data_and_receive_result函数中,发送数据后,线程会使用同一个socket对象从每个线程中获取结果数据服务器 ( A1-4)。但是没有收到数据。我不确定问题出在哪里。

之后,我尝试了另一种方法。我还打开了一个新的服务器线程(监听端口是10000B,它可以在其中监听来自其他客户端的套接字请求,例如A1-4. 主要逻辑与上述类似。而不是使用sin send(s, resultbuf, ...),我还在每个中创建一个新的套接字请求A1-4以建立从A1-4to的连接B

// In `B`, the server is listening in port 10000
// In the `send(s, resultbuf, ...)` of `A1-4`
// they will be replaced with the following:
new_socket = socket(B_server_information, port=10000)
connect(new_socket, ...)
send(new_socket, resultbuf, ...)  // send the resultbuf data in a new socket object

在这个试验中,似乎A1-4会同时连接到B10000 的同一个端口。在每个 中A1-4,日志信息都会显示连接成功,并且resultbuf都发送到B。但B会意外退出。我不确定问题出在哪里。

我不确定我是否已经明确我的问题。我希望resultbuf数据将被发送回B使用连接它的同一个套接字。但没有运气。所以我尝试了后一种方法,但仍然没有运气。

所以如果方便的话,请您给一些建议吗?谢谢。

更新

send_data_and_receive_result函数是这样的:

void send_data_and_receive_result(SOCKET sock, char* bufdata, int bufsize) {
    // send data from `B` to servers `A1-4` using the socket object `sock`
    send(sock, bufdata, bufsize, ...)


    std::cout << "begin receiving result data from the server\n"
    char recvbuf[2048];
    char *resultbuf = new char[100000000];
    size_t bytes_read = 0;
    size_t all_bytes_read = 0;

    int total_size = 0;
    while(1) {
        while((bytes_read = recv(sock, recvbuf, 2048)) > 0) {
            if (total_size == 0) {
                total_size = atoi(recvbuf); // in the first recv, I obtain how much data will be sent in this socket
            }

            // copy the current received buf data to the final buf
            memcpy(resultbuf + all_bytes_read, recvbuf, bytes_read);
         
            all_bytes_read += bytes_read;
        }

        if (total_size == all_bytes_read) {// received the data
            break;
        }
    }

    std::cout << "result data is received";
    // save the result data
    ...
    delete[]  resultbuf; resultbuf = nullptr;
}

标签: c++multithreadingsocketsserverconcurrency

解决方案


推荐阅读