利用socket进行文件分割传输
一个窗体同时作为发送和接收端,所以client的ip已经设好127.0.0.1,而且端口也已经设好。一些变量设为静态。
我使用它传一个图片,接收下来的图片有重叠。但不调试发现执行一次ClientWrite,接收方执行ServerClientRead不是一次,而是两次。
我真搞不明白了。所以那位高手做过诸如此类的程序,请指教!
具体程序如下:
/---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "UCommunicate.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
static int final,emod=0,hui=0,x=0,a=0,i=0;
TMainFrm *MainFrm;
//---------------------------------------------------------------------------
__fastcall TMainFrm::TMainFrm(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMainFrm::ClientWrite(TObject *Sender,
TCustomWinSocket *Socket)
{
void *p[20000];
static long k=20000;
static long bmpsize,c,mod;
static TMemoryStream* pms = new TMemoryStream();
if(hui==0)
{pms->LoadFromFile(filename);hui++; //装入要发送的文件。
bmpsize=pms->Size; //计算文件的大小(字节)
c=(int)bmpsize/k; //分割文件为c
mod=bmpsize%k; //分割后于下的字节数
emod=mod; //使mod在整个程序都可访问
}
if(i<c)
{
pms->Position=x; //改变内存流读取指针
pms->ReadBuffer(p,k); //把内存流读入缓冲区
x=x+k;
Client->Socket->SendBuf(p,k); //将分割的文件发送
i++ ;
}
else
{
final++;
pms->Position=x;
pms->ReadBuffer(p,mod); //发送最后mod个字节后,发送完毕
Client->Socket->SendBuf(p,mod);
}
}
//---------------------------------------------------------------------------
void __fastcall TMainFrm::Button1Click(TObject *Sender)
{
if(OpenDialog1->Execute())
{
filename = OpenDialog1->FileName;
Label1->Caption="选择图片成功";
hui=0; a=0; final=0;
x=0; i=0;
}
}
//---------------------------------------------------------------------------
void __fastcall TMainFrm::ClientConnect(TObject *Sender,
TCustomWinSocket *Socket)
{
Label1->Caption="ok";
}
//---------------------------------------------------------------------------
void __fastcall TMainFrm::ServerClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
static TMemoryStream* qms = new TMemoryStream();
void *z[20000]; //定义缓冲区大小
if(final!=1)
{
Socket->ReceiveBuf(z,20000); //接收SOCKET中的数据流
qms->Position=a;
qms->WriteBuffer(z,20000); //写入缓冲区
a=a+20000; //改变内存流指针
Client->Active=false; //每次发送前要判断网络是否畅通
Client->Port=8888; //联接远程计算机,如果成功则 发送,否则等待
Client->Active=true;
}
else //接收最后emod个字节。
{
qms->WriteBuffer(z,emod);
qms->SaveToFile("g:\\ok.bmp");
Label1->Caption="successful";
qms->Position=0;
Image1->Picture->Bitmap->LoadFromStream(qms);
}
}
//---------------------------------------------------------------------------
void __fastcall TMainFrm::Button2Click(TObject *Sender)
{
Client->Active=false;
Client->Port=8888;
Client->Active=true;
}
//---------------------------------------------------------------------------