比如一个socket连续发出两个wsasend,这个时候感觉就有了问题,如果不能的话,那么如何连续发送大量数据?

解决方案 »

  1.   

    比如一个socket连续发出两个wsasend
    ----------------------发起一万个wsasend都没问题。
      

  2.   

    关键是有具体问题你没有考虑到
    比如连续两个wsasend,第一个发送a字节,第二个发送b字节,连续调用两次wsasend
    关键是第一个发送a字节,不一样全部都发出去了,可能只发送了c字节(c<a),这样不来是发送a字节再发送b字节,结果成了发送c,b,a-c字节,这个怎么办?
      

  3.   

    只要你能管理好内存,每次使用的都是一个新的OVERLAPPEDEX,那么就完成是可行的,但是必须考虑一种情况,也就是每次投递出去N个字节未必就能一次性全部提交成功,那样的话,如果你提交了多次的WSASend,则可能会出现比如前一个发送的是:10个0,接着下一个发送的是10个1,而你第一次提交成功了5个0,接着第二个提交的全部成功,而你第一个提次的须执行第二次提交,则会得到结果:00000111111111100000,而不是原本想要的:00000000001111111111.
      

  4.   

    需要针对不同的Per IO Context.如果做到这点就没问题。不过投递过多未决的IO并不好。
      

  5.   

    当然,可能本需要缓存一下数据。总不可能一股脑的塞给Socket吧。
      

  6.   

    各位没有解决我的问题,只好不给分,我最后的解决方法还是无论读写只投递一个,之所以要问这个问题,是因为我发现如果在疯狂发送数据的情况下,如果一次只投递一个的话,会造成本地数据的堆积,这个问题只好先放一放了
    ===========================
    即便是你使用了WSASend,也同样会堆积,如果你在你的主线程当中堆积等待,那么一次性只堆积一个连接的N个包,但是一旦你是M个连接这样子提交给socket,那么在底层堆积则是N*M个包.另外我现在的处理方式是给每个连接加一个发送樗,如果正在发送则追加到发送缓冲区后面(使用链式结构).
      

  7.   

    to unsigned 
    问题不在于此,如果对于阻塞线程,可以直接用send发送,除非下层缓冲耗尽了(这种情况如果不是网络另一端有问题,很少出现).但是如果自己在上层缓冲,则可能被缓冲数据由多个线程操作,操作的时候必然要互斥,这一去一来的消耗系统非常大,包就累积起来.我刚好做了这样的一个程序碰到这种情况了.
      

  8.   

    to unsigned 
    问题不在于此,如果对于阻塞线程,可以直接用send发送,除非下层缓冲耗尽了(这种情况如果不是网络另一端有问题,很少出现).但是如果自己在上层缓冲,则可能被缓冲数据由多个线程操作,操作的时候必然要互斥,这一去一来的消耗系统非常大,包就累积起来.我刚好做了这样的一个程序碰到这种情况了.
    =================================================================
    阻塞线程是什么?
    在上层缓冲是有界定性的,也就是针对一个客户一个缓冲链,一客户最多也不过是两个线程(考虑到主线程可能产生主动发送,并且这种是完成端口设计框架当中所不建议的),而这种所谓的互斥也仅仅只是说为了更好的利用前一数据片断发送过程的间隔时间,这种系统消耗不会太大.
    一开始的时候我也确实想过这个会带来相当的消耗,所以我就直接使用一个最原始的,也就是MS的IOCP ECHO Server例程来进行测试,结果我发现当中CPU的耗用同我所设计的差不蛮多,仅仅只是流量上面,确实比我的多几百KB/S(百兆局域网,传送速率为IO各5MB/s~5.8MB/s之间),而这个差额,主要还是在于我本身的设计缺陷所带来的.目前我正打算重写,我设计的是工作线程可调节模式,也就是可以由主线程在一定范围内控制线程的数量,而这当中就存在一个问题,即当初我没有注意到当一个结程结束,会便得该线程投递的I/O操作被取消,这个目前倒是已经解决,另外一点就是我希望的是在同一个连接上面,收与发进行异步作业,也就是可以同步进行,那么就可能存在这样一个问题,当一个连接突然出现故障时,去删除相关的Context会出现意外,重新设计的思路就是不再直接删除,而是移至回收站,则清洁工结程进行处理,同时也考虑扫除部分长时间不工作的连接.
    不过目前我还没有测试出来,这个同一连接上面的异步I/O的可行性.
      

  9.   

    打错了,对于阻塞套接字
    另,我现在做的是客户端,不是服务端,服务端主线程的确很少很送数据,怪我没说清楚.服务端的不存在我说的问题.你第二个问题我正好也碰到了,基本上算是解决,不是绝对可靠,思路和你差不多,我就是一个连接上面收发异步进行,但每一个context我会有一个标识,表示是否这个context是否合法,不合法的话并不马上删除而是放入一个队列并置一个放入时间,专门开一个清理线程,放入超过一定的时间就删除,这个时间可以稍长一点,比如我设置的是30秒.这个同样是在客户端里做的,个人认为在服务端里控制线程的数量意义不大.更不能照搬cpu*2,可以手动改变值,别是一些计算大,或访问数据库慢的,操作时间相对长的,线程多一点好,我写过一个server用4个线程卡得不行,一怒之下,我改成20个,结果一切正常,线程切换的消耗相对了长时间的等待简直微不足道
      

  10.   

    不能照搬cpu*2,可以手动改变值,别是一些计算大,或访问数据库慢的,操作时间相对长的,线程多一点好,我写过一个server用4个线程卡得不行,一怒之下,我改成20个,结果一切正常,线程切换的消耗相对了长时间的等待简直微不足道
    ------------
    同意以上观点.
      

  11.   

    其实对于线程的问题,我只是给给出一个用户期望的同步运行线程参考值,但是由于线程作业过程当中,很有可能所有结程都在忙呼,那么,后续过来的客户请求,将没有线程应付,所以此时就必须无论如何得保持有一个以上的用户结程在做GetQueuedCompletionStatus等待。多出的线程在服务完成后,自动删除。
      

  12.   

    呵呵,我也碰到过,用IOCP如果接到一个消息,我要发送两个消息的话,好像非常麻烦啊。
      

  13.   

    强烈建议不要连续发送send,虽然这样做可以。一般的做法是自己实现一层缓存,把要发的数据先放入缓存,然后按一个机制去发送缓存。
      

  14.   

    去codeproject上去下载,有个代码能把你要发的数据都写到缓冲去,然后一次发,根本就无须多次send