UINT ReceiveScreen(LPVOID pParam)
{
CCrecvDlg * dlg=(CCrecvDlg*)AfxGetApp()->m_pMainWnd;
UINT *nPort=(UINT*)pParam;
CSocket m_listen;//监听socket
CSocket m_recv;//接受Socket if(m_listen.Create(*nPort))//创建监听socket成功
{
m_listen.Listen();
if(m_listen.Accept(m_recv))//连接成功
{
while(true)
{
CFile m_file;
//receive file name
char szFname[255]="";
m_recv.Receive((void*)szFname,255);
//receive file length
long len;
m_recv.Receive(&len,sizeof(DWORD));
//receive file data
if(m_file.Open(szFname,CFile::modeCreate|CFile::modeWrite|CFile::typeBinary))
{
while(len>0)
{
BYTE data[1024];
UINT dw=m_recv.Receive(&data,1024);
m_file.Write(&data,dw);
len-=dw;
} ASSERT_VALID(&m_file);
m_file.Close(); dlg->ShowPic(szFname);
}
else
{//***//
::DeleteFile(szFname);
AfxMessageBox("Open file Failed");
}
//::Sleep(500);
}//end of while(true)
}
else//连接失败
{
}
}
else//创建监听socket失败
{
}
return 0;//正常退出线程
}以上是我接受图像的线程函数,可是运行一段时间后总是会弹出"Open file Failed"(也就是在//***//处)不知道怎么回事?我感觉先接受再显示因该不会有问题,可是偏偏是文件的问题怎么回事?

解决方案 »

  1.   

    少见写得这么烂的程序
    1、接收客户端连接,正常处理应该是分配一个新的socket,让新的socket和客户端通信,监听socket继续监听,你这里倒好,server只能连接一个客户。
    2、没有出错处理,你从不判断哪里出错,更不处理包连接,接收文件名称可能一次只接收到了10个字节,也有可能一次接收完成,也有可能接收出错。
    你出错很可能就是我说的这些原因中的一个引起的。
      

  2.   

    一般server是这样连接客户端的:
    CClientSocket *pClient;
    SOCKADDR_IN  sockaddr;
    int addrlen; pClient = new CClientSocket;
    if((pClient) && Accept(*pClient))
    {
    ...
    }
      

  3.   

    其实,你的错误多半是在socket的发送方,rev=socket.send(char*)
    其实rev==length(char*)并非总成立,当某次rev<lenth.(char*)时,实际的数据小于你第一次接受的文件长度,而你的第二次socket.receive()就会得到一个错误的文件名,造成错误,
    不过,我的经验是,传送少量数据,socket是不易错的。也就是说,可能有别的原因,。
      

  4.   

    同感,可能出问题的地方很多,建议加上出错处理并写到log里看看都发生了什么。
      

  5.   

    文件打开时一般会出些什么错误?
    TCP/IP号称是安全的连接,那么它到底有多可靠?难道我高估了他?
      

  6.   

    m_recv.Receive((void*)szFname,255);你没有检查你实际的文件名的长度, 和是否是文件名, 最好是定义一个结构, 用来通信会好一点.
      

  7.   

    你在/***/处改成:
    CString strErr = _T("");
    DWORD dwErr = GetLastError();
    strErr.Format(_T("Open File Failed: %s, Error code: %d"), szFname, dwErr );
    AfxMessageBox( strErr );
    ::DeleteFile(szFname);然后看看到底是什么数据,一般根据error code 就可以知道文件错误类型。
      

  8.   

    老兄 为什么不设断点啊
    用一个socket无所谓啊  你只有一个连接 何必写clentsocket呢 原来的listeningsocket 用就可以了吧 关键还是 文件的操作问题吧
    你socket收到的数据包括文件名+数据吧   head163的话很中听哦
    可能接受到的数据 跟你想象的不一致吧  调调看 socket应该没什么问题吧
      

  9.   

    最可能出错的就是int recvlen=m_recv.Receive((void*)szFname,255);
    你加个TRACE吧。看recvlen是不是都是255.基本上不做处理判断都会出
    错。
      

  10.   

    code 3 : ERROR_PATH_NOT_FOUND
    The system cannot find the path specified. 要打开的文件没有找到,所以出错
    坦白说,你的这段代码太需要东大手术了,建议好好改改,特别是网络加多线程,加上出错处理,考虑到粘包等问题等
      

  11.   

    有个问题,我在做收/发时,一般是用mfc编的:
    发送方的CAsyncSocket::Connect(ip,port)是由接受方的函数
    CAsyncSocket::OnAccept()中用accept()来接受,
    发送方的CAsyncSocket::send()是由接受方的函数
    CAsyncSocket::OnAccept()中用Receive()来接受
    但是楼上的所有兄弟好象就没有这个过程,?????????????????????????
    你们那样编程能有那样的规范的过程吗???????????
      

  12.   

    int recvlen=m_recv.Receive((void*)szFname,255);
    这段代码最有可能的错误是什么??我想不到
      

  13.   

    有什么错呀,你一次接收255个字节,如果文件名只有8个字节,你也给他255个长度,是空格倒也罢了,其他的字符你就文件名都不对了
    如:文件名"c:\a.txt"长度为8,你给的长度是255,那么szfname就可能为"c:\a.txt&#$^#$((#.."
      

  14.   

    如果在发送方的代码是:
    char str[255];
    Send((void*)str,255);
    那么在接受端
    char str[255];
    Receive((void*)str,255);
    受到数据是不是一定是255的长度?
      

  15.   

    TCP协议是流协议,只保证先发送的字符先到,并不保证你一次收到的是一次发送的字符数。