客户端断开服务端就会产生异常并断开

WIN10上开发一个服务端程序,它能监听来自多个客户端的请求并连接,其中客户端会往服务端传送文件,使用SOCKET tcp协议。现在是每次客户端发送完文件后,服务端也能正常接收完文件,但接收完后就会产生异常退出。是开的线程来运行接收函数,现在要怎样定位问题呢?exe直接退出要应该怎么抓取log呢? 接收部分代码如下:
DWORD CClient::RecvDataThread(void* pParam)
{
CClient pClient = (CClient)pParam; //pointer to client
int reVal; //return value
char temp[MAX_NUM_BUF]; //temp value

WriteToLog("RecvDataThread");
cout <<"RecvDataThread"<<endl;

while(pClient->m_bConning)              //connection status
{   
//  if(!pClient->m_bSendConnectionSuccess)
//  {
//      break;
//  }
    cout <<"pClient->m_bConning"<<endl;
    memset(temp, 0, MAX_NUM_BUF);
    reVal = recv(pClient->m_socket, temp, MAX_NUM_BUF, 0);  //receive data

    //handle error return values
    if (SOCKET_ERROR == reVal)
    {
        int nErrCode = WSAGetLastError();

        if ( WSAEWOULDBLOCK == nErrCode )   //receive data buffer is invalid
        {
            continue;                       //continue loop
        }else if (WSAENETDOWN == nErrCode ||//client close connection
                 WSAETIMEDOUT == nErrCode ||
                WSAECONNRESET == nErrCode )
        {
            break;                          //thread exit
        }
    }

    //client close the connection
    if ( reVal == 0)
    {
        break;
    }

    //receive data
    if (reVal > 0)
    {
        cout <<"reVal > 0"<<endl;
        EnterCriticalSection(&pClient->m_cs);
        char *pClientIP = inet_ntoa(pClient->m_addr.sin_addr);
        u_short  clientPort = ntohs(pClient->m_addr.sin_port);
    //  cout<<"IP: "<<pClientIP<<"\tPort: "<<clientPort<<":"<<temp<<endl;      //output and show data
        WriteToLog(temp);
        char file_name[MAX_NUM_BUF];
        char *pfile = temp; // indicate path
        memset(file_name, 0, MAX_NUM_BUF);
        strncpy_s(file_name, "F:\\receive\\", strlen("F:\\receive\\"));
        int file_len = strlen(temp), i = 0, tem = 0;

        for (i = 0; i < file_len; i++)
        {
            if (strncmp(pfile + file_len - 1 -i, "\\", 1))  //if equal, return 0; else, return Positive
            {
                tem++;
                continue; //not equal
            }
            else // if equal, strcat path after \\  to file_name, it's exact length of path after 
                {
                    strncat_s(file_name, pfile + file_len - i, i);
                    break;
                }
        }

        if (tem == file_len)
        {
            strncat_s(file_name, temp, strlen(temp) > 1024 ? 1024 : strlen(temp));
        }

        FILE *fp;
        fopen_s(&fp, file_name, "wb");
        int len = send(pClient->m_socket, "Ready to send", strlen("Ready to send") + 1, 0);
        memset(sendMsgLogA, 0, 1024);
        sprintf_s(sendMsgLogA, "%s%d", "send size: ", len );
        WriteToLog(sendMsgLogA);

        char datalength[20];
        long int length = 0;
        int lenRecv = recv(pClient->m_socket, datalength, 21, 0);  //send file size from Client
        length = atol(datalength);

        memset(sendMsgLogA, 0, 1024);
        sprintf_s(sendMsgLogA, "%s%ld%s%ld", "file size: ", length, " recv size:", lenRecv);
        WriteToLog(sendMsgLogA);                //ready to send

        double cent = 0.0;
        char receiveBuf[SIZE];
        long int x = 0;
        while (1)
        {           
            cout <<"while (1)"<<endl;
            x = x + SIZE;  //SIZE scope is from -128 to 127
            if (x < length) // ZJX
            {
                cent = (double)x*100.0 / (double)length;
                memset(sendMsgLogA, 0, 1024);
                sprintf_s(sendMsgLogA, "%s%4.2f", "have received: ", cent);
                WriteToLog(sendMsgLogA);                //ready to send
                recv(pClient->m_socket, receiveBuf, SIZE + 1, 0);      //recv SIZE files
                fwrite(receiveBuf, 1, SIZE, fp);             //write SIZE files into receiveBuf, and continue to loop
            }
            else  //excute the function directory while files is smaller, and loop exit
            {
                recv(pClient->m_socket, receiveBuf, length + SIZE - x + 1, 0);
                fwrite(receiveBuf, 1, length + SIZE - x, fp);
                fclose(fp);                     
                WriteToLog("file received done");
                break;
            }

        }
    }
    WriteToLog("out of reVal>0");

    LeaveCriticalSection(&pClient->m_cs);
    WriteToLog("out of LeaveCriticalSection");
    memset(temp, 0, MAX_NUM_BUF);   //clean up temp variables
}

WriteToLog("out of pClient->m_bConning");
pClient->m_bConning = FALSE;            //disconnect with client
return 0;                               //thread exit

}


7个回答

那你打断点看是哪里运行出错了?肯定有地方异常了

大概流程是:客户端一连接上服务端,服务端就发送“Connect To Server Successfully”,之后客户端会给服务端发送要发送文件的地址和文件名,服务端在接收到地址和文件名后,会解析,解析完后只得到文件名,并在F:/receive目录下生成该文件名,文件名生成完后就发送"Ready to send"到客户端,客户端接收到该字符串后,就开始发送文件,服务端就也同时开始接收该文件,接收文件大小不同就按代码中条件分别处理。这些流程下来,一切都正常,能在F:/receive下得到客户端传过来的文件,但文件传输完成后,服务端程序也会马上弹出异常退出。最后的log中打印WriteToLog("out of pClient->m_bConning"); 也能在log文件中看到,说明这里不是导致服务exe退出的原因。像这样的问题要怎么分析呢?百度说的太杂了。有没有专业人士给个方向。多谢!!!

服务端EXE异常退出时

打印的log文件 等待大神降临指导!

看看是不是传输文件大小的问题

客户端手动断开前,手动关闭网络,如果是异常断开,连接通道断开,肯定是会报出异常的,你把这个异常捕获到再进行处理就可以了。

liuyunpeng07
liuyunpeng07 回复caoco: 可以
2 年多之前 回复

打断点跟了下,出现不同的原因,都是缓冲指针为野指针的错误。现在已经改好了,谢谢各位!

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐