TCP代理 - 互斥

时间:2015-01-01 18:03:05

标签: c++ 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);

        }
    }
}

感谢您的帮助。 电贺 托比

1 个答案:

答案 0 :(得分:1)

有几点需要改进。

首先:目前还不清楚你想要保护什么。我会理解你是使用一个互斥锁来保护一个缓冲区,而另一个互斥锁是另一个缓冲区,所以每个缓冲区总是只能被一个线程访问。但是,这不会发生 - 两个线程都可以同时读取+写入相同的缓冲区。相反,每个互斥锁同时保护套接字不受读取和写入的影响,这是毫无意义的,因为套接字可以完美地处理它。您可以同时在同一个套接字上读取+写入。套接字用于实现这一目标已有30多年了。

一旦更改并且您的互斥锁保护缓冲区,您将再次遇到阻塞,但不常见。您将体验到一个线程在没有可用的情况下尝试读取或写入数据,或者套接字连接已满(如果您尝试快速写入大量数据,则会发生这种情况)并且传输数据需要时间。

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

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