最近在做一个利用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