2012-03-12 189 views
0

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

对于线程文件transer,我曾尝试如下:

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

 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 

附:我知道在一个套接字上创建多个线程并不合理,但是,这是我的工作,我需要这样做:/。

问候。

回答

1

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

0

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

我认为这里的线程没用:你有一张网卡。通过多次收听同一资源,您不会变得更快。你实际上可能会让你的线程彼此阻塞,而且实际上会变慢。

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

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

+0

实际上,这是一个课程项目,因此我需要这样做。此外,我知道使用线程是毫无意义的,因为我将为每个客户端提供一个套接字,但我没有选择:)并且真的陷入了同步问题。 – StM 2012-03-12 13:26:34

+0

请编辑您的问题以使您的约束更加清晰:使用单个套接字和两侧的多个线程并行发送多个文件。提及这是一项任务,而且这种条件无论如何效率都不可谈判。 – 2012-03-12 13:31:40

0

考虑到仅限一个套接字的限制,您可能需要为正在传输的字节添加一些标头信息。这个头文件可能包含有关哪一对线程负责那一点信息的信息。

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

如果您没有识别您的数据块,将无法确定哪个线程应该处理哪个块。

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

  1. 你将不得不决定如何将这些标识符分配到双线程
  2. 如果只使用一个字节,请请注意,它所能容纳的最大值为255.
  3. 您可能必须在函数中使用recv函数中的标志MSG_PEEK(因此如果需要,您可以忽略该块)。该标志改变了功能recv的行为。我建议你阅读this(如果你在Win上编程)或this(如果你在Linux上)。