socket沾包! 有什么好办法解决?

时间:2022-11-06 14:40:17
下面是我分解数据的代码, 数据量少时没有问题, 当收到的数据超过10000条, 解析就会发生错误, 如果在发送数据室加上sleep数据也没有问题.. 但效率大大降低.所以sleep不用. 高手有没有好办法来解决~
bool CServerSock::HandleData(CListCtrl& DataList, SOCKET Client)
{
int nlen = 0;
char buf[2048] = {0};
USES_CONVERSION;

for(int i = 0; i < m_ClientNum; i++)
{
if (m_Clients[i] == Client)
{
buf[nlen] = NULL;
COM_HEAD *pComHead = new COM_HEAD;
memcpy(pComHead, &buf, sizeof(COM_HEAD));

TEST_LOGDATA *plogdata = (TEST_LOGDATA *)(buf + sizeof(COM_HEAD));

DataList.InsertItem(0, A2T(plogdata->szDate));
DataList.SetItemText(0, 1, A2T(plogdata->szTime));
DataList.SetItemText(0, 2, A2T(plogdata->szName));
DataList.SetItemText(0, 3, A2T(plogdata->szMachineID));
DataList.SetItemText(0, 4, A2T(plogdata->szCardNum));
DataList.SetItemText(0, 5, A2T(plogdata->szWorkNumber));
DataList.SetItemText(0, 6, A2T(pComHead->szVersion));
DataList.SetItemText(0, 7, plogdata->uDirection?L"出门":L"进门");
delete pComHead;
pComHead = NULL;
}
}
return true;
}

16 个解决方案

#1


这是多线程么?

DataList.InsertItem(0, A2T(plogdata->szDate));
DataList.SetItemText(0, 1, A2T(plogdata->szTime));
DataList.SetItemText(0, 2, A2T(plogdata->szName));
DataList.SetItemText(0, 3, A2T(plogdata->szMachineID));
DataList.SetItemText(0, 4, A2T(plogdata->szCardNum));
DataList.SetItemText(0, 5, A2T(plogdata->szWorkNumber));
DataList.SetItemText(0, 6, A2T(pComHead->szVersion));
DataList.SetItemText(0, 7, plogdata->uDirection?L"出门":L"进门");

这段代码需要同步吧。

#2


引用 1 楼 a_rockboy 的回复:
这是多线程么? 

DataList.InsertItem(0, A2T(plogdata->szDate)); 
DataList.SetItemText(0, 1, A2T(plogdata->szTime)); 
DataList.SetItemText(0, 2, A2T(plogdata->szName)); 
DataList.SetItemText(0, 3, A2T(plogdata->szMachineID)); 
DataList.SetItemText(0, 4, A2T(plogdata->szCardNum)); 
DataList.SetItemText(0, 5, A2T(plogdata->szWorkNumber)); 
DataList.SetItemText(0, 6, A2T(pComHead->szVersion)…

没用多线程. 这是往CLIstCtrl控件中插数据

#3


晕贴掉了一句!
bool CServerSock::HandleData(CListCtrl& DataList, SOCKET Client)
{
    int nlen = 0;
    char buf[2048] = {0};
    USES_CONVERSION;

    for(int i = 0; i < m_ClientNum; i++)
    {
        if (m_Clients[i] == Client)
        {
     nlen = recv(m_Clients[i],buf,sizeof(buf),0);
            buf[nlen] = NULL;
            COM_HEAD *pComHead = new COM_HEAD;
            memcpy(pComHead, &buf, sizeof(COM_HEAD));

            TEST_LOGDATA *plogdata = (TEST_LOGDATA *)(buf + sizeof(COM_HEAD));

            DataList.InsertItem(0, A2T(plogdata->szDate));
            DataList.SetItemText(0, 1, A2T(plogdata->szTime));
            DataList.SetItemText(0, 2, A2T(plogdata->szName));
            DataList.SetItemText(0, 3, A2T(plogdata->szMachineID));
            DataList.SetItemText(0, 4, A2T(plogdata->szCardNum));
            DataList.SetItemText(0, 5, A2T(plogdata->szWorkNumber));
            DataList.SetItemText(0, 6, A2T(pComHead->szVersion));
            DataList.SetItemText(0, 7, plogdata->uDirection?L"出门":L"进门");
            delete pComHead;
            pComHead = NULL;
        }
    }

#4


bool CServerSock::HandleData(CListCtrl& DataList, SOCKET Client)
{
    int nlen = 0;
    char buf[2048] = {0};
    USES_CONVERSION;

     DataList.LockWindowUpdate();

    for(int i = 0; i < m_ClientNum; i++)
    {
        if (m_Clients[i] == Client)
        {
            buf[nlen] = NULL;
            COM_HEAD *pComHead = new COM_HEAD;
            memcpy(pComHead, &buf, sizeof(COM_HEAD));

            TEST_LOGDATA *plogdata = (TEST_LOGDATA *)(buf + sizeof(COM_HEAD));

            DataList.InsertItem(0, A2T(plogdata->szDate));
            DataList.SetItemText(0, 1, A2T(plogdata->szTime));
            DataList.SetItemText(0, 2, A2T(plogdata->szName));
            DataList.SetItemText(0, 3, A2T(plogdata->szMachineID));
            DataList.SetItemText(0, 4, A2T(plogdata->szCardNum));
            DataList.SetItemText(0, 5, A2T(plogdata->szWorkNumber));
            DataList.SetItemText(0, 6, A2T(pComHead->szVersion));
            DataList.SetItemText(0, 7, plogdata->uDirection?L"出门":L"进门");
            delete pComHead;
            pComHead = NULL;
        }
    }

     DataList.UnlockWindowUpdate();
    return true;
}

#5


recv后面要加上错误处理。另:是阻塞模式?

#6


引用 4 楼 xhk_xhk 的回复:
bool CServerSock::HandleData(CListCtrl& DataList, SOCKET Client) 

    int nlen = 0; 
    char buf[2048] = {0}; 
    USES_CONVERSION; 

    DataList.LockWindowUpdate(); 

    for(int i = 0; i < m_ClientNum; i++) 
    { 
        if (m_Clients[i] == Client) 
        { 
            buf[nlen] = NULL; 
            COM_HEAD *pComHead = new COM_HEAD; 
            memcpy(pComHead, &buf, …

是沾包了~~~ 不是CListCtrl的问题

引用 5 楼 hityct1 的回复:
recv后面要加上错误处理。另:是阻塞模式?

沾包了就是不知道怎么处理这个数据好.

#7


如果沾包这里怎么处理沾包数据?
nlen = recv(m_Clients[i],buf,sizeof(buf),0);

#8


引用 7 楼 DailyJob 的回复:
如果沾包这里怎么处理沾包数据? 

C/C++ codenlen = recv(m_Clients[i],buf,sizeof(buf),0);

通过协议里的标识分析接收缓冲区

#9


是不是内存数据分配失败了!

#10


不是接收端的问题,问题出在发送端
LZ发送端采用的应该是非阻塞模式,当send时出现10035时,接收端会出现错误

send时检测返回是否出现10035,出了重发就好了

非阻塞send 不会出现10035

#11


我在你的上个帖子中回复了,没看到吗?

#12


你发送的数据量不能超过512字节,分批发吧

#13


搞定. 谢谢大家
bool CServerSock::HandleData(CListCtrl& DataList, SOCKET Client)
{
const int nheadlen = sizeof(COM_HEAD);
int nlen = 0;
char buf[1024] = {0};
char head[nheadlen + 1] = {0};
USES_CONVERSION;

for(int i = 0; i < m_ClientNum; i++)
{
if (m_Clients[i] == Client)
{
nlen = recv(m_Clients[i],head,nheadlen,0);
if (nlen == nheadlen)
{
head[nlen] = NULL;
COM_HEAD *pComHead = new COM_HEAD;
memcpy(pComHead, &head, sizeof(COM_HEAD));
nlen = recv(m_Clients[i],buf,(pComHead->uTotalLen - nheadlen),0);
buf[nlen] = NULL;
TEST_LOGDATA *plogdata = (TEST_LOGDATA *)(buf);

DataList.InsertItem(0, A2T(plogdata->szDate));
DataList.SetItemText(0, 1, A2T(plogdata->szTime));
DataList.SetItemText(0, 2, A2T(plogdata->szName));
DataList.SetItemText(0, 3, A2T(plogdata->szMachineID));
DataList.SetItemText(0, 4, A2T(plogdata->szCardNum));
DataList.SetItemText(0, 5, A2T(plogdata->szWorkNumber));
DataList.SetItemText(0, 6, A2T(pComHead->szVersion));
DataList.SetItemText(0, 7, plogdata->uDirection?L"出门":L"进门");
delete pComHead;
pComHead = NULL;
}
}
}
return true;
}

#14


其实还没搞定,对于nlen!=nheadlen的情况没有处理。

#15


如果是非阻塞模式,recv的所接受的数据有可能不是你所期望的,需要多次调用,知道收到完整的数据。

#16


    参考我的文章:

 从一次Windows网络编程排错经历中得出的一个可靠拆包算法

http://blog.csdn.net/clever101/archive/2008/10/11/3054548.aspx

#1


这是多线程么?

DataList.InsertItem(0, A2T(plogdata->szDate));
DataList.SetItemText(0, 1, A2T(plogdata->szTime));
DataList.SetItemText(0, 2, A2T(plogdata->szName));
DataList.SetItemText(0, 3, A2T(plogdata->szMachineID));
DataList.SetItemText(0, 4, A2T(plogdata->szCardNum));
DataList.SetItemText(0, 5, A2T(plogdata->szWorkNumber));
DataList.SetItemText(0, 6, A2T(pComHead->szVersion));
DataList.SetItemText(0, 7, plogdata->uDirection?L"出门":L"进门");

这段代码需要同步吧。

#2


引用 1 楼 a_rockboy 的回复:
这是多线程么? 

DataList.InsertItem(0, A2T(plogdata->szDate)); 
DataList.SetItemText(0, 1, A2T(plogdata->szTime)); 
DataList.SetItemText(0, 2, A2T(plogdata->szName)); 
DataList.SetItemText(0, 3, A2T(plogdata->szMachineID)); 
DataList.SetItemText(0, 4, A2T(plogdata->szCardNum)); 
DataList.SetItemText(0, 5, A2T(plogdata->szWorkNumber)); 
DataList.SetItemText(0, 6, A2T(pComHead->szVersion)…

没用多线程. 这是往CLIstCtrl控件中插数据

#3


晕贴掉了一句!
bool CServerSock::HandleData(CListCtrl& DataList, SOCKET Client)
{
    int nlen = 0;
    char buf[2048] = {0};
    USES_CONVERSION;

    for(int i = 0; i < m_ClientNum; i++)
    {
        if (m_Clients[i] == Client)
        {
     nlen = recv(m_Clients[i],buf,sizeof(buf),0);
            buf[nlen] = NULL;
            COM_HEAD *pComHead = new COM_HEAD;
            memcpy(pComHead, &buf, sizeof(COM_HEAD));

            TEST_LOGDATA *plogdata = (TEST_LOGDATA *)(buf + sizeof(COM_HEAD));

            DataList.InsertItem(0, A2T(plogdata->szDate));
            DataList.SetItemText(0, 1, A2T(plogdata->szTime));
            DataList.SetItemText(0, 2, A2T(plogdata->szName));
            DataList.SetItemText(0, 3, A2T(plogdata->szMachineID));
            DataList.SetItemText(0, 4, A2T(plogdata->szCardNum));
            DataList.SetItemText(0, 5, A2T(plogdata->szWorkNumber));
            DataList.SetItemText(0, 6, A2T(pComHead->szVersion));
            DataList.SetItemText(0, 7, plogdata->uDirection?L"出门":L"进门");
            delete pComHead;
            pComHead = NULL;
        }
    }

#4


bool CServerSock::HandleData(CListCtrl& DataList, SOCKET Client)
{
    int nlen = 0;
    char buf[2048] = {0};
    USES_CONVERSION;

     DataList.LockWindowUpdate();

    for(int i = 0; i < m_ClientNum; i++)
    {
        if (m_Clients[i] == Client)
        {
            buf[nlen] = NULL;
            COM_HEAD *pComHead = new COM_HEAD;
            memcpy(pComHead, &buf, sizeof(COM_HEAD));

            TEST_LOGDATA *plogdata = (TEST_LOGDATA *)(buf + sizeof(COM_HEAD));

            DataList.InsertItem(0, A2T(plogdata->szDate));
            DataList.SetItemText(0, 1, A2T(plogdata->szTime));
            DataList.SetItemText(0, 2, A2T(plogdata->szName));
            DataList.SetItemText(0, 3, A2T(plogdata->szMachineID));
            DataList.SetItemText(0, 4, A2T(plogdata->szCardNum));
            DataList.SetItemText(0, 5, A2T(plogdata->szWorkNumber));
            DataList.SetItemText(0, 6, A2T(pComHead->szVersion));
            DataList.SetItemText(0, 7, plogdata->uDirection?L"出门":L"进门");
            delete pComHead;
            pComHead = NULL;
        }
    }

     DataList.UnlockWindowUpdate();
    return true;
}

#5


recv后面要加上错误处理。另:是阻塞模式?

#6


引用 4 楼 xhk_xhk 的回复:
bool CServerSock::HandleData(CListCtrl& DataList, SOCKET Client) 

    int nlen = 0; 
    char buf[2048] = {0}; 
    USES_CONVERSION; 

    DataList.LockWindowUpdate(); 

    for(int i = 0; i < m_ClientNum; i++) 
    { 
        if (m_Clients[i] == Client) 
        { 
            buf[nlen] = NULL; 
            COM_HEAD *pComHead = new COM_HEAD; 
            memcpy(pComHead, &buf, …

是沾包了~~~ 不是CListCtrl的问题

引用 5 楼 hityct1 的回复:
recv后面要加上错误处理。另:是阻塞模式?

沾包了就是不知道怎么处理这个数据好.

#7


如果沾包这里怎么处理沾包数据?
nlen = recv(m_Clients[i],buf,sizeof(buf),0);

#8


引用 7 楼 DailyJob 的回复:
如果沾包这里怎么处理沾包数据? 

C/C++ codenlen = recv(m_Clients[i],buf,sizeof(buf),0);

通过协议里的标识分析接收缓冲区

#9


是不是内存数据分配失败了!

#10


不是接收端的问题,问题出在发送端
LZ发送端采用的应该是非阻塞模式,当send时出现10035时,接收端会出现错误

send时检测返回是否出现10035,出了重发就好了

非阻塞send 不会出现10035

#11


我在你的上个帖子中回复了,没看到吗?

#12


你发送的数据量不能超过512字节,分批发吧

#13


搞定. 谢谢大家
bool CServerSock::HandleData(CListCtrl& DataList, SOCKET Client)
{
const int nheadlen = sizeof(COM_HEAD);
int nlen = 0;
char buf[1024] = {0};
char head[nheadlen + 1] = {0};
USES_CONVERSION;

for(int i = 0; i < m_ClientNum; i++)
{
if (m_Clients[i] == Client)
{
nlen = recv(m_Clients[i],head,nheadlen,0);
if (nlen == nheadlen)
{
head[nlen] = NULL;
COM_HEAD *pComHead = new COM_HEAD;
memcpy(pComHead, &head, sizeof(COM_HEAD));
nlen = recv(m_Clients[i],buf,(pComHead->uTotalLen - nheadlen),0);
buf[nlen] = NULL;
TEST_LOGDATA *plogdata = (TEST_LOGDATA *)(buf);

DataList.InsertItem(0, A2T(plogdata->szDate));
DataList.SetItemText(0, 1, A2T(plogdata->szTime));
DataList.SetItemText(0, 2, A2T(plogdata->szName));
DataList.SetItemText(0, 3, A2T(plogdata->szMachineID));
DataList.SetItemText(0, 4, A2T(plogdata->szCardNum));
DataList.SetItemText(0, 5, A2T(plogdata->szWorkNumber));
DataList.SetItemText(0, 6, A2T(pComHead->szVersion));
DataList.SetItemText(0, 7, plogdata->uDirection?L"出门":L"进门");
delete pComHead;
pComHead = NULL;
}
}
}
return true;
}

#14


其实还没搞定,对于nlen!=nheadlen的情况没有处理。

#15


如果是非阻塞模式,recv的所接受的数据有可能不是你所期望的,需要多次调用,知道收到完整的数据。

#16


    参考我的文章:

 从一次Windows网络编程排错经历中得出的一个可靠拆包算法

http://blog.csdn.net/clever101/archive/2008/10/11/3054548.aspx