我在写一段时候遇到一点问题,见查不出错误代码,希望友人可以指出
HANDLE hFile;
hFile=CreateFile("Upgrade.exe",
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
FILE_INFO fileinfo;
WIN32_FIND_DATA             FindFileData;

FindClose(FindFirstFile("Upgrade.exe",&FindFileData));
memset(&fileinfo,0,sizeof(FILE_INFO));
TCHAR Title[250];
GetFullPathName("Upgrade.exe",250,Title,NULL);
strcpy(fileinfo.szFileTitle,Title); fileinfo.dwFileAttributes     =       FindFileData.dwFileAttributes;
fileinfo.ftCreationTime       =       FindFileData.ftCreationTime;
fileinfo.ftLastAccessTime     =       FindFileData.ftLastAccessTime;
fileinfo.ftLastWriteTime      =       FindFileData.ftLastWriteTime;
fileinfo.nFileSizeHigh        =       FindFileData.nFileSizeHigh;
fileinfo.nFileSizeLow         =       FindFileData.nFileSizeLow; send(sock_accept,(char*)&fileinfo,sizeof(FILE_INFO),0); UINT dwRead=0;
while(dwRead<fileinfo.nFileSizeLow)
{
byte* data = new byte[1024];
//UINT dw=myFile.Read(data, 1024);
DWORD dwSize=0;
ReadFile(hFile,data,1024,&dwSize,NULL);
send(sock_accept,(char*)data,dwSize,0); dwRead+=dwSize;
delete []data;//
}

_lclose((HFILE)hFile);
CloseHandle(hFile);
closesocket(sock_accept);

解决方案 »

  1.   

    问题可能出在:
    1。你的while循环里,每次都读1024数据,但是,该文件未必就是1024的整倍数,那么,在读到最后一块数据的时候,就可能出问题。2。用网络发送数据时,循环里,最好不要只有send,这样的机制会出现很多很多莫名其妙问题,建议:当客户端的每个recv收到1024,就send一个字节给服务端,然后服务端再发下一个1024,然后周而复始,直到发送完成。while(dwRead<fileinfo.nFileSizeLow)
    {
    byte* data = new byte[1024];
    //UINT dw=myFile.Read(data, 1024);
    DWORD dwSize=0;
    ReadFile(hFile,data,1024,&dwSize,NULL);
    send(sock_accept,(char*)data,dwSize,0);
                      recv(sock_accept,(char*)data,1,0);//修改这里
    dwRead+=dwSize;
    delete []data;//
    }
    还有一点,我发现你在调用send的时候,参数是sock_accept。天,你该不会是拿“被执行listen,并处于监听状态,等待连接”的那个SOCKET来发送/接收数据吧!?!?!?
      

  2.   

    一般来讲,CSocket类的send函数格式里头没有 socket_accept的,不过用他来绑定我们重载的函数也未尝不可。不可也可以尝试按标准格式访问。我以前的问题就是这样解决的。
      

  3.   

    在接收方检查实际接受的数据就可,不必在发送文件时发送本次发送的长度。不过最好在发送方的send的返回检查。这样int rev=send(sock_accept,(char*)data,dwSize,0);后面的dwRead+=dwSize改为dwRead+=rev,因为send不保证发送dwSize的数据。
      

  4.   

    实际情况是这样的,我原来使用cfile来打开文件,发送无问题,后来我打算在dll中使用,但是使用createfile打开文件来发送就不行了,而且开始时候是用阻塞通信,后来为了是用消息机制,使用了wsaeventselect,然后accept后使用ioctl修改sock_accept为阻塞模型,开始传文件,结果就成了这样,什么效果都没有,传过去是0字节。
    原代码是网上下的,fileinfo的结构是这样的
    typedef struct _FILE_INFO {    TCHAR       szFileTitle[128];                   //文件的标题名
        DWORD       dwFileAttributes;                   //文件的属性
        FILETIME    ftCreationTime;                     //文件的创建时间
        FILETIME    ftLastAccessTime;                   //文件的最后访问时间
        FILETIME    ftLastWriteTime;                    //文件的最后修改时间
        DWORD       nFileSizeHigh;                      //文件大小的高位双字
        DWORD       nFileSizeLow;                       //文件大小的低位双字
        DWORD       dwReserved0;                        //保留,为0
        DWORD       dwReserved1;                        //保留,为0} FILE_INFO, * PFILE_INFO;
    如果有人可以指出方法的不对,小弟万分感激!
      

  5.   

    凭感觉,你真正出错的代码,恐怕还不是你认为可能出错的地方.
    很可能是你对你使用的SOCKET模型不很熟悉,
    在某些地方操作出错了.把和SOCKET相关的代码贴出来吧.
      

  6.   

    代码如下:
    m_UpNum=0; m_UpSock=socket(AF_INET,SOCK_STREAM,0); struct sockaddr_in m_ServerAddr; int ret; m_ServerAddr.sin_family=AF_INET;
    m_ServerAddr.sin_addr.S_un.S_addr=INADDR_ANY;
    m_ServerAddr.sin_port=htons(5432); ListenEvent=WSACreateEvent(); WSAEventSelect(m_UpSock,ListenEvent,FD_ACCEPT|FD_CLOSE); ret=bind(m_UpSock,(LPSOCKADDR)&m_ServerAddr,sizeof(m_ServerAddr)); if(ret==SOCKET_ERROR)
    {
    return;
    } WSAEventSelect(m_UpSock,ListenEvent,FD_ACCEPT|FD_CLOSE); ret=listen(m_UpSock,5);
    if(ret==SOCKET_ERROR)
    {
    return;
    } UINT ThreadID; HANDLE hd=(HANDLE)_beginthreadex(NULL,0,UpgradeFun,this,0,&ThreadID); if(hd!=INVALID_HANDLE_VALUE)
    {
    CloseHandle(hd);
    }unsigned __stdcall CIOSocket::UpgradeFun(LPVOID lParam)
    { CIOSocket* pThis=reinterpret_cast<CIOSocket*>(lParam); int index;
    WSANETWORKEVENTS NetworkEvents;
    bool ret=false; while(TRUE)
    { index=WSAWaitForMultipleEvents(1,
    &pThis->ListenEvent,
    FALSE,
    WSA_INFINITE,//waitting for ever
    FALSE);
    if (index == WSA_WAIT_TIMEOUT)
    continue;
    int ret= WSAEnumNetworkEvents(pThis->m_UpSock,
     pThis->ListenEvent,
     &NetworkEvents);
    if(NetworkEvents.lNetworkEvents&FD_ACCEPT)
    {
    if(NetworkEvents.iErrorCode[FD_ACCEPT_BIT]!=0)
    {
    break;//Accept Error
    pThis->StartAcceptUpgradeFun();

    } } return 1;
    }void CIOSocket::StartAcceptUpgradeFun()
    {
    SOCKET accept_sock=accept(m_UpSock,NULL,NULL); WSAEventSelect(accept_sock,ListenEvent,0); DWORD l=1; if(ioctlsocket(accept_sock,FIONBIO,&l)!=SOCKET_ERROR)
    {
    UINT ThreadID; HANDLE hd=(HANDLE)_beginthreadex(NULL,
    0,
    AcceptUpgrade,
    (LPVOID)accept_sock,
    0,
    &ThreadID); if(hd!=INVALID_HANDLE_VALUE)
    {
    CloseHandle(hd);
    }
    }}
    unsigned __stdcall CIOSocket::AcceptUpgrade(LPVOID lParam)
    {
    SOCKET sock_accept=(SOCKET)lParam;

    HINSTANCE hInst = LoadLibrary("SendFile.DLL"); 
    if(hInst) 
    {            
    typedef DWORD (WINAPI *MYFUNC)(SOCKET sock_accept,TCHAR filepath[]);          
    MYFUNC SendFileFun = NULL;     
    SendFileFun = (MYFUNC)GetProcAddress(hInst, "SendFile");
    if(SendFileFun)     
    {             
    SendFileFun(sock_accept,"Upgrade.exe");     
    }     
    FreeLibrary(hInst); 
    } return 1;
    }SendFile的代码上面已经给出,所以就不贴了,大家看看吧,我现在已经开始在从新写另外的代码了,如果有人可以找出错误,我就将就这个代码用了,谢谢了先。
      

  7.   

    附上一句,我现在的贴的代码是写在dll中的,其实最初是直接写在代码中的,但我发现这两中方法都没区别后,就放弃了。
      

  8.   

    我已经放弃使用Event的方式了,我怕程序在教低版本的windows中无法使用,我直接使用了多线程的方式,然而,我还是很想知道,我的代码有错否,错在何方?我很想搞清楚它的原理,谢谢了先。
      

  9.   

    csdn也这样啊!明天没人回我删了。浪费我表情。