我做一个客户/服务器程序,用的是CSocket类,我从一些书上看到一般的做法是在服务器端先建立一个监听的类,然后进行监听,收到客户端的Connect后,新生成个CSocket的子类进行接收。我的程序是这样,多个客户端向server发送数据,服务器收到数据后进行处理在存入数据库。现在遇到的问题是客户端发送的数据又多又快,服务器收到数据后来不及处理,造成数据丢失。虽然可以用sleep一下,但这只适用与一个客户端。请问有什么方法可以解决这一问题?

解决方案 »

  1.   

    1 收到客户端的Connect后,新生成个CSocket的子类进行接收。我的程序是这样,多个客户端向server发送数据,服务器收到数据后进行处理在存入数据库。请问,你使用的是多线程吗?
    2 请问,是TCP 吗?
      

  2.   

    我用的不是多线程,是从多台客户机发送的数据。
    接收的函数如下:
    void CMainFrame::ReceiveData(CClientSocket *pClientSocket)
    {
        char pData[10000],tempData[1000];
    int ByteCount;
    int EndFlag=0; strcpy(pData,"");
    do
    {
    strcpy(tempData,"");
    ByteCount=pClientSocket->Receive(tempData,1000);
    if(ByteCount>1000||ByteCount<=0)
    {
    MessageBox("接收网络信息错误!","网络信息",MB_OK);
    return;
    }
    else if(ByteCount<1000&&ByteCount>0)
    {
    EndFlag=1;
    }
    tempData[ByteCount]='\0';
    strcpy(pData,tempData);
    }while(EndFlag==0);
    DealWithData((unsigned char*)pData);//在这个函数中处理数据
    }我对多线程不太了解,请问如果将DealWithData这个函数变成线程,参数(即接收到的数据)如何传递?
      

  3.   

    void CMainFrame::ReceiveData(CClientSocket *pClientSocket)
    {
        char pData[10000],tempData[1000];
    int ByteCount;
    int EndFlag=0; strcpy(pData,"");
    do
    {
    strcpy(tempData,"");
    ByteCount=pClientSocket->Receive(tempData,1000);
    if(ByteCount>1000||ByteCount<=0)
    {
    MessageBox("接收网络信息错误!","网络信息",MB_OK);
    return;
    }
    else if(ByteCount<1000&&ByteCount>0)
    {
    EndFlag=1;
    }
    tempData[ByteCount]='\0';
    strcpy(pData,tempData);
    }while(EndFlag==0);
    //DealWithData((unsigned char*)pData);//在这个函数中处理据

    //{{每接受一个 socket 开一个 select 线程
        DWORD  dwThreadId; 
        HANDLE hThread;     hThread = CreateThread( 
            NULL,                        // no security attributes 
            0,                           // use defaultstack size  
            HandleThread,                // 线程函数名 
            (LPVOID)((unsigned char*)pData,  //参数
            0,                           // use default creation flags 
            &dwThreadId);                // returns the 
                                         //threadidentifier 
     
    //检验返回值 
    ASSERT(hThread != NULL) ;
    //}}每接受一个 ,开一个 handle 线程}DWORD WINAPI HandleThread(LPVOID pParam)
    {
       if(pParam == NULL)
       {
         return ;
       }
       (unsigned char*) pData = (unsigned char*)pParam;
       DealWithData((unsigned char*)pData);//在这个函数中处理数据
    }
          
    大体上可以这样,也许还需要同步。
      

  4.   

    肯定是你的程序问题。tcp本来就有流量控制能力,客户发得快,服务器来不及收的问题不可能存在。如果服务器处理慢了,tcp会通过0窗口通告抑制客户端发送速率。
      

  5.   

    谢谢HongHuer的帮助,可是又有了新的问题,线程都开了,但数据还是存的不全。
    回zengpan_panpan,我是指服务器都收到了,但来不及处理。因为我在客户端上试了,如果加入Sleep(50),数据就存全了。
      

  6.   

    那还是程序问题啊,如果来不及处理数据怎么能继续收呢?要把程序写好怎么能用Sleep去应付问题?
      

  7.   

    你现在的情况,我个人认为服务器端要使用模型了。
    有 select 模型等(在《windows 网络编程技术》中有详细描述)模型。我对select模型有一点点认识。
    (我写的局域网的聊天室在 csdn 的软件中,是原码,多线程,select模型,vc++ MFC)
    如果你需要,可以去下来看看。在 server 端:
    每个 client 对应一个线程。
    这样处理应该不会再有问题,效率也会提高的。
      

  8.   

    我想是需要同步的.
    比如客户端发送完了后等待接受端接受完后发个确认过来再继续发会好些.
    服务端:  
    RECV       SEND
    客户端:  
    SEND       RECV
      

  9.   

    唉,真是郁闷!问题又是一大堆。收一个数就开一个线程后,出现了数据不全和数据重复的现象。奇怪的是,如果我在最初的程序里DealWithData函数前加上个MessageBox,数据就存全了,如果不加就存不全。我想可能是调用的函数耗时太多了(拆字符串,还要到数据库里查询,无重复记录才能存入)!
      

  10.   

    问题还是没有解决!!!!!!!!!
    help me!
    为什么象HongHuer建议的那样接到一个数据就开一个线程会出现这样的问题:DealWithData()函数处理的数据是重复的?