服务器怎么处理多客户端并发传输文件?

时间:2022-09-12 20:15:59
小弟现在在做一个大约500人组建的局域网内文件传输,局域网内多客户端需要同时上传文件或下载文件。(文件大小200M)
保证多客户端请求能够并发处理,支持断点续传。最主要是稳定。请做过企业内部文件传输系统的大侠们给个意见。

一开始我想用普通的阻塞式socket方式加多线程进行处理的。结果发现多客户端上传文件会比较慢。于是在这一基础上改进了一下。
使用了3个端口
主线程循环检测客户连接(端口1)。每个客户端连接成功后跑到处理线程,处理线程再次创建一个接受线程和发送线程。这两个线程再各自创建两个新的端口(端口2和端口3),并用while循环不断与客户端连接,连接成功后再次创建子线程处理具体的信息传输。那么收发文件的socket就依赖于创建的接受线程和发送线程,主线程那里的socket只是用于发送文件列表信息的。
    服务器大致模型
.....

    SOCKET sock1 = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(6000);  //发送数据的监听端口6000
    addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    bind(sock, (sockaddr *)&addr, sizeof(sockaddr));
    listen(sock, 5);
     while(1)
{
      talk = accpet();
     CreateThread(NULL, 0, RequstProc, (LPVOID)&talk 0, NULL);
 }
.......


RequstProc()
{
    CreateThread(NULL, 0, send, NULL, 0, NULL);
    CreateThread(NULL, 0, recv, NULL, 0, NULL);
}
send()//对应客户端下载操作
{
    SOCKET sock1 = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(7000);  //发送数据的监听端口7000
    addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    bind(sock, (sockaddr *)&addr, sizeof(sockaddr));
    listen(sock, 5);
   while(1)
   {
         talk1 = accpet(sock1 ,NULL,NULL);
         ...
         CreateThread(NULL, 0, sendchild, (LPVOID)&talk1 0, NULL);
         ....
   }
}
sendchild()
{
    //TODO:处理....
}

recv()//对应客户端上传操作
{
    SOCKET sock2 = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8000);  //发送数据的监听端口8000
    addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    bind(sock, (sockaddr *)&addr, sizeof(sockaddr));
    listen(sock, 5);
   while(1)
   {

         talk2 = accpet(sock2 ,NULL,NULL);
          .....
         CreateThread(NULL, 0, recvchild, (LPVOID)&talk2, 0, NULL);
         .....
   }
}
recvchild()
{
    //TODO:处理.....
}


上述工作做完后,运行的时候,发现效率提高了很多,但是总是感觉这样不安全。
网上查看了一下,有人提出使用select(选择)、WSAAsyncSelect(异步选择)、WSAEventSelect(事件选择)、overlapped(重叠)以及completion port(完成端口)等几种模式。我不知道这几种模型的安全性,稳定性优势在哪里。
于是试着写了一个select模式,发现跟我用多线程的差不多。在多客户端并发请求的时候,服务器处理起来差不多。(不知道具体该做哪些全面测试) 
还有就是,完成端口的,由于不怎么熟悉,就没有尝试。
另外,还查到有人使用的FTP传输文件(貌似大文件传输很多人选用FTP)。

请熟悉的大侠们跟我讲一下,我的项目应该选用哪种模式比较稳定,优化。

10 个解决方案

#1


楼主,你所说的不安全是指什么?
1.明码传输不安全
2.还是CreateThread的系统架构不安全,资源访问出问题,容易崩溃
3.系统压力承受问题

#2


不用搞出这么多端口,一个就行了。如果三个端口比一个端口快,这说明的代码有问题。速度慢,那是因为你的服务器磁盘慢,可以使用内存缓冲。

#3


tiger9991,你好!

不安全  主要考虑的是 CreateThread 的系统架构不安全,资源访问出问题,容易崩溃。资源出错的时候没有相应的处理机制,在线程里面,只会一直在发或一直在收。昨天了解了一下FTP协议的模式,FTP的控制端口会处理各种不同的命令,而数据端口则只处理传输文件的事情。对于文件传输过程中的异常或者可能崩溃的情况,会有相应的命令来及时处理,那么我们就不担心一旦出错服务器崩溃的问题。同时提高服务器的容错率。

我现在检测服务器的方式只是多个客户端一直连接,不断传输文件,不知道对于服务器还有没有其他方面的压力测试。比如断线什么的。

#4


zhouzhipen,你好!
三个端口比一个端口快,这说明的代码有问题。对于多端口处理,和单一端口处理,请问下这样的速度是不是一样的。
然后服务器的磁盘慢,可以使用内存缓冲。----是表明我在传输文件中使用的buffer缓冲区其实是磁盘缓冲区,而并不是内存缓冲区么。
需要这样做么:
PoolType* Malloc();
CList<PoolType> m_oMemoryPool; 

#5


该回复于2012-08-15 08:22:05被版主删除

#6


又见此帖,楼主回帖很正式啊,大文件感觉FTP稳定性高。代码写起来也方便。
Thread一个崩溃,主进程就崩溃,这个一直很讨厌。

#7


reactor+epool或iocp

#8


tiger9991,你好!

谢谢关注!我决定使用FTP了。由于之前没有做过大项目,一时之间不该如何选择,查阅了很多资料后,觉得还是使用FTP简单好用,稳定性好!
再次感谢!

#9


求代码参考88651388@qq.com

#10


也想学习一下,可惜没有源代码

#1


楼主,你所说的不安全是指什么?
1.明码传输不安全
2.还是CreateThread的系统架构不安全,资源访问出问题,容易崩溃
3.系统压力承受问题

#2


不用搞出这么多端口,一个就行了。如果三个端口比一个端口快,这说明的代码有问题。速度慢,那是因为你的服务器磁盘慢,可以使用内存缓冲。

#3


tiger9991,你好!

不安全  主要考虑的是 CreateThread 的系统架构不安全,资源访问出问题,容易崩溃。资源出错的时候没有相应的处理机制,在线程里面,只会一直在发或一直在收。昨天了解了一下FTP协议的模式,FTP的控制端口会处理各种不同的命令,而数据端口则只处理传输文件的事情。对于文件传输过程中的异常或者可能崩溃的情况,会有相应的命令来及时处理,那么我们就不担心一旦出错服务器崩溃的问题。同时提高服务器的容错率。

我现在检测服务器的方式只是多个客户端一直连接,不断传输文件,不知道对于服务器还有没有其他方面的压力测试。比如断线什么的。

#4


zhouzhipen,你好!
三个端口比一个端口快,这说明的代码有问题。对于多端口处理,和单一端口处理,请问下这样的速度是不是一样的。
然后服务器的磁盘慢,可以使用内存缓冲。----是表明我在传输文件中使用的buffer缓冲区其实是磁盘缓冲区,而并不是内存缓冲区么。
需要这样做么:
PoolType* Malloc();
CList<PoolType> m_oMemoryPool; 

#5


该回复于2012-08-15 08:22:05被版主删除

#6


又见此帖,楼主回帖很正式啊,大文件感觉FTP稳定性高。代码写起来也方便。
Thread一个崩溃,主进程就崩溃,这个一直很讨厌。

#7


reactor+epool或iocp

#8


tiger9991,你好!

谢谢关注!我决定使用FTP了。由于之前没有做过大项目,一时之间不该如何选择,查阅了很多资料后,觉得还是使用FTP简单好用,稳定性好!
再次感谢!

#9


求代码参考88651388@qq.com

#10


也想学习一下,可惜没有源代码