要做转发服务器,很麻烦,通讯时遇到了问题
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如何才能比较好的完成?请教有经验的高手回答
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如何才能比较好的完成?请教有经验的高手回答
根据.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服务器
用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 到是可能的,并且这样做也没有问题。
和服务器之间应该用独立线程、异步长连接,稳定高效
假设你有1000个到客户端的连接,1个到服务器的连接,则
那1个到服务器的连接上的IO吞吐量等于那1000个到客户端的连接上的IO吞吐量之和
你把这1001个连接一起扔到IOCP中等同处理合适吗???IOCP的本质是用少量线程高频率反复进行异步IO投递,降低线程切换的开销,获得更优的高并发IO处理能力你都准备用recv、send这种根本不考虑效率的阻塞函数了,你还折腾IOCP干嘛?
避免这个问题是不是应该建立两个完成端口,对于和服务端通信的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的提示,请教各位这种情况如何处理
所以,通过一个有限容量的线程池来共同分担所有的客户端IO请求——这就是IOCP思想你的服务端只有一个,有必要让它去和客户端竞争线程池资源吗?当然是自己独享一个线程每个客户端收发的数据都要转发给服务端,显然你和服务端的通信量等于与所有客户端的通信量的总和
这很难理解?IoType被重置,导致WSARecv和WSASend混淆,这不是WSARecv和WSASend本身的问题
是因为你在投递WSARecv和WSASend时,传入了同一个overlapped对象,这本身就是错误的
并发投递IO操作时,保证传入不同的overlapped对象,自然就避免了相互干扰
2、客户端请求统一放入一个请求队列,队列中的每一条记录包括请求者的socket和请求内容
3、专门开辟一个线程与服务器通信
4、服务器线程工作逻辑为:从请求队列读取一个请求、连接相应的服务器、获取服务器回复、关闭连接、向IOCP投递回复,如此反复循环
能不能把转发接收服务端数据的socket加入到select,在另个线程中接收服务端数据。
MFC会帮你建立一个独立线程,运行一个CSocketWnd对象,你所有的CAsyncSocket对象都只需要处理OnRecv、OnSend等消息响应函数,CSocketWnd会在FD事件发生时自动调用你的OnXXX函数,不用你关心底层细节
IOCP处理客户端,select接收服务端数据。这个方法能用么