服务器端采用WSAAsyncSelect模型,对客户端发送过来的数据进行处理。
客户端要向服务器端发送数据请求,数据组织成一定的报文格式发送,报文头中包含了此次发送的请求类型和报文长度,然后客户端用send函数把整个报文发送出去,由于报文可能很长,因此采用循环发送。服务器端在FD_READ的响应中先接收报文头,然后根据报文类型进行不同的处理,在这些不同的处理中根据报文头中的报文长度读取整个报文。问题是当客户端一次send发送不完整个报文时,在服务器端的处理中根据报文头中的长度信息能直接读取到整个报文吗?还是需要在另外一个FD_READ之后才能读取到呢?
客户端要向服务器端发送数据请求,数据组织成一定的报文格式发送,报文头中包含了此次发送的请求类型和报文长度,然后客户端用send函数把整个报文发送出去,由于报文可能很长,因此采用循环发送。服务器端在FD_READ的响应中先接收报文头,然后根据报文类型进行不同的处理,在这些不同的处理中根据报文头中的报文长度读取整个报文。问题是当客户端一次send发送不完整个报文时,在服务器端的处理中根据报文头中的长度信息能直接读取到整个报文吗?还是需要在另外一个FD_READ之后才能读取到呢?
{
recv(); //接收报文头
…… //处理报文头,得到报文类型和总的报文长度
case type: //根据不同报文类型进行处理
{
while(1)
{
recv(); //循环读取整个报文。 此时客户端发送的报文并不是一个完整的报文,那在此处循环接收报文头中所表示的报文长度的报文,是否能
接收到完整的报文呢?
}
}
}
的确是啊。但我每次send都发送整个数据,服务器端接受完整个数据后就退出循环了,cpu应该不会等太长时间的吧
你没弄清楚何谓"异步".如果没接收完的数据还没到达,你循环调用recv(),一样是没有数据接收到,recv()只会不断地返回错误,最大的问题是,你这样做已经破坏了"异步"的执行环境,将"异步"弄成了阻塞,在你的while()循环中,系统其它消息,象有数据可接收的FD_READ等消息你的程序都没法接收到.正确做法是当第一次没能接收完,等待下一个FD_READ消息,然后在第一次没接完的buffer后追加.例如第一次接收了50 bytes,那么第二次接收就是SessionCurrent->DataBuf.buf = &SessionCurrent->Buffer[50];
SessionCurrent->DataBuf.len = sizeof(SessionCurrent->Buffer) - 50;
if (WSARecv(hSocket, &(SessionCurrent->DataBuf),1, &RecvBytes,&Flags, NULL, NULL) == SOCKET_ERROR)第二次再接不完,继续象上面的追加就是.一直追回到接完为止就是.