1. 程式人生 > >關於socket中recv的返回值

關於socket中recv的返回值

最近在做一個利用socket下載圖片的小程式。基本思路就是建立socket以後自己組包然後傳送過去,然後recv接收裡面的資料裡面就包含了圖片資料資訊。

一開始自己在寫的時候,一直會遇到問題。關鍵程式碼如下:

char* WriteBuffer = (char *)malloc(1024 * 1024 * 2);            //建立足夠大的Buffer
        
        hPhoto = CreateFileA(FilePath,                                    // 開啟檔案
            GENERIC_WRITE,
            FILE_SHARE_WRITE,
            NULL,
            CREATE_ALWAYS,
            FILE_ATTRIBUTE_NORMAL,
            NULL);

        memset(WriteBuffer, 0, Length);                                    //清空Buffer                

        if (Length % 1024 == 0)                                            //根據長度計算for迴圈的讀取次數
            Lun = Length / 1024 - 1;
        else
            Lun = Length / 1024;

        for (i = 0; i <= Lun; i++)
        {

            recv(LinkSocket, (char*)recvbuffer, 1024, 0);                //接收資料
            CopyMemory(WriteBuffer, recvbuffer, 1024);                    //將資料存入Buffer
            //Sleep(1);                                                    //這裡一定要睡上一會。。。
            memset(recvbuffer, 0, 1024);                                //清空臨時Buffer
            WriteBuffer += 1024;                    
        }
        WriteBuffer -= 1024 * i;
        WriteFile(hPhoto, WriteBuffer, Length, &dwWritten,0);            //寫入檔案操作
        SetFilePointer(hPhoto, 0, NULL, FILE_END);

        CloseHandle(hPhoto);

每次都必須sleep睡一會兒才可以。如果是不寫sleep的話,程式直接崩潰掉了。

由於百思不得其解,只好在CSDN上面請教大牛了。

下面是我錯誤的地方:

recv本身是阻塞模式的,這部分可以這樣寫:

int nRecvLen =0;
    while ( nRecvLen < Length ) {
        int len = recv(LinkSocket, WriteBuffer + nRecvLen, 1024, 0);
        if ( len ==0 )
            break;
        nRecvLen += len;
    }
    WriteFile(hPhoto, WriteBuffer, nRecvLen, 
&dwWritten, NULL); CloseHandle(hPhoto);

recv(LinkSocket, (char*)recvbuffer, 1024, 0);  

請注意,recv的返回值的意義,你期望讀取1024,實際返回可能只有1000,所以,你必須根據recv的返回值來確定,實際讀取了多少資料

你的問題就出在這裡了

給你寫個大致的模板
bmplen=2000;//假設已經接受到圖片的長度,假設為2000
int recvlen=0;
while(recv<2000)
{
int ret=recv(......);
memcpy(WriteBuffer+recvlen,buffer,ret);
recvlen=recvlen+ret;
}

大致就是這樣了
}


每次寫socket都有各種各樣的錯誤,然後有各種各樣的收穫。

再次謝謝大家了。

下面附上論壇地址。

http://topic.csdn.net/u/20120721/17/a480efe0-15e3-44fb-a18c-ea9cf4909057.html?seed=291447330&r=79203312#r_79203312