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

问题描述 投票:0回答:3

我一直在研究文件下载应用程序,其中服务器不断等待来自客户端的新连接请求,当新连接到达时服务器接受该连接并创建一个新过程来服务最近连接到服务器的客户端。 客户端可以请求从服务器下载多个文件。 对于每个文件,客户端和服务器端都会创建一个新线程,并且每个文件的数据传输应在服务器和客户端的适当线程对之间进行。 我正在使用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函数只是通过套接字写入和读取fName(如在pthread_create中看到的)指定的文件字节,这时我遇到了一个主要问题:

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

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

        receive         send

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

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

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

PS:我知道在一个套接字上创建许多线程没有任何意义,但是,这是我的硬件,我需要以这种方式进行:/。

问候。

c sockets pthreads client-server
3个回答
1
投票

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


0
投票

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

我认为这里的线程没用:您只有一张网卡。 多次收听同一资源不会使您变得更快。 实际上,您的线程很可能相互阻塞,并且实际上速度较慢。

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

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


0
投票

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

例如, sthread1将从文件a.txt发送100个字节。 您可以在该流的开头添加一个字节,其中包含数字1 。 当接收到该数据块时, cthread1需要检查第一个字节:如果它是1那么可以,该块用于cthread1 ,继续进行处理。 this chunk and keep waiting, giving the other threads opportunity to run too. 如果标头不是1 ,则cthread1应该 该块并继续等待,从而使其他线程也有机会运行。

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

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

  1. 您将必须决定如何将这些标识符分配给线程对。
  2. 如果仅使用一个字节,请记住该字节的最大值为255。
  3. 您可能必须在cthread中的recv函数中使用标志MSG_PEEK (因此,如果需要,可以忽略该块)。 该标志改变函数recv的行为。 我建议你阅读 (如果你正在编写在Win)或 (如果你是在Linux上)。
© www.soinside.com 2019 - 2024. All rights reserved.