创建一个线程,在线程函数里,用DO.....while将来文件分块传送。部分代码如下:wsabuf[3].buf=new char[4096];
wsabuf[3].len=4096;do
{
dwRead=sourceFile.Read(wsabuf[3].buf,4096);
if(SOCKET_ERROR==WSASendTo(m_PresSocket,wsabuf,4,&dwSend,0,
(SOCKADDR*)&addrto,sizeof(SOCKADDR),NULL,NULL))
{
AfxMessageBox("系统错误1007",MB_OK,IDS_Msg);
return 0;
}
}
while(dwRead>0);
AfxMessageBox("文件发送完成",MB_OK,IDS_Msg);
程序运行发现,如果我的文件比较小,比如小于4KB,也就是正刚好小于我定义的包大小,也就是一次调用WSASend刚好能够传送过去,那么对方就能够收到小于4KB的文件,如果我要传送的文件大于4KB的话,也就是一次WSASend不能传送过去,而是要经过DO-WHILE循环来做的话,经测试,程序第一次经DO调用WSASend似乎没有问题,但是第二资进入DO语句时程序出现死机崩溃状态,查了很久,也不知道为什么?请高手们帮帮忙!
谢谢了!
wsabuf[3].len=4096;do
{
dwRead=sourceFile.Read(wsabuf[3].buf,4096);
if(SOCKET_ERROR==WSASendTo(m_PresSocket,wsabuf,4,&dwSend,0,
(SOCKADDR*)&addrto,sizeof(SOCKADDR),NULL,NULL))
{
AfxMessageBox("系统错误1007",MB_OK,IDS_Msg);
return 0;
}
}
while(dwRead>0);
AfxMessageBox("文件发送完成",MB_OK,IDS_Msg);
程序运行发现,如果我的文件比较小,比如小于4KB,也就是正刚好小于我定义的包大小,也就是一次调用WSASend刚好能够传送过去,那么对方就能够收到小于4KB的文件,如果我要传送的文件大于4KB的话,也就是一次WSASend不能传送过去,而是要经过DO-WHILE循环来做的话,经测试,程序第一次经DO调用WSASend似乎没有问题,但是第二资进入DO语句时程序出现死机崩溃状态,查了很久,也不知道为什么?请高手们帮帮忙!
谢谢了!
myFile.Open("D:\\text.txt", CFile::modeRead | CFile::typeBinary);
int myFileLength = myFile.GetLength(); // Going to send the correct File Size
sockRecv.Send(&myFileLength, 4); // 4 bytes long
byte* data = new byte[myFileLength];
myFile.Read(data, myFileLength);
//sockRecv.Send(data, myFileLength); //Send the whole thing now
for(int i=0;i<=myFileLength;i+=1024)
{
sockRecv.Send(data+i,1024); //Send the whole thing now
Sleep(10);
}
if(myFileLength%1024!=0)
sockRecv.Send(data+myFileLength-myFileLength%1024,myFileLength%1024);我传送文件的服务器端代码是这么写的,大家看看有没有问题
//sockClient.Receive(data, dataLength); //Get the whole thing
for(int i=0;i<=dataLength;i+=1024)
sockClient.Receive(data+i,1024); //Get the whole thing now
if(dataLength%1024!=0)
sockClient.Receive(data+dataLength-dataLength%1024,dataLength%1024);这是客户端,但不知道为什么接受的数据不对
而且程序设置不了断点,莫名奇妙啊
读文件内存超界了吧,不够4K要读4K,似乎是这样的
dwRead=sourceFile.Read(wsabuf[3].buf,4096);
回答:
这个语句并非是每次都读取4KB的字节,4096是缓冲区的大小,dwRead是读取的实际字节数,如果文件不够4KB的话,那它就是读取文件的实际大小,并将读取的字节数用dwRead返回!不会发生越界的//---------------------------------------
4102509(物到极时终必反.....) ( ) 信誉:91 Blog 加为好友 dwRead=sourceFile.Read(wsabuf[3].buf,4096);读结尾时如果小于4096呢..回答:
读结尾如果小于4096,对于发送端应该不会出现问题,原因和上面的回答差不多,但是问题可能会出现在接收端,接收端最后一次写的时候会写入4096,这样就造成文件多写入了一些。但是我的那个问题原因不在这。我是读第一个4KB正常,读第二个4KB就死机。
当然对于上面你的这个问题可以有解决的办法,就是每次都将读取到的实际字节数发送给对方,对方写的时候也写入这个实际节字数就行了!最后,我告诉大家,刚刚我对程序进行一点的改进,发现:
如果我在读取一块包,将该包地送给对方,然后加了一个Sleep(1),
也就是在WSASend函数后曾加函数Sleep(1);
程序好像比较正常了!能分多次读取数据包并发送给对方!我想知道原因!
for(int i=0;i<=myFileLength;i+=1024)
{
sockRecv.Send(data+i,1024); //Send the whole thing now
Sleep(10);
}
if(myFileLength%1024!=0)
sockRecv.Send(data+myFileLength-myFileLength%1024,myFileLength%1024);
//---------------------
看了一下你这段代码,感觉应该是在处理最后一块数据包的时候出了问题!不过我对你这个Sleep很有兴趣,不知道你为什么要用Sleep呢?我真的很想知道,也请高手们看了我上面一条回复给点意见,烦啊!
这样做就算用TCP也很难保证稳定性的可以试一下 发一个包过去 ,
客户端收到处理完成以后给服务器一个返回确认包
服务器收到确认包再发一个新的