一个socket分一个线程收 一个线程发
发送的有一个发送 一个收 协议是这样
msgHead(协议头 里面包含数据长度)
发送数据 = msgHead + 数据A
接收数据 = msgHead + 数据B
接收的先收到msgHead知道数据长度,再收数据B 我写了代码 大伙儿帮我看下有什么问题 错误处理这些可以么? 拜托
DWORD WINAPI CModuleApp::_SendThread( LPVOID pParam )
{
CModuleApp* pModule = (CModuleApp*)pParam;
DWORD dwRet = 0;
vector<char> vecSendMsg;
for (;;)
{
dwRet = WaitForSingleObject(m_hEventSendThreadStop, 0);
if( dwRet == WAIT_OBJECT_0 )
break;
if( pModule->m_msgManger.GetSendMsg(vecSendMsg) )//获取发送信息 这里封装了 msgHead +数据
{
if( pModule->m_socket.SendEx(vecSendMsg) == ERROR_SUCCESS) 封装的socket发送
{

}
}

Sleep(1000);
}
SetEvent(m_hEventSendThreadExit);
return ERROR_SUCCESS;
}DWORD WINAPI CModuleApp::_RecvThread( LPVOID pParam )
{
CModuleApp* pModule = (CModuleApp*)pParam;
DWORD dwRet = 0;
vector<char> vecRecv;
for(;;)
{
dwRet = WaitForSingleObject(m_hEventSendThreadStop, 0);
if( dwRet == WAIT_OBJECT_0 )
break;
if( pModule->m_socket.RecvEx(vecRecv) == ERROR_SUCCESS )//封装的socket
{
pModule->m_msgManger.DisMsg(vecRecv);  //收到后处理
}
Sleep(100);
}
return ERROR_SUCCESS;
}
这是2个收发线程long CSocketEx::SendEx( const vector<char>& vecMsg )
{
try
{
if (vecMsg.empty())
{
return -1;
} if(!m_bConnFlag)
{
CloseSocket();
return -1;
} DWORD dwSendBytes = 0;
DWORD dwBlockCount = 0;
DWORD dwRet = 0;
DWORD dwSendLen = vecMsg.size();
int nErrorCode;
while (dwSendBytes != dwSendLen && m_bConnFlag)
{
if( dwSendLen - dwSendBytes <= 0 )
break;
dwRet = send(m_socket, &(vecMsg[dwSendBytes]), dwSendLen - dwSendBytes, 0);
if (dwRet == SOCKET_ERROR)
{
nErrorCode = WSAGetLastError();
if (nErrorCode != WSAEWOULDBLOCK)
{
CloseSocket();
return nErrorCode;
}
Sleep(10); if(dwBlockCount == 6000)
{
CloseSocket();
return -2;
}
dwBlockCount ++;
}
else if (dwRet == 0)
{
CloseSocket();
return -3;
}
else if (dwRet > 0)
{
dwSendBytes += dwRet;
dwBlockCount = 0;
}
else
{
CloseSocket();
return -4;
}
} }
catch (...)
{
CloseSocket();
// CLog::WriteLog("SendEx - Error");
return -5;
}
return ERROR_SUCCESS;
}
long CSocketEx::RecvEx( vector<char>& vecMsg )
{
try
{
if(!m_bConnFlag)
{
CloseSocket();
return -1;
} DWORD dwRecvBytes = 0; //已经收到的数据
int nRet = -1;
int nLastError = 0;
fd_set fdread;
TIMEVAL   tjf; 
msgHead head;
DWORD dwRecvLen = sizeof(msgHead); //先收一个头的大小
vecMsg.resize(sizeof(msgHead));
while(TRUE)
{
tjf.tv_sec =1; 
tjf.tv_usec =0; 
FD_ZERO(&fdread); 
FD_SET(m_socket,&fdread);     //   ss   是个以连接的socket 
nRet=select(0,&fdread,NULL,NULL,&tjf);   //这里自己参考msdn中select的定义 
if( nRet != SOCKET_ERROR )
{
if(FD_ISSET(m_socket,&fdread)) 
{
nRet = recv(m_socket, &(vecMsg[dwRecvBytes]), dwRecvLen - dwRecvBytes, 0);
if (nRet == SOCKET_ERROR)
{
nLastError = WSAGetLastError();
if (nLastError != WSAEWOULDBLOCK)
{
CloseSocket();
return nLastError;
}
Sleep(10);
}
else if(nRet == 0)
{
CloseSocket();
return -3;
}
else if (nRet > 0)
{
dwRecvBytes += nRet;
if( dwRecvBytes >= sizeof(msgHead) &&dwRecvLen == sizeof(msgHead))
{
memcpy(&head, &(vecMsg[0]), sizeof(msgHead));
dwRecvLen += head.dataLen;
vecMsg.resize(dwRecvLen);
}
if( dwRecvBytes == dwRecvLen && dwRecvLen >  sizeof(msgHead) )
{
return ERROR_SUCCESS;
}
}
else
{
CloseSocket();
return -4;
}
}
}
} }
catch (...)
{
CloseSocket();
// CLog::WriteLog("RecvEx - Error");
return -5;
}
return ERROR_SUCCESS;
}这个是对应的 发送线程 和接受线程

解决方案 »

  1.   

    当发送、接收多后,会有一个明显的问题 就是效率,
    每个接收线程都处于阻塞等待状态
    建议采用异步方式,用事件对象让接收线程处于等待状态(不获取时间片)
    当send时,激活接收线程接收。
    而且个人感觉发送没有必要再开启一个线程,发送完全可以都写在主线程里
      

  2.   


    DWORD WINAPI CModuleApp::_SendThread( LPVOID pParam )
    {
        CModuleApp* pModule = (CModuleApp*)pParam;
        DWORD dwRet = 0;
        vector<char> vecSendMsg;
        for (;;)
        {
            dwRet = WaitForSingleObject(m_hEventSendThreadStop, 0);
            if( dwRet == WAIT_OBJECT_0 )
                break;
            if( pModule->m_msgManger.GetSendMsg(vecSendMsg) )msgHead +数据
            {
                if( pModule->m_socket.SendEx(vecSendMsg) == ERROR_SUCCESS) 
                {
                    
                }
            }
            
            Sleep(1000);
        }
        SetEvent(m_hEventSendThreadExit);
        return ERROR_SUCCESS;
    }楼主的代码, 很有创意.
    在循环体中每次都等待退出Event, 时间为0, 假如等待成功, 就代表要退出循环, 结束线程, 并且把退出事件设置为受信, 让外部可以知道线程已经运行到退出的那一步了. 真的十分有创意...
      

  3.   

    直接用线程的句柄来WaitFor..
    你所用的Event, 不用来做退出, 而是用来让线程等待处理任务会比较合理点吧..