基于UDP的IOCP在接收数据操作时 如何区分数据 本帖最后由 stolen007 于 2011-05-29 06:43:39 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 那请问是否会影响效率呢 能否给个具体代码 我加入CRC校验 还有 客户端把封包分成100个 万一丢包呢 我要怎么组合 比较有效率 我自己的实现代码 但是还没有全部完成 大家帮我看看 GENERAL_CONTEXT *pGeneralContext=pUdpContext->pGenContext; if (pGeneralContext->CrcSize!=crc16((uint8 *)pGeneralContext->buff,sizeof(pGeneralContext->buff))) { //要求重新发送 设置一个重新发送的标志 } else { if(pGeneralContext->TotalNO>0) //判断是否是只有一个 只有一个就不用下面这些操作了 { for ()//循环查找链表 { if (pGeneralContext->Flag=) //循环比较 { //继续插入 要加入10个字节的偏移 判断是否完整 if () { } } } } /*否则就是 没有发送错误的 首先判断是否是多个封包pGeneralContext->TotalNO判断是否是最新编码 迭代比较pGeneralContext->Flag 如果找不到就新建一个指针保存 如果不是就插入到 指定标志的偏移里 判断是否完整了 如果完整则传递给客户 释放掉数据 */ int CIocpServer::IssueUdpSendOp(struct sockaddr_in& remoteAddr,char* buf,unsigned long data_len,SOCKET socket,char * Flag){ try { if(m_bStopServer) { return FALSE; } if(m_pUdpContextManager==NULL) throw CSrvException("IssueUdpSendOp m_pUdpContextManager指针非法.",-1); //下面的循环是把数据块分包 unsigned long leave_bytes = data_len; unsigned long trans_bytes = data_len; unsigned short counter = 0; // unsigned short data_start_index = 0; //数据真实的起始位 GENERAL_CONTEXT *pGeneralContext; memset((char *)pGeneralContext,0,sizeof(pGeneralContext)); if (data_len>DEFAULT_UDP_BUFFER_SIZE) { if ((data_len%DEFAULT_UDP_BUFFER_SIZE)==0) { pGeneralContext->TotalNO=(data_len/DEFAULT_UDP_BUFFER_SIZE); } else { pGeneralContext->TotalNO=(data_len/DEFAULT_UDP_BUFFER_SIZE)+1; } } else { pGeneralContext->TotalNO=0; } memcpy(pGeneralContext->Flag,Flag,sizeof(Flag)); do { memset((char *)pGeneralContext->buff,0,sizeof(pGeneralContext->buff)); memset((char *)pGeneralContext->CrcSize,0,sizeof(pGeneralContext->CrcSize)); memset((char *)pGeneralContext->SortNo,0,sizeof(pGeneralContext->SortNo)); UDP_CONTEXT* pUdpContext = NULL; m_pUdpContextManager->GetContext(pUdpContext); if(pUdpContext==NULL) throw CSrvException("pUdpContext指针非法.",-1); if(leave_bytes <=DEFAULT_UDP_BUFFER_SIZE) //小于一次发送量 trans_bytes = leave_bytes; else trans_bytes = DEFAULT_UDP_BUFFER_SIZE; leave_bytes = leave_bytes - trans_bytes; //一次发送后剩余的字节数 // memcpy(pUdpContext->data_buffer,buf+counter*DEFAULT_UDP_BUFFER_SIZE,trans_bytes); //拷贝字节数 memcpy(pGeneralContext->buff,buf+counter*DEFAULT_UDP_BUFFER_SIZE,trans_bytes); //拷贝字节数 pGeneralContext->CrcSize=crc16((uint8 *)pGeneralContext->buff,sizeof(pGeneralContext->buff)); counter++; pGeneralContext->SortNo=counter; ZeroMemory(&pUdpContext->operate_overlapped,sizeof(WSAOVERLAPPED)); pUdpContext->operate_type = IO_UDP_SEND; pUdpContext->socket = socket; pUdpContext->operate_buffer.buf =(char *) pUdpContext->pGenContext; pUdpContext->operate_buffer.len = trans_bytes;//注意此处的6 pUdpContext->remote_address = remoteAddr; pUdpContext->remote_address_len = sizeof(struct sockaddr); DWORD nubmerBytes = 0; int err = WSASendTo( pUdpContext->socket, &pUdpContext->operate_buffer, 1, &nubmerBytes, 0, (struct sockaddr*)&pUdpContext->remote_address, sizeof(pUdpContext->remote_address), &pUdpContext->operate_overlapped, NULL); if(SOCKET_ERROR == err && WSA_IO_PENDING != WSAGetLastError()) { ReleaseContext((IO_PER_HANDLE_STRUCT*)pUdpContext); throw CSrvException("IssueUdpSendOp->WSASend发生错误.",WSAGetLastError()); } else if(0 == err) { //还要考虑立即完成的情况 } }while(leave_bytes>0); return TRUE; } catch(CSrvException& e) { this->PrintDebugMessage(e); if(m_bExceptionStop) throw e; } catch(...) { string message("IssueUdpSendOp 发生未知异常."); PrintDebugMessage(message.c_str()); if(m_bExceptionStop) throw message; } return FALSE;} 我想问几个关于listview的消息 想外包一个tapi方面的项目,有兴趣的高手qq联系 程序运行时,在任务管理器里为什么没有显示 这个错误请教高手'm_pSet' : undeclared identifier 程序调试的问题 求SQL语句! 怎样才能不刷新整个屏幕呢? 有没有简单的方法替换文本文件中的特定字符串? 再次求教:VC中怎样按顺序向数据库添加记录? 在单文档启动时,如何改变他的大小。启动成功后,不能用鼠标拖动边框,改变大小。 求教 窗体中容器上的控件 其句柄如何获取? 冒泡排序.....
还有 客户端把封包分成100个 万一丢包呢 我要怎么组合 比较有效率
GENERAL_CONTEXT *pGeneralContext=pUdpContext->pGenContext;
if (pGeneralContext->CrcSize!=crc16((uint8 *)pGeneralContext->buff,sizeof(pGeneralContext->buff)))
{
//要求重新发送 设置一个重新发送的标志
}
else
{
if(pGeneralContext->TotalNO>0) //判断是否是只有一个 只有一个就不用下面这些操作了
{
for ()//循环查找链表
{
if (pGeneralContext->Flag=) //循环比较
{
//继续插入 要加入10个字节的偏移 判断是否完整
if ()
{
}
}
}
}
/*否则就是 没有发送错误的 首先判断是否是多个封包pGeneralContext->TotalNO
判断是否是最新编码 迭代比较pGeneralContext->Flag 如果找不到就新建一个指针保存
如果不是就插入到 指定标志的偏移里 判断是否完整了 如果完整则传递给客户 释放掉数据
*/
{
try
{
if(m_bStopServer)
{
return FALSE;
} if(m_pUdpContextManager==NULL)
throw CSrvException("IssueUdpSendOp m_pUdpContextManager指针非法.",-1); //下面的循环是把数据块分包
unsigned long leave_bytes = data_len;
unsigned long trans_bytes = data_len;
unsigned short counter = 0;
// unsigned short data_start_index = 0; //数据真实的起始位
GENERAL_CONTEXT *pGeneralContext;
memset((char *)pGeneralContext,0,sizeof(pGeneralContext));
if (data_len>DEFAULT_UDP_BUFFER_SIZE)
{
if ((data_len%DEFAULT_UDP_BUFFER_SIZE)==0)
{
pGeneralContext->TotalNO=(data_len/DEFAULT_UDP_BUFFER_SIZE);
}
else
{
pGeneralContext->TotalNO=(data_len/DEFAULT_UDP_BUFFER_SIZE)+1;
}
}
else
{
pGeneralContext->TotalNO=0;
}
memcpy(pGeneralContext->Flag,Flag,sizeof(Flag));
do
{
memset((char *)pGeneralContext->buff,0,sizeof(pGeneralContext->buff));
memset((char *)pGeneralContext->CrcSize,0,sizeof(pGeneralContext->CrcSize));
memset((char *)pGeneralContext->SortNo,0,sizeof(pGeneralContext->SortNo));
UDP_CONTEXT* pUdpContext = NULL;
m_pUdpContextManager->GetContext(pUdpContext);
if(pUdpContext==NULL)
throw CSrvException("pUdpContext指针非法.",-1); if(leave_bytes <=DEFAULT_UDP_BUFFER_SIZE) //小于一次发送量
trans_bytes = leave_bytes;
else
trans_bytes = DEFAULT_UDP_BUFFER_SIZE;
leave_bytes = leave_bytes - trans_bytes; //一次发送后剩余的字节数
// memcpy(pUdpContext->data_buffer,buf+counter*DEFAULT_UDP_BUFFER_SIZE,trans_bytes); //拷贝字节数
memcpy(pGeneralContext->buff,buf+counter*DEFAULT_UDP_BUFFER_SIZE,trans_bytes); //拷贝字节数
pGeneralContext->CrcSize=crc16((uint8 *)pGeneralContext->buff,sizeof(pGeneralContext->buff));
counter++;
pGeneralContext->SortNo=counter;
ZeroMemory(&pUdpContext->operate_overlapped,sizeof(WSAOVERLAPPED));
pUdpContext->operate_type = IO_UDP_SEND;
pUdpContext->socket = socket;
pUdpContext->operate_buffer.buf =(char *) pUdpContext->pGenContext;
pUdpContext->operate_buffer.len = trans_bytes;//注意此处的6
pUdpContext->remote_address = remoteAddr;
pUdpContext->remote_address_len = sizeof(struct sockaddr);
DWORD nubmerBytes = 0;
int err = WSASendTo(
pUdpContext->socket,
&pUdpContext->operate_buffer,
1,
&nubmerBytes,
0,
(struct sockaddr*)&pUdpContext->remote_address,
sizeof(pUdpContext->remote_address),
&pUdpContext->operate_overlapped,
NULL);
if(SOCKET_ERROR == err && WSA_IO_PENDING != WSAGetLastError())
{
ReleaseContext((IO_PER_HANDLE_STRUCT*)pUdpContext);
throw CSrvException("IssueUdpSendOp->WSASend发生错误.",WSAGetLastError());
}
else if(0 == err)
{
//还要考虑立即完成的情况
}
}while(leave_bytes>0); return TRUE;
}
catch(CSrvException& e)
{
this->PrintDebugMessage(e);
if(m_bExceptionStop)
throw e;
}
catch(...)
{
string message("IssueUdpSendOp 发生未知异常.");
PrintDebugMessage(message.c_str());
if(m_bExceptionStop)
throw message;
}
return FALSE;
}