Pyrogenesis  trunk
NetFileTransfer.h
Go to the documentation of this file.
1 /* Copyright (C) 2021 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef NETFILETRANSFER_H
19 #define NETFILETRANSFER_H
20 
21 #include <map>
22 #include <string>
23 
24 class CNetMessage;
25 class CFileTransferResponseMessage;
26 class CFileTransferDataMessage;
27 class CFileTransferAckMessage;
28 class INetSession;
29 
30 // Assume this is sufficiently less than MTU that packets won't get
31 // fragmented or dropped.
32 static const size_t DEFAULT_FILE_TRANSFER_PACKET_SIZE = 1024;
33 
34 // To improve performance without flooding ENet's internal buffers,
35 // maintain a small number of in-flight packets.
36 // Pick numbers so that with e.g. 200ms round-trip latency
37 // we can hopefully get windowSize*packetSize*1000/200 = 160KB/s bandwidth
38 static const size_t DEFAULT_FILE_TRANSFER_WINDOW_SIZE = 32;
39 
40 // Some arbitrary limit to make it slightly harder to use up all of someone's RAM
41 static const size_t MAX_FILE_TRANSFER_SIZE = 8*MiB;
42 
43 /**
44  * Asynchronous file-receiving task.
45  * Other code should subclass this, implement OnComplete(),
46  * then pass it to CNetFileTransferer::StartTask.
47  */
49 {
50 public:
52  virtual ~CNetFileReceiveTask() {}
53 
54  /**
55  * Called when m_Buffer contains the full received data.
56  */
57  virtual void OnComplete() = 0;
58 
59  // TODO: Ought to have an OnFailure, e.g. when the session drops or there's another error
60 
61  /**
62  * Uniquely identifies the request within the scope of its CNetFileTransferer.
63  * Set automatically by StartTask.
64  */
66 
67  size_t m_Length;
68 
69  std::string m_Buffer;
70 };
71 
72 /**
73  * Handles transferring files between clients and servers.
74  */
76 {
77 public:
79  : m_Session(session), m_NextRequestID(1), m_LastProgressReportTime(0)
80  {
81  }
82 
83  /**
84  * Should be called when a message is received from the network.
85  * Returns INFO::SKIPPED if the message is not one that this class handles.
86  * Returns INFO::OK if the message is handled successfully,
87  * or ERR::FAIL if handled unsuccessfully.
88  */
89  Status HandleMessageReceive(const CNetMessage& message);
90 
91  /**
92  * Registers a file-receiving task.
93  */
94  void StartTask(const std::shared_ptr<CNetFileReceiveTask>& task);
95 
96  /**
97  * Registers data to be sent in response to a request.
98  * (Callers are expected to have their own mechanism for receiving
99  * requests and deciding what to respond with.)
100  */
101  void StartResponse(u32 requestID, const std::string& data);
102 
103  /**
104  * Call frequently (e.g. once per frame) to trigger any necessary
105  * packet processing.
106  */
107  void Poll();
108 
109 private:
110  Status OnFileTransferResponse(const CFileTransferResponseMessage& message);
111  Status OnFileTransferData(const CFileTransferDataMessage& message);
112  Status OnFileTransferAck(const CFileTransferAckMessage& message);
113 
114  /**
115  * Asynchronous file-sending task.
116  */
118  {
120  std::string buffer;
121  size_t offset;
124  };
125 
127 
129 
130  using FileReceiveTasksMap = std::map<u32, std::shared_ptr<CNetFileReceiveTask>>;
132 
133  using FileSendTasksMap = std::map<u32, CNetFileSendTask>;
135 
137 };
138 
139 #endif // NETFILETRANSFER_H
virtual ~CNetFileReceiveTask()
Definition: NetFileTransfer.h:52
size_t packetsInFlight
Definition: NetFileTransfer.h:123
FileSendTasksMap m_FileSendTasks
Definition: NetFileTransfer.h:134
u32 m_NextRequestID
Definition: NetFileTransfer.h:128
static const size_t DEFAULT_FILE_TRANSFER_WINDOW_SIZE
Definition: NetFileTransfer.h:38
static const size_t MAX_FILE_TRANSFER_SIZE
Definition: NetFileTransfer.h:41
Interface for sessions to which messages can be sent.
Definition: NetSession.h:55
CNetFileTransferer(INetSession *session)
Definition: NetFileTransfer.h:78
static const size_t DEFAULT_FILE_TRANSFER_PACKET_SIZE
Definition: NetFileTransfer.h:32
size_t maxWindowSize
Definition: NetFileTransfer.h:122
double m_LastProgressReportTime
Definition: NetFileTransfer.h:136
uint32_t u32
Definition: types.h:39
std::map< u32, CNetFileSendTask > FileSendTasksMap
Definition: NetFileTransfer.h:133
virtual void OnComplete()=0
Called when m_Buffer contains the full received data.
Asynchronous file-receiving task.
Definition: NetFileTransfer.h:48
std::string m_Buffer
Definition: NetFileTransfer.h:69
static const size_t MiB
Definition: alignment.h:105
FileReceiveTasksMap m_FileReceiveTasks
Definition: NetFileTransfer.h:131
std::map< u32, std::shared_ptr< CNetFileReceiveTask > > FileReceiveTasksMap
Definition: NetFileTransfer.h:130
i64 Status
Error handling system.
Definition: status.h:169
u32 m_RequestID
Uniquely identifies the request within the scope of its CNetFileTransferer.
Definition: NetFileTransfer.h:65
The base class for all network messages exchanged within the game.
Definition: NetMessage.h:32
std::string buffer
Definition: NetFileTransfer.h:120
INetSession * m_Session
Definition: NetFileTransfer.h:126
Handles transferring files between clients and servers.
Definition: NetFileTransfer.h:75
size_t m_Length
Definition: NetFileTransfer.h:67
CNetFileReceiveTask()
Definition: NetFileTransfer.h:51
u32 requestID
Definition: NetFileTransfer.h:119
size_t offset
Definition: NetFileTransfer.h:121
Asynchronous file-sending task.
Definition: NetFileTransfer.h:117