程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 【筆記本】第二階段工作完成,筆記本第二階段

【筆記本】第二階段工作完成,筆記本第二階段

編輯:Delphi

【筆記本】第二階段工作完成,筆記本第二階段


完成了服務端的基本功能,把客戶端也完善了一些,服務端功能實現:

開發環境:Delphi XE8 + superobject + DIOCP

選擇DIOCP的原因:這兩年,這個框架的作者很勤勞,這兩年一直在不斷的完善,算是Delphi這個圈子裡面比較成熟的通訊框架了。

服務端寫的還比較粗,文檔校驗、文檔版本管理這些功能都沒做,用是可以用了,但是還是要繼續完善。沒有截圖,來兩段代碼吧。

 1 const
 2   MSG_SERVICE_USER            = 0;
 3   MSG_SERVICE_FILE            = 1;
 4 
 5 const
 6   MSG_CONNECTFAIL             = 404;    //連接失敗
 7 
 8 const
 9   MSG_USER_SUCCESSFUL         = 1000;
10   MSG_USER_LOGIN              = 1001;
11   MSG_USER_REGISTER           = 1002;
12 
13 const
14   MSG_FILE_REQ_UPLOAD         = 2001;
15   MSG_FILE_READYUPLOAD        = 2002;
16   MSG_FILE_UPLOADING          = 2003;
17   MSG_FILE_REQ_DOWNLOAD       = 2004;
18   MSG_FILE_READYDOWNLOAD      = 2005;
19   MSG_FILE_DOWNLOADING        = 2006;
20   MSG_FILE_GETFILESIZE        = 2007;
21   MSG_FILE_DELETEFILE         = 2008;
22 
23 const
24   MSG_ERR_UNKNOWN             = 4001;
25   MSG_ERR_INVALIDUSER         = 4002;   //無效用戶
26   MSG_ERR_USERNOTFOUND        = 4003;   //用戶不存在
27   MSG_ERR_WRONGPASSWORD       = 4004;   //密碼錯誤
28   MSG_ERR_USEREXIST           = 4005;   //用戶名已經存在(注冊新用戶業務)
29   MSG_ERR_USERTOOMUCH         = 4006;   //用戶數量已經達到上限(注冊新用戶業務)
30   MSG_ERR_SPACEFULL           = 4007;   //空間已滿
31   MSG_ERR_NOTAUTHUPLOAD       = 4008;   //沒有上傳權限
32   MSG_ERR_NOTAUTHDOWNLOAD     = 4009;   //沒有下載權限
33   MSG_ERR_FILENOTFOUND        = 4010;   //文件不存在
  1 unit snt.client.net.filetrans;
  2 
  3 interface
  4 
  5 uses
  6   System.SysUtils, System.Classes, System.Math, diocp.coder.tcpClient,
  7   utils.simpleMsgPack, snt.net.coder.stream, snt.net.msgcode;
  8 
  9 type
 10   TSNTFileTransContext = class(TObject)
 11   private
 12     FCoderTcpClient: TDiocpCoderTcpClient;
 13     FDiocpContext: TIocpCoderRemoteContext;
 14     FCMDStream: TMemoryStream;
 15     FCMDMsgPack: TSimpleMsgPack;
 16     procedure OnRecvObject(pvObject:TObject);
 17     procedure SendCMDObject(pvCMDObject: TSimpleMsgPack);
 18     function  GetFileSize(const pvFile: string): Int64;
 19   private
 20     FFileStream: TFileStream;
 21     FLocalFile, FRemoteFile: string;
 22     FFileSize: Int64;
 23     function  upload(const pvRemoteFile, pvToken: string): Int64;
 24     procedure uploadNextBlock(const pvToken: string = '');
 25     function  download(const pvRemoteFile: string; const pvFileSize: Int64): Int64;
 26     procedure downloadNextBlock();
 27   public
 28     constructor Create(pvCoderTcpClient: TDiocpCoderTcpClient);
 29     destructor Destroy; override;
 30 
 31     procedure init(const pvHost: string; const pvPort: Integer);
 32     procedure requestUpload(const pvLocalFile, pvToken: string);
 33     procedure requestDownload(const pvLocalFile, pvToken: string);
 34   end;
 35 
 36 implementation
 37 
 38 uses utils.safeLogger;
 39 
 40 const
 41   SEC_SIZE = 1024 * 1024;
 42 
 43 { TSNTFileTransContext }
 44 
 45 constructor TSNTFileTransContext.Create(pvCoderTcpClient: TDiocpCoderTcpClient);
 46 begin
 47   inherited Create;
 48   FCoderTcpClient:= pvCoderTcpClient;
 49   FCMDStream  := TMemoryStream.Create;
 50   FCMDMsgPack := TSimpleMsgPack.Create;
 51 end;
 52 
 53 destructor TSNTFileTransContext.Destroy;
 54 begin
 55   if Assigned(FFileStream) then FFileStream.Free;
 56   FCMDStream.Free;
 57   FCMDMsgPack.Free;
 58   inherited;
 59 end;
 60 
 61 procedure TSNTFileTransContext.init(const pvHost: string; const pvPort: Integer);
 62 begin
 63   FDiocpContext:= TIocpCoderRemoteContext(FCoderTcpClient.Add);
 64   FDiocpContext.RegisterCoderClass(TIOCPStreamDecoder, TIOCPStreamEncoder);
 65   FDiocpContext.OnContextAction:= OnRecvObject;
 66   if not FDiocpContext.Active then
 67   begin
 68     FDiocpContext.Host:= pvHost;
 69     FDiocpContext.Port:= pvPort;
 70     FDiocpContext.Connect;
 71   end;
 72 end;
 73 
 74 procedure TSNTFileTransContext.SendCMDObject(pvCMDObject: TSimpleMsgPack);
 75 var
 76   lvCMDStream:TMemoryStream;
 77 begin
 78   lvCMDStream := TMemoryStream.Create;
 79   try
 80     pvCMDObject.EncodeToStream(lvCMDStream);
 81     FDiocpContext.WriteObject(lvCMDStream);
 82   finally
 83     lvCMDStream.Free;
 84   end;
 85 end;
 86 
 87 function TSNTFileTransContext.GetFileSize(const pvFile: string): Int64;
 88 var
 89   lvFileStream: TFileStream;
 90 begin
 91   lvFileStream:= TFileStream.Create(FLocalFile, fmOpenRead);
 92   try
 93     result:= lvFileStream.Size;
 94   finally
 95     lvFileStream.Free;
 96   end;
 97 end;
 98 
 99 procedure TSNTFileTransContext.requestUpload(const pvLocalFile, pvToken: string);
100 var
101   lvMsgData: TSimpleMsgPack;
102 begin
103   lvMsgData:= TSimpleMsgPack.Create;
104   try
105     FLocalFile:= pvLocalFile;
106     lvMsgData.I['service.type']    := MSG_SERVICE_FILE;
107     lvMsgData.I['msg.code']        := MSG_FILE_REQ_UPLOAD;
108     lvMsgData.S['params.filename'] := ExtractFileName(pvLocalFile);
109     lvMsgData.I['params.filesize'] := GetFileSize(pvLocalFile);
110     lvMsgData.S['params.token']    := pvToken;
111     SendCMDObject(lvMsgData);
112   finally
113     FreeAndNil(lvMsgData);
114   end;
115 end;
116 
117 procedure TSNTFileTransContext.requestDownload(const pvLocalFile, pvToken: string);
118 var
119   lvMsgData: TSimpleMsgPack;
120 begin
121   lvMsgData:= TSimpleMsgPack.Create;
122   try
123     FLocalFile:= pvLocalFile;
124     lvMsgData.I['service.type']    := MSG_SERVICE_FILE;
125     lvMsgData.I['msg.code']        := MSG_FILE_REQ_DOWNLOAD;
126     lvMsgData.S['params.filename'] := ExtractFileName(pvLocalFile);
127     lvMsgData.S['params.token']    := pvToken;
128     SendCMDObject(lvMsgData);
129   finally
130     FreeAndNil(lvMsgData);
131   end;
132 end;
133 
134 function TSNTFileTransContext.upload(const pvRemoteFile, pvToken: string): Int64;
135 begin
136   FFileStream:= TFileStream.Create(FLocalFile, fmOpenRead);
137   FRemoteFile:= pvRemoteFile;
138   uploadNextBlock(pvToken);
139 end;
140 
141 procedure TSNTFileTransContext.uploadNextBlock(const pvToken: string);
142 var
143   lvPosition, lvSize: Int64;
144 begin
145   lvPosition:= FFileStream.Position;
146   if (FFileStream.Position = FFileStream.Size) then exit;
147 
148   FCMDMsgPack.clear();
149   FCMDMsgPack.I['service.type']   := MSG_SERVICE_FILE;
150   FCMDMsgPack.I['msg.code']       := MSG_FILE_UPLOADING;
151   FCMDMsgPack.S['params.filename']:= FRemoteFile;
152   FCMDMsgPack.S['params.token']   := pvToken;
153   FCMDMsgPack.I['params.start']   := lvPosition;
154   lvSize:= Min(SEC_SIZE, FFileStream.Size- FFileStream.Position);
155   FCMDMsgPack.ForcePathObject('params.data').LoadBinaryFromStream(FFileStream, lvSize);
156   if (FFileStream.Position = FFileStream.Size) then
157     FCMDMsgPack.B['params.isend'] := True;
158   //
159   FCMDStream.Clear;
160   FCMDMsgPack.EncodeToStream(FCMDStream);
161   FDiocpContext.WriteObject(FCMDStream);
162 end;
163 
164 
165 function TSNTFileTransContext.download(const pvRemoteFile: string;
166 
167   const pvFileSize: Int64): Int64;
168 
169 begin
170   FFileStream:= TFileStream.Create(FLocalFile, fmCreate or fmShareDenyWrite);
171   FRemoteFile:= pvRemoteFile;
172   FFileSize  := pvFileSize;
173   downloadNextBlock();
174 end;
175 
176 procedure TSNTFileTransContext.downloadNextBlock;
177 var
178   lvPosition, lvSize: Int64;
179   lvBytes: TBytes;
180 begin
181   lvBytes := FCMDMsgPack.ForcePathObject('data').AsBytes;
182   FFileStream.Write(lvBytes[0], Length(lvBytes));
183   if FFileStream.Size = FFileSize then exit;
184 
185   FCMDMsgPack.clear();
186   FCMDMsgPack.I['service.type']    := MSG_SERVICE_FILE;
187   FCMDMsgPack.I['msg.code']        := MSG_FILE_DOWNLOADING;
188   FCMDMsgPack.S['params.filename'] := FRemoteFile;
189   FCMDMsgPack.I['params.start']    := FFileStream.Position;
190   FCMDStream.Clear;
191   FCMDMsgPack.EncodeToStream(FCMDStream);
192   FDiocpContext.WriteObject(FCMDStream);
193 end;
194 
195 procedure TSNTFileTransContext.OnRecvObject(pvObject: TObject);
196 var
197   lvMsgData: TSimpleMsgPack;
198 begin
199   lvMsgData:= TSimpleMsgPack.Create;
200   try
201     lvMsgData.DecodeFromStream(TMemoryStream(pvObject));
202     // server error
203     if lvMsgData.I['result.code'] = -1 then
204     begin
205       sfLogger.logMessage(lvMsgData.S['result.msg']);
206       exit;
207     end;
208     sfLogger.logMessage(lvMsgData.S['msg.code']);
209     // logic
210     case lvMsgData.I['msg.code'] of
211       MSG_FILE_READYUPLOAD:
212         upload(lvMsgData.S['params.filename'],lvMsgData.S['params.token']);
213       MSG_FILE_UPLOADING:
214         uploadNextBlock();
215       MSG_FILE_READYDOWNLOAD:
216         download(lvMsgData.S['params.filename'],lvMsgData.I['params.filesize']);
217       MSG_FILE_DOWNLOADING:
218         downloadNextBlock();
219       MSG_ERR_NOTAUTHUPLOAD:
220         ;//沒有上傳權限
221       MSG_ERR_SPACEFULL:
222         ;//空間不足
223       MSG_ERR_NOTAUTHDOWNLOAD:
224         ;//沒有下載權限
225       MSG_ERR_FILENOTFOUND:
226         ;//文件不存在
227     end;
228   finally
229     lvMsgData.Free;
230   end;
231 end;

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved