1

这是出于教育目的(大学作业)。

我需要用 C 语言为 Linux 编写一个客户端-服务器程序。(我已经有了那部分。客户端连接到服务器,它可以毫无问题地发送和接收文件......)。

当客户端连接到服务器时,它会向服务器发送客户端上的文件列表。所以服务器有一个它的客户端上所有文件的列表。

客户端 A 可以向服务器请求文件“test.txt”,服务器知道该文件在客户端 B 上,并且该文件应该从 B 传输到 A。我正在考虑最好的方法这。

  1. 从 B 接收到缓冲区,并立即将缓冲区发送()到 A?
  2. recv() 将 B 中的整个文件保存在服务器上,然后发送给 A?

我的程序应该支持这种行为:如果 A 向 B 询问文件,然后 C 向 B 询问文件,C 不应等到传输 A<-->B 结束。这就是我卡住的地方。

非常感谢你!!

编辑:我的服务器正在使用线程:每当有新客户端连接时,都会打开一个新线程来为其提供服务。目前,我的客户不使用线程(可以更改)。

4

3 回答 3

1

如果您想使用套接字一次进行多次传输,您有两种选择:

阻塞套接字和线程

这就是您编写服务器的方式。线程的问题在于它们可能导致难以调试的错误。将其与本身很难调试的网络错误结合起来,您将面临一个潜在的噩梦般的调试会话。

非阻塞套接字和 select()

这种方式不需要线程,而是使用 select() 来查看哪些套接字有数据等待读取。将其与一些循环结合起来,您可以同时传输多个文件。将套接字设置为非阻塞很容易,使用正确的可能会稍微棘手一些,但考虑到线程+网络错误的可能性,这是我个人更喜欢编写网络代码的方式。

关于您的实际问题;我会建议这样的事情:

Client A connects to server S. You need to bind the local side for the next step.
A also opens another socket for data transfer on the next port upwards.
S sends file list to A. How you build up the file list I leave to you.
A requests file F from S.
S checks which client has F.
S sends "send F to A on port X" to B. You can check which remote port is used, and then you know which port to send the file on.
B recieves and executes the command.
于 2012-12-21T09:34:35.297 回答
0

您必须为每个客户端连接 2 个套接字,因此您将拥有 4 个这样的套接字:

1 A <-> C
2 B <-> C 
3 A <-> C <-> B 4

因此,您将不得不使用套接字 1 和 2 在客户端 A 和服务器 C(套接字 1)之间以及客户端 B 和服务器 C(套接字 2)之间传输文件。

然后,您必须使用套接字 3 和 4 在服务器 C 中开发一个桥接器,以将数据从 A 传输到 B。

我猜多线程解决方案应该可以工作!

于 2012-12-21T09:04:38.200 回答
0

到目前为止我所得到的:服务器仅使用 select() 运行。客户端有一个处于listen() 模式的套接字——称之为dataSocket(在它的常规套接字之上)。如果客户端 A 想要一个文件,它会告诉服务器文件名。服务器通过文件找到用户,并对 dataSocket 进行 connet()。(我设法实现了)。

小文件传输没有问题。大文件失败。

我认为这是因为我的客户出了问题。我已经使用 select() 函数实现了客户端,如果它发现有人在执行 connect(),它会打开一个新线程并为请求提供服务。但是有什么问题。。代码是这样的:

FD_SET(globalSocket,&origin);
FD_SET(dataSocket,&origin);
FD_SET(STDIN,&origin); //#define STDIN 0
while(1)
{
 readfds=origin;
 select(fdmax+1,&readfds,NULL,NULL,NULL);
 for(i=0;...)
  {
   if(FD_ISSET(i,&readfds)
   {
    if(i==STDIN)
     // get user input
    if(i==dataSocket)
     {
      printf("someone wants a file from me");
      pthread_create(...);
     }
   }
  }
}

我看到的一个问题是,当我第一次请求文件时,它会打印 2 或 3 次“有人想要我的文件”这一行,但只创建了一个线程。当我尝试发送一个大文件时,我确实得到了一些文件,但随后弹出“对等连接重置”......

我希望这里有人能够回答我解释得不太好的问题。谢谢你。

于 2012-12-21T18:34:32.827 回答