[讨论]如何向应用层提供Socket网络数据收发的封装
VC中客户端socket与服务器连接后,需要执行一个封状的操作
朝服务器发送一些数据(命令),然后返回结果
假设全部才字符串,类似这样的函数
CString SendCommand (CString cmd,socket sk)
要求在执行这个函数的时候能同时响应用户界面操作
也就是要用异步方式
而且这个socket已经建立好,有RecvTheard在处理
我目前是用Event实现的,很别扭:
m_hevtReadStore=CreateEvent(NULL,false,FALSE,NULL);
//m_tcp是封装的socket基本操作类
CString SendCommand (CString cmd)
{
....
m_tcp.send(sk,cmd,...);
//然后等待hevtReadStore被置信号
int i=0;
while(i<100)
{
if(WaitForSingleObject(m_hevtReadStore,100)!=WAIT_TIMEOUT)
{
rt=_buf;
break;
}
m_tcp.peek_message();
i++;
}
if(i>=100)
{
rt= "ERROR";
}
return rt;
}
以下是RecvThread里的处理:
DWORD dwRecvBytes=0 ; // 接收到的字符长度
DWORD dwHeadBytes=0 ; // 头长度
DWORD Flags=0; // WSARecv的参数
bool error=0;
dwHeadBytes=sizeof(_head);
while(!m_IsStop)
{
if(error)
{
//重新创建连接,并退出当前接收线程
OnDisconnect(&m_client);
//ReConnect();
return 1;
}
memset(_buf,0,DIRECTMAXBUFFER);
DWORD dwSize;
dwRecvBytes=m_tcp.recv(m_client,(char*) &_head,sizeof(_head),10);
if(dwRecvBytes!=dwHeadBytes)
{
//收到的头长度不够,忽略数据包
int err =WSAGetLastError();
if(err !=WSAEWOULDBLOCK)
{
error=true;
}
else
{
Sleep(500);
}
continue;
}
dwSize=_head.nSize;
// 数据包太大,忽略数据包
if(dwSize>DIRECTMAXBUFFER )
continue;
_head.lpbuf=_buf;
if(dwSize>0)
{
dwRecvBytes=m_tcp.recv(m_client,_buf,dwSize,20);
if(dwRecvBytes!=dwSize)
{
//收到的消息内容长度不够,忽略数据包
error=true;
continue;
}
}
switch(_head.nCmd)
{
case COOL_READSTORE:
SetEvent(m_hevtReadStore);
break;
default:
DoMessage(_head);
}
Sleep(100);
}
return 0;
但这样问题很多
首先是全局变量问题
当被置信的时候,有可能收到另一个数据包
这样_buf中的数据会改变
造成严重错误
请讨论解决方案
分数不是问题,找到好的解决方案后,再开贴送500分