我用TCP/IP建立了C/S结构。
客户端首先发数据,服务端等40MS后给客户端发数据。
客户端没100MS检查是否收到数据,收到就给服务器发。
循环执行。大部分情况都很好,只是出现一个怪现象。
没隔10分钟,就会出现收不到数据的情况。发现每隔10分钟,SOCKET会缓存几拍一起发送。我已经设置SOKET为NO_DELAY发送了,还是不行。各位大虾,给点意见吧。服务端建立程序如下:
/* The WinSock DLL is acceptable. Proceed. */
GROUP g = 0;
//
sServer = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, g, 0);
//sServer = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, WSA_FLAG_OVERLAPPED); //创建套接字
sockaddr_in sockAddr;

memset(&sockAddr, 0, sizeof(sockaddr_in));
sockAddr.sin_family = AF_INET;
    sockAddr.sin_port = htons(SerPort);
sockAddr.sin_addr.S_un.S_addr = inet_addr(IPAddr);

int ret = bind(sServer, (sockaddr*)(&sockAddr), sizeof(sockaddr_in)); if (ret != 0)
{
return CTEC_BINDERR;
}
else
{
DWORD dwBytesReturned = 0;
BOOL bNewBehavior = TRUE; //ture 非阻塞 false 阻塞
DWORD status;
// disable  new behavior using
// IOCTL: SIO_UDP_CONNRESET
status = WSAIoctl(sServer, FIONBIO,
&bNewBehavior, sizeof(bNewBehavior),
NULL, 0, &dwBytesReturned,
NULL, NULL); if (SOCKET_ERROR == status)
{
DWORD dwErr = WSAGetLastError();
if (WSAEWOULDBLOCK == dwErr)
{
// nothing to do
return 0;
}
else
{
return 0;
}
} int killnagle = 0;
int result = setsockopt(sServer, IPPROTO_IP, TCP_NODELAY, (const char*)&killnagle, sizeof(int)); if (result != 0)
{
return 0;
} setsockopt(sServer,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
setsockopt(sServer,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));

listen(sServer, 1);客户端建立如下:
GROUP g = 0;
// sClient = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, g, 0);
sClient = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, g, 0); sockaddr_in dstAddr;
dstAddr.sin_family = AF_INET;
dstAddr.sin_addr.S_un.S_addr = inet_addr(sServerAddr);
dstAddr.sin_port = htons(uSerPort); int ret = WSAConnect(sClient, (sockaddr*)(&dstAddr), sizeof(SOCKADDR), NULL, NULL,NULL, NULL ); if (ret == 0)
{
pClientRecvBuffer = new char[MAX_DATA_LEN];
memset(pClientRecvBuffer, 0, MAX_DATA_LEN);

DWORD dwBytesReturned = 0;
BOOL bNewBehavior = TRUE; //ture Not blocking false blocking
DWORD status;
// disable  new behavior using
// IOCTL: SIO_UDP_CONNRESET
status = WSAIoctl(sClient, FIONBIO,
&bNewBehavior, sizeof(bNewBehavior),
NULL, 0, &dwBytesReturned,
NULL, NULL); if (SOCKET_ERROR == status)
{
DWORD dwErr = WSAGetLastError();
if (WSAEWOULDBLOCK == dwErr)
{
// nothing to do
return 0;
}
else
{
return 0;
}
} int killnagle = 0;
int result = setsockopt(sClient, IPPROTO_IP, TCP_NODELAY, (const char*)&killnagle, sizeof(int)); if (result != 0)
{
return 0;
} setsockopt(sClient,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
setsockopt(sClient,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));

解决方案 »

  1.   

    100M局域网,可以说没有其他干扰。
    就两台电脑,1个HUB,相连。数据量在100K左右。10分钟的规律最疑惑了,用UDP也是这种效果,10分钟必丢一包。
      

  2.   

    目前是:
    nSendBuf = 1024*1024
    nRecvBuf = 1024*1024
    setsockopt(sClient,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int)); 
    setsockopt(sClient,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));如果改成:
    nSendBuf = 0
    nRecvBuf = 0
    setsockopt(sClient,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int)); 
    setsockopt(sClient,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));根本就通不起来,发送和接收都非常缓慢。
      

  3.   

    所有代码:#include "stdafx.h"
    #define INFO_SIZE 50
    #define MAX_DATA_LEN (500*1024)
    #define RECV_ONE_PACKET (500*1024)const int nSendBuf = 1024*1024;
    const int nRecvBuf = 1024*1024;HANDLE hExitEvent = NULL;char *pServerRecvBuffer = NULL;
    int g_iServerRecvLen = 0;
    char *pClientRecvBuffer = NULL;
    int g_iClientRecvLen = 0;BOOL bSvrDataOK = FALSE;
    BOOL bClientDataOK = FALSE;SOCKET sServer = INVALID_SOCKET;
    SOCKET sServer_Connected = INVALID_SOCKET;
    SOCKET sClient = INVALID_SOCKET;DWORD WINAPI AcceptThread(LPVOID lpParam);
    DWORD WINAPI SvrRecvThread(LPVOID lpParam);
    DWORD WINAPI ClientRecvThread(LPVOID lpParam);BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
     )
    {
    //初始化TCP/IP
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;

    wVersionRequested = MAKEWORD( 2, 2 );

    err = WSAStartup( wVersionRequested, &wsaData );
    if ( err != 0 ) {
    /* Tell the user that we could not find a usable */
    /* WinSock DLL.                                  */
    return 1;
    }

    /* Confirm that the WinSock DLL supports 2.2.*/
    /* Note that if the DLL supports versions greater    */
    /* than 2.2 in addition to 2.2, it will still return */
    /* 2.2 in wVersion since that is the version we      */
    /* requested.                                        */

    if ( LOBYTE( wsaData.wVersion ) != 2 ||
    HIBYTE( wsaData.wVersion ) != 2 ) {
    /* Tell the user that we could not find a usable */
    /* WinSock DLL.                                  */
    WSACleanup( );
    return 1; 
    } //退出事件
    hExitEvent = CreateEvent(NULL,FALSE,FALSE,NULL);    return TRUE;
    }void CALLBACK OnAccept(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2) 

        SetEvent((HANDLE)dwUser);
    } DWORD WINAPI AcceptThread(LPVOID lpParam)
    {
    TIMECAPS tc; 
    MMRESULT mmres;
        if ( timeGetDevCaps(&tc,sizeof(tc))!=TIMERR_NOERROR )

    FILE* fp = NULL;
    fp = fopen(".\\TCP_CTEC.log","a+");
    char info[INFO_SIZE];
    memset(info, 0, INFO_SIZE);
    sprintf(info, "%s\n", "Can't get accept multimedia timer resolution");
    fwrite(info,1,INFO_SIZE,fp);
    fclose(fp);
    fp = NULL;
    return 0;

        
    HANDLE hSleep = CreateEvent(NULL,FALSE,FALSE,NULL); if ( !(mmres=timeSetEvent(1000, tc.wPeriodMin, OnAccept, (DWORD)hSleep, TIME_PERIODIC)))

    return 0;
    } while (1)
    {
    int iExit = WaitForSingleObject(hExitEvent,0);
    if(iExit==WAIT_OBJECT_0)
    {
    break;
    } DWORD res = WaitForMultipleObjects(1,&hSleep,FALSE,INFINITE);
    sockaddr_in srcAddr;
    int nAddrLen = sizeof(sockaddr);
    SOCKET sAccetpTemp = WSAAccept(sServer, (sockaddr*)(&srcAddr), &nAddrLen, NULL, 0);

    if (sAccetpTemp != INVALID_SOCKET)
    {
    sServer_Connected = sAccetpTemp;
    setsockopt(sServer_Connected,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
    setsockopt(sServer_Connected,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
    }
    } timeKillEvent(mmres);
    CloseHandle(hSleep);
    hSleep = NULL; return 1;
    }
    void CALLBACK OnSvrRecv(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2) 

        SetEvent((HANDLE)dwUser);
    } DWORD WINAPI SvrRecvThread(LPVOID lpParam)
    {
    //设置1毫秒定时器
    TIMECAPS tc; 
    MMRESULT mmres;
        if ( timeGetDevCaps(&tc,sizeof(tc))!=TIMERR_NOERROR )

    FILE* fp = NULL;
    fp = fopen(".\\TCP_CTEC.log","a+");
    char info[INFO_SIZE];
    memset(info, 0, INFO_SIZE);
    sprintf(info, "%s\n", "Can't get svr recv multimedia timer resolution");
    fwrite(info,1,INFO_SIZE,fp);
    fclose(fp);
    fp = NULL;
    return 0;

        //设置事件
    HANDLE hSleep = CreateEvent(NULL,FALSE,FALSE,NULL);
    //启动定时器
    if ( !(mmres=timeSetEvent(1, tc.wPeriodMin, OnSvrRecv, (DWORD)hSleep, TIME_PERIODIC)))

    return 0;
    } //接收缓冲区
    WSABUF lpBuffers[1];
    lpBuffers[0].buf = new char[RECV_ONE_PACKET];
    lpBuffers[0].len = RECV_ONE_PACKET;
    DWORD dwNumberOFBytesRecved = 0;

    int nRet = 0;
    DWORD dwFlag = 0; while (1)
    {
    int iExit = WaitForSingleObject(hExitEvent,0);
    if(iExit==WAIT_OBJECT_0)
    {
    break;
    } DWORD res = WaitForMultipleObjects(1,&hSleep,FALSE,INFINITE); //获取一包,得到头,用于判断是否获取完全
    nRet = WSARecv(sServer_Connected, lpBuffers, 1, &dwNumberOFBytesRecved, &dwFlag, NULL, NULL);
    if (nRet == 0 && pServerRecvBuffer != NULL && dwNumberOFBytesRecved > 0)
    {
    //获取实际数据长度
    int iDataSize = *(int*)lpBuffers[0].buf;
    //拷贝数据,去掉数据长度
    memcpy(pServerRecvBuffer, lpBuffers[0].buf+sizeof(int), dwNumberOFBytesRecved-sizeof(int));
    g_iServerRecvLen += dwNumberOFBytesRecved-sizeof(int); //再获取全部
    while (g_iServerRecvLen < iDataSize)
    {
    nRet = WSARecv(sServer_Connected, lpBuffers, 1, &dwNumberOFBytesRecved, &dwFlag, NULL, NULL);
    if(nRet == 0 && pServerRecvBuffer != NULL && dwNumberOFBytesRecved > 0)
    {
    memcpy(pServerRecvBuffer+g_iServerRecvLen, lpBuffers[0].buf, dwNumberOFBytesRecved);
    g_iServerRecvLen += dwNumberOFBytesRecved; if(g_iServerRecvLen == iDataSize)
    {
    break;
    }
    }
    else
    {
    // int nError = WSAGetLastError();
    // wsprintf(msgBuf, "WSARecv failed, error:%d \n", nError);
    // OutputDebugString(msgBuf);
    }
    } bSvrDataOK = TRUE;
    }
    }
    timeKillEvent(mmres);
    CloseHandle(hSleep);
    hSleep = NULL;
    delete []lpBuffers[0].buf;
    lpBuffers[0].buf = NULL;
    return 1;
    }
      

  4.   

    DWORD WINAPI ClientRecvThread(LPVOID lpParam)
    {
    TIMECAPS tc; 
    MMRESULT mmres;
        if ( timeGetDevCaps(&tc,sizeof(tc))!=TIMERR_NOERROR )

    FILE* fp = NULL;
    fp = fopen(".\\TCP_CTEC.log","a+");
    char info[INFO_SIZE];
    memset(info, 0, INFO_SIZE);
    sprintf(info, "%s\n", "Can't get client recv multimedia timer resolution");
    fwrite(info,1,INFO_SIZE,fp);
    fclose(fp);
    fp = NULL;
    return 0;

        
    HANDLE hSleep = CreateEvent(NULL,FALSE,FALSE,NULL); if ( !(mmres=timeSetEvent(1, tc.wPeriodMin, OnSvrRecv, (DWORD)hSleep, TIME_PERIODIC)))

    return 0;
    } WSABUF lpBuffers[1];
    lpBuffers[0].buf = new char[RECV_ONE_PACKET];
    lpBuffers[0].len = RECV_ONE_PACKET;
    DWORD dwNumberOFBytesRecved = 0; int nRet = 0;
    DWORD dwFlag = 0; while (1)
    {
    int iExit = WaitForSingleObject(hExitEvent,0);
    if(iExit==WAIT_OBJECT_0)
    {
    break;
    } DWORD res = WaitForMultipleObjects(1,&hSleep,FALSE,INFINITE); //获取一包,得到头,用于判断是否获取完全
    nRet = WSARecv(sClient, lpBuffers, 1, &dwNumberOFBytesRecved, &dwFlag, NULL, NULL);

    if (nRet == 0 && pClientRecvBuffer != NULL &&dwNumberOFBytesRecved > 0)
    {
    int iDataSize = *(int*)lpBuffers[0].buf;
    //拷贝数据
    memcpy(pClientRecvBuffer, lpBuffers[0].buf+sizeof(int), dwNumberOFBytesRecved-sizeof(int));
    g_iClientRecvLen += dwNumberOFBytesRecved-sizeof(int); //再获取全部
    while (g_iClientRecvLen < iDataSize)
    {
    nRet = WSARecv(sClient, lpBuffers, 1, &dwNumberOFBytesRecved, &dwFlag, NULL, NULL);
    if(nRet == 0 && pClientRecvBuffer != NULL &&dwNumberOFBytesRecved > 0)
    {
    memcpy(pClientRecvBuffer+g_iClientRecvLen, lpBuffers[0].buf, dwNumberOFBytesRecved);
    g_iClientRecvLen += dwNumberOFBytesRecved;
    if(g_iClientRecvLen == iDataSize)
    {
    break;
    }
    }
    else
    {
    // int nError = WSAGetLastError();
    // wsprintf(msgBuf, "WSARecv failed, error:%d \n", nError);
    // OutputDebugString(msgBuf);
    }
    }

    bClientDataOK = TRUE;
    }
    }
    timeKillEvent(mmres);
    CloseHandle(hSleep);
    hSleep = NULL;
    delete []lpBuffers[0].buf;
    lpBuffers[0].buf = NULL;
    return 1;
    }extern "C" _declspec(dllexport) int InitServer(LPCSTR IPAddr, UINT SerPort)
    {
    /* The WinSock DLL is acceptable. Proceed. */
    GROUP g = 0;
    //
    sServer = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, g, 0);
    //sServer = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, WSA_FLAG_OVERLAPPED); //创建套接字
    sockaddr_in sockAddr;

    memset(&sockAddr, 0, sizeof(sockaddr_in));
    sockAddr.sin_family = AF_INET;
        sockAddr.sin_port = htons(SerPort);
    sockAddr.sin_addr.S_un.S_addr = inet_addr(IPAddr);

    int ret = bind(sServer, (sockaddr*)(&sockAddr), sizeof(sockaddr_in)); if (ret != 0)
    {
    return CTEC_BINDERR;
    }
    else
    {
    DWORD dwBytesReturned = 0;
    BOOL bNewBehavior = TRUE; //ture 非阻塞 false 阻塞
    DWORD status;
    // disable  new behavior using
    // IOCTL: SIO_UDP_CONNRESET
    status = WSAIoctl(sServer, FIONBIO,
    &bNewBehavior, sizeof(bNewBehavior),
    NULL, 0, &dwBytesReturned,
    NULL, NULL); if (SOCKET_ERROR == status)
    {
    DWORD dwErr = WSAGetLastError();
    if (WSAEWOULDBLOCK == dwErr)
    {
    // nothing to do
    return 0;
    }
    else
    {
    return 0;
    }
    } int killnagle = 0;
    int result = setsockopt(sServer, IPPROTO_IP, TCP_NODELAY, (const char*)&killnagle, sizeof(int)); if (result != 0)
    {
    return 0;
    } setsockopt(sServer,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
    setsockopt(sServer,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));

    listen(sServer, 1);
    ret = CTEC_SUCCESS; pServerRecvBuffer = new char[MAX_DATA_LEN];
    memset(pServerRecvBuffer, 0, MAX_DATA_LEN); //起一个线程监听
    DWORD dwAcceptThreadID = 0;
    HANDLE hAcceptThread = CreateThread(NULL, 0, AcceptThread, 0, 0, &dwAcceptThreadID);

    //起一个数据接收线程
    DWORD dwRecvThreadID = 0;
    HANDLE hRecvThread = CreateThread(NULL, 0, SvrRecvThread, 0, 0, &dwRecvThreadID);

    if(!SetThreadPriority(hRecvThread, THREAD_PRIORITY_TIME_CRITICAL))
    {
    FILE* fp = NULL;
    fp = fopen(".\\TCP_CTEC.log","a+");
    char info[INFO_SIZE];
    memset(info, 0, INFO_SIZE);
    sprintf(info, "%s\n", "Set the SVR recv thread failed!");
    fwrite(info,1,INFO_SIZE,fp);
    fclose(fp);
    fp = NULL;
    return 0;
    }

    return sServer;
    }
    }
    extern "C" _declspec(dllexport) int RecvData(char * RevData, int DataLen,UINT uSocket)
    {
    int ret = 0; if (uSocket == sServer)
    {
    if (DataLen >= g_iServerRecvLen)
    {
    if (g_iServerRecvLen > 0 && bSvrDataOK)
    {
    memcpy(RevData, pServerRecvBuffer, g_iServerRecvLen);
    ret = g_iServerRecvLen;
    g_iServerRecvLen = 0;
    bSvrDataOK = FALSE;
    }
    else
    ret = CTEC_TIMEOUT;
    }
    else
    ret = CTEC_SOCKETERR_GETDATALEN;
    }
    else if (uSocket == sClient)
    {
    if (DataLen >= g_iClientRecvLen)
    {
    if (g_iClientRecvLen > 0 && bClientDataOK)
    {
    memcpy(RevData, pClientRecvBuffer, g_iClientRecvLen);
    ret = g_iClientRecvLen;
    g_iClientRecvLen = 0;
    bClientDataOK = FALSE;
    }
    else
    ret = CTEC_TIMEOUT;
    }
    else
    ret = CTEC_SOCKETERR_GETDATALEN;
    }
    else
    ret = CTEC_SOCKETERR; return ret;
    }
    extern "C" _declspec(dllexport) int Exit_Server(UINT uSocket)
    {
    if (hExitEvent != NULL)
    {
    SetEvent(hExitEvent);
    //等待处理结束
    Sleep(1000);
    CloseHandle(hExitEvent);
    hExitEvent = NULL;
    } delete []pServerRecvBuffer;
    pServerRecvBuffer = NULL;

    if (sServer_Connected != INVALID_SOCKET)
    closesocket(sServer_Connected);
    if (sServer != INVALID_SOCKET)
    closesocket(sServer);
    return 0;
    }
    extern "C" _declspec(dllexport) int InitClient(LPCSTR sServerAddr, UINT uSerPort)
    {
    GROUP g = 0;
    // sClient = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, g, 0);
    sClient = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, g, 0); sockaddr_in dstAddr;
    dstAddr.sin_family = AF_INET;
    dstAddr.sin_addr.S_un.S_addr = inet_addr(sServerAddr);
    dstAddr.sin_port = htons(uSerPort); int ret = WSAConnect(sClient, (sockaddr*)(&dstAddr), sizeof(SOCKADDR), NULL, NULL,NULL, NULL ); if (ret == 0)
    {
    pClientRecvBuffer = new char[MAX_DATA_LEN];
    memset(pClientRecvBuffer, 0, MAX_DATA_LEN);

    DWORD dwBytesReturned = 0;
    BOOL bNewBehavior = TRUE; //ture Not blocking false blocking
    DWORD status;
    // disable  new behavior using
    // IOCTL: SIO_UDP_CONNRESET
    status = WSAIoctl(sClient, FIONBIO,
    &bNewBehavior, sizeof(bNewBehavior),
    NULL, 0, &dwBytesReturned,
    NULL, NULL); if (SOCKET_ERROR == status)
    {
    DWORD dwErr = WSAGetLastError();
    if (WSAEWOULDBLOCK == dwErr)
    {
    // nothing to do
    return 0;
    }
    else
    {
    return 0;
    }
    } int killnagle = 0;
    int result = setsockopt(sClient, IPPROTO_IP, TCP_NODELAY, (const char*)&killnagle, sizeof(int)); if (result != 0)
    {
    return 0;
    } setsockopt(sClient,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));
    setsockopt(sClient,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int)); /*for test
    DWORD dwNumberOFBytesSent = 0;
    WSABUF lpBuffers[1];
    //长度需要加个头,表示长度
    lpBuffers[0].buf = new char[MAX_DATA_LEN];
    memset(lpBuffers[0].buf, 0, MAX_DATA_LEN);
    *(int*)(lpBuffers[0].buf) = MAX_DATA_LEN - sizeof(int);
    lpBuffers[0].len = MAX_DATA_LEN;
    ret = WSASend(sClient, lpBuffers, 1, &dwNumberOFBytesSent, 0, NULL, NULL );
    */

    //起一个数据接收线程
    DWORD dwRecvThreadID = 0;
    HANDLE hRecvThread = CreateThread(NULL, 0, ClientRecvThread, 0, 0, &dwRecvThreadID);

    if(!SetThreadPriority(hRecvThread, THREAD_PRIORITY_TIME_CRITICAL))
    {
    FILE* fp = NULL;
    fp = fopen(".\\TCP_CTEC.log","a+");
    char info[INFO_SIZE];
    memset(info, 0, INFO_SIZE);
    sprintf(info, "%s\n", "Set the Client recv thread failed!");
    fwrite(info,1,INFO_SIZE,fp);
    fclose(fp);
    fp = NULL;
    return 0;
    }

    return sClient;
    }
    else
    return CTEC_CONNECTTIONERR;}
    extern "C" _declspec(dllexport) int SendData(char * cData, int iDataLen ,int *uSocket)
    {
    WSABUF lpBuffers[1];
    //长度需要加个头,表示长度
    lpBuffers[0].buf = new char[iDataLen+sizeof(int)];
    lpBuffers[0].len = iDataLen + sizeof(int); //将数据长度放在头4个字节
    memcpy(lpBuffers[0].buf, &iDataLen, sizeof(int));
    //拷真正的数据
    memcpy(lpBuffers[0].buf+sizeof(int), cData, iDataLen); DWORD dwNumberOFBytesSent = 0; int ret = 0;
    if (*uSocket == sClient)
    {
    ret = WSASend(sClient, lpBuffers, 1, &dwNumberOFBytesSent, 0, NULL, NULL );
    }
    else if (*uSocket == sServer)
    {
    ret = WSASend(sServer_Connected, lpBuffers, 1, &dwNumberOFBytesSent, 0, NULL, NULL );
    } if (dwNumberOFBytesSent != iDataLen + sizeof(int))
    ret = CTEC_TIMEOUT; delete []lpBuffers[0].buf;
    lpBuffers[0].buf = NULL;
    return ret;

    }
    extern "C" _declspec(dllexport) int Exit_Client(UINT uSocket)
    {
    if (hExitEvent != NULL)
    {
    SetEvent(hExitEvent);
    //等待处理结束
    Sleep(1000);
    CloseHandle(hExitEvent);
    hExitEvent = NULL;
    } delete []pClientRecvBuffer;
    pClientRecvBuffer = NULL;

    if(sClient != INVALID_SOCKET)
    closesocket(sClient);
    return 0;
    }
      

  5.   

    一个40ms,一个100ms,这样等?
    不扑空才怪!
    都不要看代码都可知楼主的问题了,帖那长代码干嘛?
      

  6.   

    不怎么会扑空呢?
    也就是说,客户端发给服务器端,服务端40MS后反馈给客户端。
    问题是客户端有时候要超过100MS后才能收到。不正常。