TCP 代理 - 互斥量

TCP proxy - mutex

我想用 C++ 为大学编写一个简单的 TCP 代理。代理与两个线程一起工作,一个从源端口读取并写入目标端口,另一个线程在另一个方向做同样的事情。目的是在将来读取和操作数据包。如果我使用互斥锁锁定端口以在同一端口上进行读写,我会丢失包。你能帮我定位问题吗,因为我已经尝试了很长时间了?

    thread1 = 0;
    thread2 = 0;



    //Client

    struct sockaddr_in address;
    int size;

    if ((create_socket=socket (AF_INET, SOCK_STREAM, 0)) > 0)
        printf ("Socket wurde angelegt\n");
    address.sin_family = AF_INET;
    address.sin_port = htons (PORT);
    inet_aton (IP, &address.sin_addr);
    if (connect ( create_socket, (struct sockaddr *) &address, sizeof (address)) == 0)
        printf ("Verbindung mit dem Server (%s) hergestellt\n", inet_ntoa (address.sin_addr));


    //Server

    socklen_t addrlen;
    struct sockaddr_in address2;
    const int y = 1;
    if ((create_socket2=socket (AF_INET, SOCK_STREAM, 0)) > 0)
        printf ("Socket wurde angelegt\n");
    setsockopt( create_socket2, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int));
    address2.sin_family = AF_INET;
    address2.sin_addr.s_addr = INADDR_ANY;
    address2.sin_port = htons (PORT2);
    if (bind ( create_socket2, (struct sockaddr *) &address2, sizeof (address2)) != 0) {
        printf( "Der Port ist nicht frei – belegt!\n");
    }
    listen (create_socket2, 5);
    addrlen = sizeof (struct sockaddr_in);
    new_socket2 = accept ( create_socket2, (struct sockaddr *) &address2, &addrlen );
    if (new_socket2 > 0)
        printf ("Ein Client (%s) ist verbunden ...\n", inet_ntoa (address2.sin_addr));



    thread apm(apm_gcs);
    thread gcs(gcs_apm);

    apm.join();
    gcs.join();

}


inline void apm_gcs()
{


    while (STOP==FALSE)
    {       
        {
            lock_guard<mutex> lock(tcp60Mutex);
            res = read(create_socket, buffer2, sizeof(buffer2));   // returns after 5 chars have been input 
        }

        {
            lock_guard<mutex> lock(tcp65Mutex);
            write(new_socket2, buffer2, res);
        }
    }
}





inline void gcs_apm()
{

    while (STOP==FALSE)
    { 
        {
            lock_guard<mutex> lock(tcp65Mutex);
            res2 = read(new_socket2, buffer, sizeof(buffer));   // returns after 5 chars have been input 
        }

        {
            lock_guard<mutex> lock(tcp60Mutex);
            write(create_socket, buffer, res2);

        }
    }
}

感谢您的帮助。 问候 托比

有几处需要改进。

首先:不清楚你到底想保护什么。如果您使用一个互斥量来保护一个缓冲区,而使用另一个互斥量来保护另一个缓冲区,我会理解,因此每个缓冲区将始终仅由一个线程访问。然而,这并没有发生——两个线程可以同时读+写同一个缓冲区。相反,每个互斥锁同时保护一个套接字不被读+写,这是没有意义的,因为套接字可以完美地处理它。您可以同时在同一个套接字上读+写。套接字用于此操作已有 30 多年了。

一旦更改并且您的互斥锁保护缓冲区,您将 运行 再次阻塞,尽管频率较低。你会体验到一个线程在 none 可用时尝试读取或写入数据,或者套接字连接已满(如果你试图快速写入大量数据会发生这种情况)并且传输数据需要时间。

这可以通过 select() 或者 poll() 来解决。因此要走的路是:

每个线程使用 select() 或 poll() 来确定它是否可以读取或写入数据。只有在可以的情况下,它才会锁定缓冲区的互斥量,然后读取或写入数据(在 select() 或 poll() 确定后不会阻塞),然后释放互斥量。