客户端 - 服务器类似应用程序的线程同步

时间:2012-03-12 13:09:08

标签: c sockets pthreads client-server

我一直致力于文件下载应用程序,其中服务器持续等待来自客户端的新连接请求,当新连接到达时,服务器接受此连接并创建新进程以服务最近连接到服务器的客户端。客户端可以请求从服务器下载多个文件。对于每个文件,客户端和服务器端创建一个新线程,并且应该在服务器和客户端的正确线程对之间执行每个文件的数据传输。我正在为线程使用C和 pthread 。我现在为每个客户端提供稳定的套接字连接和成功的流程创建。

对于线程文件传输器,我尝试如下:

在客户端我正在创建运行接收文件的方法的线程:

        int k;
        for (k = 0; k < fNameCounter; k++)
        {
            pthread_t thread_id;
            int status = pthread_create(&thread_id, NULL, &receiveFile, fName );

            if (status != 0)
            {
                printf("Thread Creation Failed \n");
                exit(0);
            }
        }

同样在服务器端,我创建相同数量的线程,如下所示:

        int k;
        for (k = 0; k < fnameCounter; k++)
        {
            pthread_t thread_id;
            int status = pthread_create(&thread_id, NULL, &sendFile, fName );

            if (status != 0)
            {
                printf("Thread Creation Failed \n");
                exit(0);
            }
        }

sendFile和receiveFile函数只是通过socket写入和读取fName指定的文件的字节(正如你在pthread_create中看到的那样),此时我遇到了一个主要问题:

据我所知,在这个程序中,在所有线程完成从服务器接收数据之后,可能存在文件内容可能不同的问题,因为sendFile和readFile函数只是从套接字读取并写入套接字。

我如何保证,客户的每个线程都从服务器的正确线程中获取正确的数据,如下所述:

        receive         send

cthread1 ---->  a.txt  <-----   sthread1

cthread1 ---->  a.txt  <-----   sthread1

cthread1 ---->  a.txt  <-----   sthread1

P.S。我知道在一个套接字上创建多个线程没有意义,但是,这是我的hw,我需要这样做:/。

问候。

3 个答案:

答案 0 :(得分:1)

最简单的方法是为每个文件打开一个新套接字。

答案 1 :(得分:0)

完成zvrba非常有效的点(一个套接字,一个文件)。

我认为线程在这里没用:你有一张网卡。通过多次监听相同的资源,您将无法获得更快的速度。你实际上可能让你的线程相互阻塞并且实际上更慢。

如果您想向用户提供反馈,那么您可以为所有套接字IO创建一个后台线程。

您应该使用select在同一个线程中处理多个连接,以检测可以读取/写入哪个套接字。

答案 2 :(得分:0)

考虑到只有一个套接字的限制,您可能希望向正在传输的字节添加一些标头信息。此标头可能包含有关哪一对线程负责该信息的信息。

例如,sthread1将从文件a.txt发送100个字节。您可以在该流的开头添加一个字节,其中包含数字1。当收到数据块时,cthread1需要检查第一个字节:如果它是1那么好,这个块用于cthread1,继续处理。如果标题不是1,则cthread1 忽略此块并继续等待,让其他线程也有机会运行。

如果您不识别数据块,则无法确定哪个线程应处理哪个块。

请注意,这会增加很多处理的复杂性:

  1. 您必须决定如何将这些标识符分配给您的线程对
  2. 如果您只使用一个字节,请记住它保留的最大值为255。
  3. 您可能必须在MSG_PEEK内的recv函数中使用标记cthread(因此,如果需要,您可以忽略该块)。此标志会更改函数recv的行为。我建议您阅读this(如果您正在使用Win进行编程)或this(如果您使用的是Linux)。