这是我的代码,我接受了客户端发送过来的文件数据,但是在接收的时候总是出错
,后来我跟踪发现是在Receive的时候阻塞了,只要客户端一退出程序就会马上继续执行,请大家帮忙看看是怎么回事儿。
代码:
//打开文件,用来保存接收的数据
if(file.Open("e:\\game\\test2.txt",CFile::modeCreate | CFile::modeWrite))
{
//接收数据的缓冲区
char buf[1024];
//保存接收数据时的返回值
int nCount=1024;
//循环接收数据,直到接收完为止。
while(nCount != 0 && nCount != SOCKET_ERROR )
{
//接收数据
nCount=m_pSocket->Receive(buf,1024);
UINT code=m_pSocket->GetLastError();
file.Write(buf,nCount);
} file.Close();
AfxMessageBox("接收完成!");
}
,后来我跟踪发现是在Receive的时候阻塞了,只要客户端一退出程序就会马上继续执行,请大家帮忙看看是怎么回事儿。
代码:
//打开文件,用来保存接收的数据
if(file.Open("e:\\game\\test2.txt",CFile::modeCreate | CFile::modeWrite))
{
//接收数据的缓冲区
char buf[1024];
//保存接收数据时的返回值
int nCount=1024;
//循环接收数据,直到接收完为止。
while(nCount != 0 && nCount != SOCKET_ERROR )
{
//接收数据
nCount=m_pSocket->Receive(buf,1024);
UINT code=m_pSocket->GetLastError();
file.Write(buf,nCount);
} file.Close();
AfxMessageBox("接收完成!");
}
2、使用异步socket类时应该响应事件,而不是主动去接收数据。
文件的大小应该是5K所以,不存在太小的问题。
其实数据已经接收完了,但是程序并不知道,所以他还继续接收,导致阻塞。但是该如何判断数据是否已经接收完了呢?
不存在完不完的问题,就算你的包太大而被拆开,
那也是来多少接收多少。
解决的方法:
在客户端调用shutdown(sock,SD_WRITE),这会导致写缓冲区中所有数据马上发送出去,并且发送一个FIN报文,通知服务端数据已经全部发完。服务端收到所有数据之后,再次调用Recv就会返回0的字节数,表明连接已经断开,这时服务端还是应当先调用shutdown(sock,SD_WRITE)同样通知客户端。当客户端也收到所有数据后,连接就正式断开了。