delphi上傳文件
Ⅰ 【DELPHI】如何在兩台電腦間傳送文件
Delphi 實現傳送文件
1.建立兩個工程Server及Client
分別放TServerSocket及TClientSocket控制項,Demo,Edit控制項等。
2.設置TServerSocket name為 SS, ServerType為stNonBlocking,TClientSocket name為cs,ClientType為ctNonBlocking表示非同步讀寫信息。注意ClientType和ServerType要相一致.若為ctBlocking則表示同步讀寫信息。
3.Socket傳送文件的順序圖
a)Client-->Server MP_QUERY
b)Server-->Client MP_ACCEPT
c) Client-->Server MP_FileProperty
d)Server-->Client MP_NextWillBeData
e)Client-->Server MP_NextWillBeData
f)Server-->Client MP_DATA
g) Client-->Server 發送數據
h) Server接收數據並處理
i)Client-->Server MP_END結束
4.Client端代碼-----------------------------------------------------------------------------------------------------------------
unit UnitClient;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ScktComp, StdCtrls, Buttons, ExtCtrls, ComCtrls;
Const
//設置協議標志符
//標志將要發送文件名
MP_QUERY ='aaaaa';
//標志伺服器拒絕接收
MP_REFUSE ='bbbbb';
//標志伺服器同意接收文件
MP_ACCEPT ='ccccc';
//標志將要傳遞數據
MP_NEXTWILLBEDATA='ddddd';
//標志伺服器端准備接收數據
MP_DATA ='eeeee';
//標志客戶端取消了本次發送操作
MP_ABORT ='fffff';
//標志已經發送完畢
MP_END='iiiii';
//標志發送的文件長度
MP_FILEPROPERTY='jjjjj';
//指定每次發送包的大小
iBYTEPERSEND=1024;
type
TForm1 = class(TForm)
OpenDialog1: TOpenDialog;
cs: TClientSocket;
Panel1: TPanel;
btnSendFile: TBitBtn;
edtIPAddress: TEdit;
Memo1: TMemo;
edtHostName: TEdit;
RB1: TRadioButton;
RB2: TRadioButton;
ProBar: TProgressBar;
Btncancel: TBitBtn;
Btnexit: TBitBtn;
procere btnSendFileClick(Sender: TObject);
procere csRead(Sender: TObject; Socket: TCustomWinSocket);
procere FormCreate(Sender: TObject);
procere BtncancelClick(Sender: TObject);
procere BtnexitClick(Sender: TObject);
private
//定義一個發送文件的數據流
fsSend: TFileStream;
//設置開始狀態位
tStart:Boolean;
//標識當前時間
TickCount:Longword;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
//發送文件
procere TForm1.btnSendFileClick(Sender: TObject);
begin
//關閉套接字連接
cs.Close;
//初始化進程條
Probar.Position:=0;
if RB1.Checked then
begin
cs.Host:='';
//指定要連接的主機IP地址
cs.Address:=edtIPAddress.Text;
end
else
//指定要連接的主機名
cs.Host:=edtHostName.Text;
//要連接的主機所用埠號
cs.Port:=2000;
//打開套接字連接
cs.Open;
//點擊發送確認按鈕
if OpenDialog1.Execute then
Begin
//發送連接請求
cs.Socket.SendText(MP_QUERY+OpenDialog1.FileName);
end;
end;
//客戶端接收來自伺服器端的信息
procere TForm1.csRead(Sender: TObject; Socket: TCustomWinSocket);
var
MsgRecv:string;
bufSend:pointer;
iLength:Integer;
begin
//得到客戶端發來的信息
MsgRecv:=Socket.ReceiveText;
//取前5位,得到協議標志符
MsgRecv:=(MsgRecv,1,5);
//接收到拒絕信息
if MsgRecv=MP_REFUSE then
memo1.Lines.Add('連接請求被拒絕!')
//接收到確認接收信息
else if MsgRecv=MP_ACCEPT then
begin
//為要發送的文件創建文件流
fsSend:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);
tStart:=False;
//進度條顯示
Probar.Max:=fsSend.Size;
memo1.Lines.Add('開始發送!');
//獲取發送開始時的時間
TickCount:=GetTickCount;
//創建文件流並發送文件長度。
Socket.SendText(MP_FILEPROPERTY+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
memo1.Lines.Add('發送數據中... ...');
tStart:=True;
end;
//還有數據沒有發送。
if fsSend.Position< fsSend.Size-1 then
begin
iLength:=fsSend.Size-1-fsSend.Position;
//將數據分段發送
if iLength>iBYTEPERSEND then
iLength:=iBYTEPERSEND;
GetMem(bufSend,iLength+1);
try
//讀取文件流數據
fsSend.Read(bufSend^,iLength);
//發送長度為iLength的數據
Socket.SendBuf(bufSend^,iLength);
//進度條顯示
Probar.Position:=fsSend.Position;
finally
//釋放內存
FreeMem(bufSend,iLength+1);
end;
//發送完畢
end else
begin
//通知主機文件傳送結束。
Socket.SendText(MP_END);
memo1.Lines.Add('發送完成!');
//獲取發送耗時
memo1.Lines.Add('發送耗時'+IntToStr(GetTickCount-TickCount)+'毫秒');
fsSend.Free;
end;
//取消文件發送過程
end else if MsgRecv=MP_ABORT then
begin
memo1.Lines.Add('中止!');
//文件傳送取消
fsSend.Free;
end;
end;
procere TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
end;
//取消
procere TForm1.BtncancelClick(Sender: TObject);
begin
//取消文件發送過程
cs.Socket.SendText(MP_ABORT);
end;
procere TForm1.BtnexitClick(Sender: TObject);
begin
Form1.Close;
end;
end.
5.Server端代碼------------------------------------------------------------------------------------------------
unit UnitServer;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, ScktComp, ExtCtrls;
Const
//設置協議標志符
//標志將要發送文件名
MP_QUERY ='aaaaa';
//標志伺服器拒絕接收
MP_REFUSE ='bbbbb';
//標志伺服器同意接收文件
MP_ACCEPT ='ccccc';
//標志將要傳遞數據
MP_NEXTWILLBEDATA='ddddd';
//標志伺服器端准備接收數據
MP_DATA ='eeeee';
//標志客戶端取消了本次發送操作
MP_ABORT ='fffff';
//標志已經發送完畢
MP_END='iiiii';
//標志發送的文件長度
MP_FILEPROPERTY='jjjjj';
//指定每次發送包的大小
iBYTEPERSEND=1024;
type
TForm1 = class(TForm)
SaveDialog1: TSaveDialog;
ss: TServerSocket;
Memo1: TMemo;
procere ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
procere FormCreate(Sender: TObject);
procere FormDestroy(Sender: TObject);
private
//定義一個接收文件的數據流
fsRecv:TFileStream;
//設置開始狀態位
tStart:Boolean;
//標識當前時間
TickCount:Longword;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
//伺服器端接收來自客戶端的信息
procere TForm1.ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
msgr,theFileName:string;
bufRecv:Pointer;
iLength:Integer;
begin
//接收到的數據的長度
iLength:=Socket.ReceiveLength;
//開辟一塊新的內存,用來保存接收到的數據
GetMem(bufRecv,iLength);
try
//接收數據
Socket.ReceiveBuf(bufRecv^,iLength);
//將接收到的數據以字元串的形式存到msgr中
msgr:=StrPas(PChar(bufRecv));
//取前5個字元
msgr:=Copy(msgr,1,5);
if msgr=MP_QUERY then
begin
//去掉字元串前後的空格和控制字元
msgr:=Trim(StrPas(PChar(bufRecv)));
//第5個字元後面的字元串為文件名
theFileName:=ExtractFileName(Copy(msgr,6,Length(msgr)));
SaveDialog1.Title:='請選擇或輸入接收到的數據保存到的文件名:';
SaveDialog1.FileName:=theFileName;
//點擊確認保存按鈕
if SaveDialog1.Execute then
begin
//為需保存的文件創建文件流
fsRecv:=TFileStream.Create(SaveDialog1.FileName,fmCreate);
//如果同意接收數據。
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 ('文件傳送完成!');
memo1.Lines.Add ('接收耗時'+IntToStr(GetTickCount-TickCount)+'毫秒');
fsRecv.Free;
end
//接收到文件傳送取消信息
else if msgr=MP_ABORT then
begin
memo1.Lines.Add ('MP_ABORT');
Socket.SendText(MP_ABORT);
fsRecv.Free;
end
else
begin
if not tStart then
begin
memo1.Lines.Add('接收數據...');
tStart:=True;
end;
//將接收緩沖區數據寫入文件
fsRecv.WriteBuffer(bufRecv^,iLength);
//通知客戶端繼續發送數據
Socket.SendText(MP_DATA);
end;
finally
//釋放內存
FreeMem(bufRecv,iLength);
end;
end;
procere TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
//設置的監聽埠
ss.Port:=2000;
//開始監聽
ss.Open;
end;
procere TForm1.FormDestroy(Sender: TObject);
begin
ss.Close;
end;
end.
Ⅱ Delphi編寫文件傳輸的實現方法
的確是很大的命題,可用於文件網路傳輸的控制項倒是不少,得到IP地址也不難,但最重要的問題是如何避開防火牆、路由的阻攔,也就是如何穿透路由/防火牆的技術。
建議先學習下乙太網方面的知識。
================================================
通常情況下,我們都應該在應用層編程。就像陽光上的橋說的一樣,實現文件傳輸並不困難。
對於獲得對方IP的觀念應該糾正一下。如果通信還沒有建立,你又要主動發起和對方的通訊,那麼你應該首先詢問對方的地址;如果已經建立了通訊,那麼對方的IP你已經就是知道了的。
打個比方:你要上我家來,你又從來沒來過,你就需要問我我家在哪裡,你是不可能憑空知道我家住何處的;你來過我家的話,不用我說你也知道我家在哪裡,除非你忘了...
另外:非法穿透防火牆/路由會給客戶的系統帶來安全隱患,而且對於編程來講也是不具備廣泛性和持久性的。安全漏洞遲早是會被封鎖的,除非你不考慮這些因素。
Ⅲ Delphi 傳送文件方法
只要是Tcp/Ip協議的都好,具體的話可以用Indy控制項,可以用TCPServer&TCPClient,但需要自己寫握手協議。
這個好辦,IdHTTP控制項要放上,在哪個面板里記不得了慢慢找,
FormCreate是觸發的事件,自己想怎麼觸發自己定這些不用說吧.
//delphi代碼
procere TForm1.FormCreate(Sender: TObject);
var
AData: TIdMultiPartFormDataStream;
ARes: string;
begin
IdHTTP1.Request.ContentType:= 'multipart/form-data';
AData:= TIdMultiPartFormDataStream.Create;
AData.AddFile('myfile', 'a.txt', '');
AData.Position:= 0;
ARes:= IdHTTP1.Post('http://127.0.0.1/test.php', AData);
AData.Free;
end;
php里接收上傳的文件與網頁上傳的那種一樣
Ⅳ Delphi中,怎麼使用ftp主動下傳文件
delphi 提供了 indy 組件包,其中 TIdFTP 可以實現通過以 FTP 方式進行文件的上傳與下載。示例代碼如下:procere TForm1.Button2Click(Sender: TObject);var tt :TIdFTPListItems; t : TIdFTPListItem; i : integer; tfname : String;begin IdFTP1.TransferType := ftBinary; //指定為二進制文件 或文本文件ftASCII for i:=0 to IdFTP1.DirectoryListing.Count-1 do begin tt := IdFTP1.DirectoryListing; //得到當前目錄下文件及目錄列表 t := tt.Items[i]; //得到一個文件相關信息 Label1.Caption :=t.Text; //取出一個文件信息內容 tfname := t.FileName; showmessage(t.OwnerName+' '+t.GroupName+' '+t.FileName+' '+t.LinkedItemName); if IdFTP1.DirectoryListing.Items[i].ItemType = ditFile then //如果是文件 begin IdFTP1.Get(tfname,'d:\FTPtest\'+tfname,True,True); //下載到本地,並為覆蓋,且支持斷點續傳 end; end;end;
Ⅵ delphi 7怎麼往伺服器傳文件
提供個思路吧!
1、可以利用FTP方式,在伺服器駕設一個FTP伺服器,在DEPHI中只要用FTP控制項就可以直接傳送!,ftp上傳可以去度娘查……相當多
2、利用//192.168.0.1方式
,這種方式等同於!
Ⅶ [delphi]關於上傳文件,代碼如下: 問題是文件上傳都成功,可是下載的時候卻只能下下來一個空白的文件
這種問題我也遇到過,不知道你用的是不是SQL,如果是SQL SERVER 的話,你可以用查詢分析器查詢這條數據,然後他的image欄位就會顯示出來,如果為空,說明你上傳的時候沒有將東西上傳上去,那就是上傳的問題,如果是有數據的,那主要就是下載的問題,先明確問題之後,再去找下面的原因。
哦,突然發現,你是將數據流用字元串保存的?
如果是這樣,要用特定的函數將流轉換成字元串的。 (自己網路下,把流轉換成字元串,我這無法網路- -)
pWJNR:=Parameters.ParamByName('CJWJ').LoadFromStream(pFileStream,ftBlob);
這么寫應該是不對的。
一般情況是,定義一個流類型,然後將文件轉換成流,然後直接保存到資料庫的image欄位中,然後下載的時候,再將image欄位轉換成文件。就好了。。
var
m:TMemoryStream;
begin
m:=TMemoryStream.Create;
m.LoadFromFile(Fielname);
Data1.ADOhtgl.edit;
Data1.ADOhtgl.Parameters.ParamByName('CJWJ').LoadFromStream(m,ftBlob);
Date1.ADOhtgl.Post;
end;
如滿意請採納,如有問題請追問。
Ⅷ Delphi 文件傳輸
1.既然你要實現文件互傳,那一般只能使用TCP方式(因為文件數據量一般比較大),那麼在服務端使用TCP控制項Listen,在客戶端也使用TCP控制項進行連接(connect),然後就可以了。如果你要實現雙向傳輸,正如你所說,兩邊都要有服務端和客戶端,即做一個軟體,放兩個TCP控制項,一個用於服務端,一個用於客戶端。
2.至於你後面一種情況,實際上這是一個你無法直接通過編程解決的問題(本質上是NAT,即1個外網IP=n個內網IP)。目前解決的方法是:
1)使用VPN,現成的是VNN軟體(北京一個公司開發的,可以免費使用7天);
2)自己做個中轉(中轉軟體運行一定要有外網地址),然後實現文件傳輸前,兩個傳輸方都登錄中轉,所有傳輸通過中轉軟體就可以了。
目前我只知道這兩種方法,如果有第三種,也請告訴我,謝謝!
Ⅸ DELPHI實現服務端與客戶端之間進行文件夾傳輸
文件傳輸可以用FTP協議,delphi4,delphi7都有簡易ftp的控制項,另外,若伺服器是公用伺服器,也可以用標准下載方式。
Ⅹ 在delPhi中怎麼通過webservice上傳文件,比較
您好,很高興能幫助您
把上傳的圖片進行編碼(base64),數據傳輸到伺服器端後再進行解碼生成圖片
你的採納是我前進的動力,
記得好評和採納,答題不易,互相幫助,