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
}
那你打断点看是哪里运行出错了?肯定有地方异常了
大概流程是:客户端一连接上服务端,服务端就发送“Connect To Server Successfully”,之后客户端会给服务端发送要发送文件的地址和文件名,服务端在接收到地址和文件名后,会解析,解析完后只得到文件名,并在F:/receive目录下生成该文件名,文件名生成完后就发送"Ready to send"到客户端,客户端接收到该字符串后,就开始发送文件,服务端就也同时开始接收该文件,接收文件大小不同就按代码中条件分别处理。这些流程下来,一切都正常,能在F:/receive下得到客户端传过来的文件,但文件传输完成后,服务端程序也会马上弹出异常退出。最后的log中打印WriteToLog("out of pClient->m_bConning"); 也能在log文件中看到,说明这里不是导致服务exe退出的原因。像这样的问题要怎么分析呢?百度说的太杂了。有没有专业人士给个方向。多谢!!!
看看是不是传输文件大小的问题
客户端手动断开前,手动关闭网络,如果是异常断开,连接通道断开,肯定是会报出异常的,你把这个异常捕获到再进行处理就可以了。
打断点跟了下,出现不同的原因,都是缓冲指针为野指针的错误。现在已经改好了,谢谢各位!