接手一个程序,是关于文件传输的。
服务器和客户端原来都是用Delphi写的,服务器的源代码没有,只有客户端的源代码。看了客户端的代码的实现的特点:
1、每个客户端最大可以有24个跟服务器的通信请求,都是用的TCP。
2、客户端首先开一个Socket1连接到服务器POR1,连接上后发送请求命令字查
询服务器端的文件列表,由服务器返回列表结果;根据返回的结果再用
Socket1发送命令字请求传输文件列表中的某个文件,然后再开一个Socket2来
连接到服务器PORT2,连接后用Socket2来接收文件数据。
3、所有的命令字都在Socket1上进行,并且命令字请求的发送次数不多,
Socket2只负责接收文件数据。
4、根据上述,每个客户端就会有24*2=48个Socket同时在线。负载特点:
1、每个文件的平均大小在200M左右。
2、不超过16个客户端。现在由于服务器端不能满足一些要求,需要用VC重新写一个新的服务器,要与
现在的客户端兼容。初步设计如下:
1、服务器开2个线程分别侦听PORT1和PORT2端口。
2、在PORT1上有连接请求后开启一个线程接收该连接上发来的命令字,处理请
求并返回结果,继续等待接收命令字。
3、在PORT2上有连接后再开启一个线程来进行文件传输,直到文件传输完毕或
者客户端发送中止传输的命令请求。俺估计原来的服务器端也是这么写的(只是估计)。初步一看,这个思路很简单,但是效率上个人觉得不怎么样。因为要是客户端
太多的话,服务器要开的线程就太多了。最大要16*48=768个线程,不可思议了。要怎么样设计才更加合理呢??欢迎各位老大指点!谢谢!

解决方案 »

  1.   

    可以考虑用异步socket处理来命令,所有命令socket由一个线程处理
      

  2.   

    ftp就是这样的。server 不要用一连接一线程,有很多IO模型的
      

  3.   

    谢谢各位!
    看了一些帖子,现在确定用IOCP,但对IOCP不熟悉,所以学习了几天。
    命令Socket应该可以容易用IOCP实现,但对于文件传输Socket,因为数据量比较大,还有一个读取文件的问题,读取文件也是很耗时间的,所以估计还是要开一个单独的线程来实现,这样,线程数量还是很大。
      

  4.   

    文件传输只能用开线程的方法把其他通信用udp ,也没有必要用iocp
      

  5.   

    谢谢各位!
    关于IOCP,俺有几个疑问:
    1、IOCP的工作者线程里只是对IO的结果进行处理,在另外的一个发送线程里对Socket进行WSASend的操作,但是由于该IO操作不能立即完成,使得不能继续投递Send,如何解决这个问题?
    比如说:发送线程里WSASend投递了1024Byte,但是在IO线程里GetQueuedCompletionStatus返回时实际上只是发送了1000Byte,还有24Byte没有成功,是不是要在发送线程里等待,直到在IO线程里继续投递了该24Byte后才能在发送线程里继续WSASend?
    2、在双方都没有WSASend和WSARecv的情况下,在客户端用shutdown和closesocket断开连接,服务器如何才能知道客户端已经断开?经测试,在这种情况下GetQueuedCompletionStatus并没有返回。
    当然,在这种情况下,在发送线程里投递WSASend的话可以直接得到WSAECONNRESET或者WSAESHUTDOWN的错误代码。
    3、我只是在WSAAccept的时候投递了一个WSARecv,之后有数据到达时在IO线程里GetQueuedCompletionStatus返回后,若在这时不再投递WSARecv,往后的数据也都能正常接收;若在这时直接在这里继续投递WSARecv,则之后就不断的有GetQueuedCompletionStatus返回,而且此时I第二个参数显示传输了0个Byte,这是为什么?因为俺看到很多其他的例子代码都可以在这里直接投递WSARecv,而俺的就不可以,要正常接收数据到底这里该不该直接投递?
      

  6.   

    不要害怕线程
    想想UNIX中,很多服务是一连接FORK开个进程,那不是更加可怕?
    事实上是
    现在的线程切换技术已经非常成熟,
    一个线程切换需要的CPU指令是1600-2000,
    而目前随便一个CPU的都是上1000 MHZ的的,这是什么概念?  
    我用自己写的线程池,每个连接一个线程,普通PC都可以支持到1600个在线
    事实上最消耗资源的不是线程切换,而是消息系统加界面
    所以如果是单纯的SERVICE,还是写成NT SERVER好了
    界面对资源的占用不是一点点,而是大部分