完成了服务端的基本功能,把客户端也完善了一些,服务端功能实现:
- 通讯消息定义
- 用户管理结构设计
- 在服务端用一个json文件存取用户数据
- 自定义文件存取路径(考虑分布式部署)
- 用户注册
- 用户登录
- 文件上传校验
- 文件下载校验
- 批量文件上传、下载
开发环境: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, TIOCPStreamEnco