Socket 文件传输

服务端

1.控件:TServerSocket

2.OnClientRead事件处理

procedure TMainForm.ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
msgr,theFileName:ansistring;
bufRecv:Pointer;
acc,iLength:Integer;
begin

acc:=0; //接收 0 1-不接受
//接收到的数据的长度
iLength:=Socket.ReceiveLength;
//开辟一块新的内存,用来保存接收到的数据
//GetMem(bufRecv,iLength+1);
  bufRecv:=AllocMem(iLength+1);     //// xe2 要AllocMem 且+1

{ //拷贝数据到缓存   d6
  Buf:=AllocMem(BufSize);

StrCopy(Buf,pchar(st));
 }

try
//接收数据
Socket.ReceiveBuf(bufRecv^,iLength);
//将接收到的数据以字符串的形式存到msgr中
msgr:=StrPas(PansiChar(bufRecv));    //
//取前5个字符
msgr:=Copy(msgr,1,5);
if msgr=MP_QUERY then
begin
//去掉字符串前后的空格和控制字符
msgr:= StrPas(PansiChar(bufRecv));     //  PChar
//第5个字符后面的字符串为文件名
theFileName:=ExtractFileName(Copy(msgr,6,Length(msgr)-5));
 StB.Panels[0].Text:=‘准备接收文件‘;
memo1.Lines.Add(‘接收文件:‘+theFileName);
//SaveDialog1.Title:=‘请选择或输入接收到的数据保存到的文件名:‘;
//SaveDialog1.FileName:=ansistring(theFileName);      //ansistring
//点击确认保存按钮
if acc=0 then //if SaveDialog1.Execute then
begin
//为需保存的文件创建文件流
 try
 fsRecv:=TFileStream.Create(‘V:\自助拷贝\内网到外网\‘+theFileName,fmCreate);    //fsRecv:=TFileStream.Create(SaveDialog1.FileName,fmCreate);

except
  Socket.SendText(MP_ABORT);
  exit;
 end;
 //如果同意接收数据。
 StB.Panels[0].Text:=‘开始接收‘;
//memo1.Lines.Add (‘开始接收!‘);
TickCount:=GetTickCount;
//发送同意接收文件的信息
Socket.SendText(MP_ACCEPT);
tStart:=False;
end
else
//发送拒绝接收文件的信息
Socket.SendText(MP_REFUSE);
end
else if msgr=MP_FILEPROPERTY then
begin
//接收文件长度并说明主机可以接收数据了
Socket.SendText(MP_NEXTWILLBEDATA);
end
else if msgr=MP_NEXTWILLBEDATA then
begin
//要求发送端发送数据
Socket.SendText(MP_DATA);
end else if msgr=MP_END then
begin
//memo1.Lines.Add (‘文件:‘+theFileName);
memo1.Lines.Add(‘成功‘);
StB.Panels[0].Text:= ‘传送完成‘;
//memo1.Lines.Add (timetostr(time())+‘传送完成,接收耗时‘+IntToStr(GetTickCount-TickCount)+‘毫秒‘);
StB.Panels[1].Text:=‘接收耗时‘+IntToStr(GetTickCount-TickCount)+‘毫秒‘;
fsRecv.Free;
end
//接收到文件传送取消信息
else if msgr=MP_ABORT then
begin
//memo1.Lines.Add (‘MP_ABORT‘);
StB.Panels[0].Text:= ‘MP_ABORT‘;
Socket.SendText(MP_ABORT);
fsRecv.Free;
end
else
begin
if not tStart then
begin
//memo1.Lines.Add(‘接收文件...‘);
StB.Panels[0].Text:=‘接收文件...‘;
tStart:=True;
end;
//将接收缓冲区数据写入文件
fsRecv.WriteBuffer(bufRecv^,iLength);
//通知客户端继续发送数据
Socket.SendText(MP_DATA);
end;
finally
//释放内存
FreeMem(bufRecv,iLength);
end;
end;

客户端

1.控件TClienSockte

2.添加文件:

try
  StB.Panels.Items[0].Text:=(‘读文件‘);
  cs.Socket.SendText(MP_QUERY+ansistring(OpenDialog1.FileName));       //ansistring
   btnSendFile.Enabled:=false;
   Application.ProcessMessages;//增加简单多线程,防假死
except
  showmessage(‘无法连接服务器‘);
  btnSendFile.Enabled:=True;

end;

3. ClienSockte.open

4.TClienSockte onread 事件

//客户端接收来自服务器端的信息
procedure TForm1.csRead(Sender: TObject; Socket: TCustomWinSocket);
var
MsgRecv: ansistring; // ansistring
bufSend:pointer;
iLength:Integer;
begin
//得到客户端发来的信息
MsgRecv:=socket.ReceiveText;   //ansistring
//取前5位,得到协议标志符
MsgRecv:=copy(MsgRecv,1,5);
//接收到拒绝信息
if MsgRecv=MP_REFUSE then
StB.Panels.Items[0].Text:=(‘连接请求被拒绝!‘)
//接收到确认接收信息
else if MsgRecv=MP_ACCEPT then
begin
//为要发送的文件创建文件流
fsSend:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);
tStart:=False;
//进度条显示
Probar.Max:=fsSend.Size;
StB.Panels.Items[0].Text:=(‘开始发送!‘);
memo1.Lines.Add(‘发送文件:‘+OpenDialog1.FileName);
//获取发送开始时的时间
TickCount:=GetTickCount;
//创建文件流并发送文件长度。
Socket.SendText(MP_FILEPROPERTY+ ansistring(inttostr(Trunc(fsSend.Size/iBYTEPERSEND)+1)));
end
else if MsgRecv=MP_NEXTWILLBEDATA then
begin
//通知接收端将要传送数据。
Socket.SendText(MP_NEXTWILLBEDATA);
end
else if MsgRecv=MP_DATA then
begin
//接收到确认信息,开始发送数据。
if not tStart then
begin
StB.Panels.Items[0].Text:=(‘发送中...‘);
StB.Panels.Items[1].Text:=(‘‘);
Btnexit.Enabled:=false;
tStart:=True;
end;
//还有数据没有发送。
if fsSend.Position< fsSend.Size-1 then
begin
iLength:=fsSend.Size-1-fsSend.Position+1;
//将数据分段发送
if iLength>iBYTEPERSEND then
iLength:=iBYTEPERSEND;
GetMem(bufSend,iLength);
try
//读取文件流数据
fsSend.Read(bufSend^,iLength);
//发送长度为iLength的数据
Socket.SendBuf(bufSend^,iLength);
//进度条显示
Probar.Position:=fsSend.Position;
finally
//释放内存
FreeMem(bufSend,iLength);
end;
//发送完毕
end else
begin
//通知主机文件传送结束。
Socket.SendText(MP_END);

//获取发送耗时
memo1.Lines.Add(‘完成!‘);
StB.Panels.Items[0].Text:=‘发送完毕‘;
StB.Panels.Items[1].Text:=‘耗时‘+IntToStr(GetTickCount-TickCount)+‘毫秒‘ ;
btnSendFile.Enabled:=True;
Btnexit.Enabled:=True;
fsSend.Free;
end;
//取消文件发送过程
end else if MsgRecv=MP_ABORT then
begin
btnSendFile.Enabled:=True;
StB.Panels.Items[0].Text:=(‘文件传输被中止‘);
exit;
//文件传送取消
fsSend.Free;
end;
end;

时间: 2024-11-05 18:54:10

Socket 文件传输的相关文章

C#Socket文件传输(发送与接收代码)

这里是发送的代码: SendVarData是转码后发送函数 1 /// <summary> 2 /// 发送文件 3 /// </summary> 4 /// <param name="userName"></param> 5 private void SendFileToClient(string userName) 6 { 7 User targetUser = userListDict[userName]; 8 String tar

Java基于Socket文件传输示例(转)

最近需要进行网络传输大文件,于是对基于socket的文件传输作了一个初步的了解.在一位网友提供的程序基础上,俺进行了一些加工,采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加快传输的速度.废话少说,先来看服务器端的程序. 1.服务器端 package sterning; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.DataOutputStream;

socket文件传输功能的实现

服务端: #include <stdio.h> #include <winsock2.h> #pragma comment (lib, "ws2_32.lib")  //加载 ws2_32.dll    #define BUF_SIZE 1024    int main(int argc, char *argv[]){     //先检查文件是否存在     char *filename = "Beyond.mp3";//文件名     FI

Java基于Socket文件传输示例

最近需要进行网络传输大文件,于是对基于socket的文件传输作了一个初步的了解.在一位网友提供的程序基础上,俺进行了一些加工,采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加快传输的速度.废话少说,先来看服务器端的程序. 1.服务器端 package localSocket; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.DataOutputStrea

android--Java基于Socket文件传输示例

最近需要进行网络传输大文件,于是对基于socket的文件传输作了一个初步的了解.在一位网友提供的程序基础上,俺进行了一些加工,采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加快传输的速度.废话少说,先来看服务器端的程序. 1.服务器端 package sterning;import java.io.BufferedInputStream;import java.io.DataInputStream;import java.io.DataOutputStream;impo

android WIFI Socket 文件传输——问题已经解决了,发帖只因高兴--嘿嘿--并不彻底欢迎点评

本来是一个问题贴,最终因为太长了,只能搞成博客了.算是做个记录吧 </pre><pre name="code" class="java">我的这个Socket是想保持一个长连接,文件可以循环传输 但是我的问题在于,不能抓住文件传输完成的这个时机,导致异常 我的文件发送代码 [code=java] public void sendFile(String filePath) { try { File file = new File(filePat

C++大文件传输

C/C++大文件/数据网络传输方法总结 在C/C++网络编程中不免会遇到需要传输大数据.大文件的情况,而由于socket本身缓冲区的限制,大概一次只能发送4K左右的数据,所以在传输大数据时客户端就需要进行分包,在目的地重新组包.而实际上已有一些消息/通讯中间件对此进行了封装,提供了直接发送大数据/文件的接口:除此之外,利用共享目录,ftp,ssh等系统命令来实现大文件/数据也不失为一种好的方法. 1.基础的基于socket进行传输 基础的基于socket进行传输关键在于控制,需要自己行分包和组包

python 3.x 学习笔记13 (socket_ssh and socket_文件传输)

ssh服务端 import socket,os server = socket.socket() server.bind(('localhost',6666)) server.listen() conn, addr = server.accept() while True: print('等待新数据!') cmd = conn.recv(1024) if len(cmd) == 0: break data = os.popen(cmd.decode()).read() cmd_size = le

linux网络环境下socket套接字编程(UDP文件传输)

今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中,如果我们使用TCP传输,会造成传输速度较慢的情况,所以我们在进行文件传输的过程中,最好要使用UDP传输. 在其中,我们需要写两个程序,一个客户端,一个服务端,在一个终端中,先运行服务端,在运行客户端,在服务端和客户端都输入IP地址和端口号,注意服务端和客户端的端口号要相同,然后选择功能,在linux