要做转发服务器,很麻烦,通讯时遇到了问题
A为客户端端,B为转发服务器,C为真实服务器    B接收到A请求,把Socket关联到完成端口,B向C发送数据(B,C进行连接的套接字也关联到完成端口,因为C也会主动发数据,所以进行了关联),然后B接收C的数据,B把转发给A。在B-C进行通讯时使用WSASend和WSARecv函数会在IOCP工作线程中检测到。我用send和recv函数可以么。这样有什么影响。    再查找资料时,说WSASend和WSARecv一起调用会有问题,不能这么调用么。怎么解决这种应答方式通讯呢    我这个实现用IOCP如何才能比较好的完成?请教有经验的高手回答

解决方案 »

  1.   

    Client<->B(需要建立的服务器)<->C(213.23.45.24)
    根据.CONFIG读取配置信息,建立自己的转发服务器A USERA  PASS1  
    B USERB  PASS2  
    C USERB  PASS3  初始化服务器B,建立3个连接B-C,连接到服务器213.23.45.24Client连接B,查找3个连接中的空闲连接,建立连接(占用该连接10秒),然后发送指令给B(占用时间到10秒),B转发给C后,
    C返回给B,然后转发给Client.如果A没有在10秒中内发送指令给B,自动把该通道让给其他的Client
    如何控制10秒,如何建立这个IOCP服务器
      

  2.   

    http://topic.csdn.net/u/20090624/09/bf41a82d-4fc8-4052-bc53-18b0da405ac8.html?seed=604832994http://topic.csdn.net/u/20090623/22/3bc308a0-9bde-4be7-92aa-81df76cef514.html?seed=53253237&r=58244566#r_58244566
      

  3.   

    “在B-C进行通讯时使用WSASend和WSARecv函数会在IOCP工作线程中检测到。我用send和recv函数可以么。这样有什么影响。     再查找资料时,说WSASend和WSARecv一起调用会有问题,不能这么调用么。怎么解决这种应答方式通讯呢 ”
    用send和recv是可以的,不过这样的话,就失去了用iocp的优势。因为send,recv会阻塞在哪里,效率大打折扣。而用wsarecv和wsasend,接收和发送操作完以后就不用管了,实际完成后会有通知给你。
    一起调用应该没有问题吧,没试过。不过,wsarecv和wsasend一般是等一个操作完成后,再进行下一个操作,比如:你上边的B wsarecv到A的数据后,B会wsasend给C请求,B再wsarecv C 的返回信息,B再wsasend A 该信息。整个流程比较清晰,应该不会用到 B wsarecv A 的同时 ,B wsasend A信息吧?而B
    wsarecv C 的同时, B wsasend A 到是可能的,并且这样做也没有问题。
      

  4.   

    可以用send代替一下WSASend(),不能用recv()代替WSARecv(),因为WSARecv()是要投递接收请求的,你如果用recv()代替的话,一次对方再发过来的数据你完成端口就接收不到了,可者会出现问题,因为WSARecv()里投递的数据参数里还包括一些别的对象
      

  5.   

    和服务器通信的socket关联完成端口干什么???
    和服务器之间应该用独立线程、异步长连接,稳定高效
    假设你有1000个到客户端的连接,1个到服务器的连接,则
    那1个到服务器的连接上的IO吞吐量等于那1000个到客户端的连接上的IO吞吐量之和
    你把这1001个连接一起扔到IOCP中等同处理合适吗???IOCP的本质是用少量线程高频率反复进行异步IO投递,降低线程切换的开销,获得更优的高并发IO处理能力你都准备用recv、send这种根本不考虑效率的阻塞函数了,你还折腾IOCP干嘛?
      

  6.   

    WSASend和WSARecv一起调用会有问题?什么问题?从来都是并发调用的,没碰到过问题
      

  7.   

    谢谢sun007700,xy_dream,fangle6688等的指导和服务器通信的socket关联完成端口,可能是我描述错误,这个socket是转发建立的socket用于和服务器通信的。是这个socket关联到完成端口和服务器之间应该用独立线程,这里不懂,是用线程进行数据通信么假设你有1000个到客户端的连接,1个到服务器的连接,则 那1个到服务器的连接上的IO吞吐量等于那1000个到客户端的连接上的IO吞吐量之和。为什么是这样的,是因为关联的是一个完成端口么?
    避免这个问题是不是应该建立两个完成端口,对于和服务端通信的socket应该关联到一个新的完成端口。
    这个地方很重要,因为只要和服务端成功连接,服务器是一直有数据发送给转发的,而且数据量比较大。这里怎么处理WSASend和WSARecv一起使用我看到这样的文字:
    在一次操作中(比如接收到数据后的操作),先后调用WSASend和WSARecv,来实现发送数据,然后继续Recv的动作,这样做可行吗?答案是否定的。分析:调用WSASend之前,设置IoType为IoSend,标志本次操作是发送操作;然后在调用WSARecv前,设置IoType为IoRecv,标志本次操作是接收操作。IOCP在处理消息队列时,首先应该接收到的是发送操作,由于IoType已经被设置成了IoRecv,在判断时就会将这次操作判断成接收操作,去检测接收BUFFER,这样显然就出错了;然后会接收到接收操作,此时IoType是IoRecv,仍然判断为接收操作,此时检测接收BUFFER,是正确的。这样做的直观表现就是接收事件明显变多了。
    文章出处:http://www.diybl.com/course/3_program/c++/cppsl/20071215/92173.htmlxy_dream的提示,请教各位这种情况如何处理
      

  8.   

    客户端因为可能会很多,所以如果给每个客户端都分配一个子线程的话,对服务器资源消耗太大
    所以,通过一个有限容量的线程池来共同分担所有的客户端IO请求——这就是IOCP思想你的服务端只有一个,有必要让它去和客户端竞争线程池资源吗?当然是自己独享一个线程每个客户端收发的数据都要转发给服务端,显然你和服务端的通信量等于与所有客户端的通信量的总和
    这很难理解?IoType被重置,导致WSARecv和WSASend混淆,这不是WSARecv和WSASend本身的问题
    是因为你在投递WSARecv和WSASend时,传入了同一个overlapped对象,这本身就是错误的
    并发投递IO操作时,保证传入不同的overlapped对象,自然就避免了相互干扰
      

  9.   

    明白了。fangle6688你说的对。不应该把客户端的连接和转发与服务端的连接放在IOCP中处理。当前是我需要根据客户端的请求通过转发去连接不同的服务器,如果已有客户端请求了服务器,那么当前客户端就不用去再和服务器连接了,数据直接由转发和客户端进行数据通信。过这个时候转发和服务器使用一个线程就不合适了吧,这里也应该使用IOCP么谢谢
      

  10.   

    如果服务端有多个,建议与服务器之间的通信使用短连接你的架构应该是:1、使用一个IOCP与所有客户端通信
    2、客户端请求统一放入一个请求队列,队列中的每一条记录包括请求者的socket和请求内容
    3、专门开辟一个线程与服务器通信
    4、服务器线程工作逻辑为:从请求队列读取一个请求、连接相应的服务器、获取服务器回复、关闭连接、向IOCP投递回复,如此反复循环
      

  11.   

    端连接不合适。和服务端通信首先有一系列的命令通讯进行握手。握手成功后就接收服务端的数据。
    能不能把转发接收服务端数据的socket加入到select,在另个线程中接收服务端数据。
      

  12.   

    如果服务端有LOGIN之类的机制,用短连接效率确实太低这种情况下建议你与服务器通信使用MFC的CAsyncScoket,用其封装好的消息机制来简化程序架构
    MFC会帮你建立一个独立线程,运行一个CSocketWnd对象,你所有的CAsyncSocket对象都只需要处理OnRecv、OnSend等消息响应函数,CSocketWnd会在FD事件发生时自动调用你的OnXXX函数,不用你关心底层细节
      

  13.   

    不使用MFC。IOCP+SELECT可以一起使用么。客户端有三个socket需要去转发进行通信。服务端有四个端口的数据需要接收。
    IOCP处理客户端,select接收服务端数据。这个方法能用么
      

  14.   

    把connect的到服务端的端口也关联到完成端口,这样对效率影响大不大