服务器客户端建立链接成功,客户端send数据服务器能接受处理,然后服务器tcpServer->Send调用CTcpServer::Send向客户端发送数据,客服端第一次用recv可以阻塞接受数据,但客服端第二次就不能阻塞接受数据了 请问是什么原因?客户端:
iSend = send(client, (char *)reqPackData, iLen, 0); 第一步:这里先给服务器发送数据iRecv = recv(client, buff, 1024, 0); 第三步:客户端接受到结构数据处理,这里可以阻塞接受
if (reqPackData->ReqNo == ((ReqPack *)buff)->ReqNo)
{
iRecv = recv(client, buff, 1024, 0); 第五步:应该是接受服务器发送的偏移地址数据,但这步没有阻塞没有接受
}服务器端:
tcpServer->Send(s, (char *)reqPack, sizeof(ReqPack)); 第二步:服务器处理数据后调用CTcpServer::Send发送结构数据给客服端
tcpServer->Send(s, pCom+reqPack->dwoffset, reqPack->dwSize); 第四步:服务器发送偏移地址数据给客服端
、、、、、、、、、、、、、、、、、、、、、、、、、、、
int CTcpServer::Send(SOCKET s, char *buf, DWORD size)
{
、、、、、、、、、、、、、、、、、、、、、、、、、、、
iSend = WSASend(s, &(PerIoData->DataBuf), 1, &SendBytes, Flags, &(PerIoData->Overlapped), NULL);
、、、、、、、、、、、、、、、、、、、、、、、、、、、
}开发环境VC.NET2005 那里人气太差了 借本版宝地 请高手指点
iSend = send(client, (char *)reqPackData, iLen, 0); 第一步:这里先给服务器发送数据iRecv = recv(client, buff, 1024, 0); 第三步:客户端接受到结构数据处理,这里可以阻塞接受
if (reqPackData->ReqNo == ((ReqPack *)buff)->ReqNo)
{
iRecv = recv(client, buff, 1024, 0); 第五步:应该是接受服务器发送的偏移地址数据,但这步没有阻塞没有接受
}服务器端:
tcpServer->Send(s, (char *)reqPack, sizeof(ReqPack)); 第二步:服务器处理数据后调用CTcpServer::Send发送结构数据给客服端
tcpServer->Send(s, pCom+reqPack->dwoffset, reqPack->dwSize); 第四步:服务器发送偏移地址数据给客服端
、、、、、、、、、、、、、、、、、、、、、、、、、、、
int CTcpServer::Send(SOCKET s, char *buf, DWORD size)
{
、、、、、、、、、、、、、、、、、、、、、、、、、、、
iSend = WSASend(s, &(PerIoData->DataBuf), 1, &SendBytes, Flags, &(PerIoData->Overlapped), NULL);
、、、、、、、、、、、、、、、、、、、、、、、、、、、
}开发环境VC.NET2005 那里人气太差了 借本版宝地 请高手指点
iRecv = recv(client, buff, 1024, 0); 第三步:客户端接受到结构数据处理,这里可以阻塞接受
已经把所有数据发送过来了。
iRecv = recv(client, buff, 1024, 0); 第三步:客户端接受到结构数据处理,这里可以阻塞接受
已经把所有数据发送过来了。
这里的确阻塞接受了服务器第一次发送的全部数据;我的目的是:服务器第一次(第二步)发送结构数据,客户端第一次用recv(第三步)接受处理,如果这个结构数据正确,客服端第二次用recv(第五步)接受服务器第二次(第四步)发送的偏移地址中的数据,但客服端第二次用recv(第五步)确不能阻塞接受数据了高手们再指点下 非常感谢大家
这个我推荐你用流对象来接受,你那个我现在可以肯定是粘包了,没有按照你的想法来发送.
要解决这个东西,一般推荐用异步的接受,或者用类似BinaryReader 的对象来读取.
而客户端在接收的时候没有对粘包的情况做处理,很有可能第一次接收的时候就把数据都接收完了
粘包并不是和数据量有关的.
SOCKET client;这个不算流对象,用SYSTEM.IO空间下面的对象.
我这里应该不是粘包的问题,因为我是单步执行都不可以的;我单步执行到客服端第二次recv(第五步)不阻塞,然后再执行服务器第二次发送数据(第四步)的。 看来我是不是需要直接就这样处理了:服务器端只tcpServer->Send一次,这个数据包包括: (char *)reqPack + pCom+reqPack->dwoffset(也就是把结构体数据与偏移地址数据一起发送),客服端也只接收一次:iRecv = recv(client, buff, 1024, 0);
应该这样要好些吧 请大家指点下,服务器端程序是别人做好了的 这样我就要改他的程序了
while (true){
check -= iRecv;
if(check==0){
// 数据已经全部接收
break;
}else{
// 数据已经部分接收
continue;
}}
// 这是c#的代码
iRecv = recv(client, buff, ((ReqPack *)buff)->dwSize, 0);这样就可以了 感谢大家