3 /////////////////////////////////////////////////////////////////////
5 typedef byte XDWord[4];
8 #define MDWORD(a,b) ((((uint32)((uint16)(b)))<<16)+((uint16)(a)))
9 #define LOWORD(l) ((uint16)(l))
10 #define HIWORD(l) ((uint16)(((uint32)(l) >> 16) & 0xFFFF))
12 #define SWAP_WORD(word) (((uint16)(word) & 0x00ff) << 8) \
13 | (((uint16)(word) & 0xff00) >> 8)
15 #define SWAP_DWORD(dword) ((((uint32)(dword) & 0x000000ff) << 24) \
16 | (((uint32)(dword) & 0x0000ff00) << 8) \
17 | (((uint32)(dword) & 0x00ff0000) >> 8) \
18 | (((uint32)(dword) & 0xff000000) >> 24))
20 #define PUTXDWORD(b, d) \
21 (b)[0] = (byte)(((d) >> 24) & 0xFF); \
22 (b)[1] = (byte)(((d) >> 16) & 0xFF); \
23 (b)[2] = (byte)(((d) >> 8) & 0xFF); \
24 (b)[3] = (byte)( (d) & 0xFF);
28 (byte)(((d) >> 24) & 0xFF), \
29 (byte)(((d) >> 16) & 0xFF), \
30 (byte)(((d) >> 8) & 0xFF), \
34 #define GETXDWORD(b) (uint32)(((b)[0] << 24) | ((b)[1] << 16) | ((b)[2] << 8) | (b)[3])
36 #define PUTXWORD(b, w) \
37 (b)[0] = (byte)(((w) >> 8) & 0xFF); \
38 (b)[1] = (byte)(((w) ) & 0xFF);
42 (byte)(((w) >> 8) & 0xFF), \
46 #define GETXWORD(b) (uint16)(((b)[0] << 8) | (b)[1])
48 /////////////////////////////////////////////////////////////////////
50 define SERVER_PORT = 7649;
52 define MAX_HANDLES = 16;
54 // Packets sent from Client to Server
56 class BasePacket : struct
62 class OpenPacket : BasePacket
65 char fileName[1]; // Rest follows, null terminated
68 class ClosePacket : BasePacket
73 class ReadPacket : BasePacket
80 class SizePacket : BasePacket
85 enum PacketType { open, close, read, size };
87 class NetworkServer : Service
89 OldList clients { offset = (uint)&((ClientConnection)0).prev };
92 ClientConnection socket { this };
94 Logf("Connection from %s, port %d\n", socket.inetAddress, SERVER_PORT);
98 class ClientConnection : Socket
100 ClientConnection prev, next;
101 File handles[MAX_HANDLES];
105 uint OnReceive(const byte * buffer, uint count)
107 if(count >= sizeof(class Packet))
109 BasePacket packetHeader = (BasePacket) buffer;
110 if(count >= GETXDWORD(packetHeader.size))
112 Log("received packet\n");
113 switch((PacketType)GETXDWORD(packetHeader.type))
117 OpenPacket packet = (OpenPacket) packetHeader;
118 byte reply[4] = XDWORD(MAXDWORD);
122 for(c = 0; c < MAX_HANDLES; c++)
127 // Test valid free handle
130 handles[c] = FileOpen(packet.fileName, read);
132 PUTXDWORD(reply, c+1);
134 Send(reply, sizeof(reply));
139 ClosePacket packet = (ClosePacket) packetHeader;
140 uint handle = GETXDWORD(packet.handle);
142 if(handle > 0 && handle <= MAX_HANDLES)
144 File file = handles[handle-1];
148 handles[handle-1] = null;
155 ReadPacket packet = (ReadPacket) packetHeader;
157 uint handle = GETXDWORD(packet.handle);
160 if(handle > 0 && handle <= MAX_HANDLES)
162 File file = handles[handle-1];
165 uint readSize = GETXDWORD(packet.readSize);
167 if(readSize > this.readSize)
169 readBuf = renew readBuf byte[readSize];
170 this.readSize = readSize;
174 file.Seek(GETXDWORD(packet.readStart), start);
175 realRead = file.Read(readBuf, 1, readSize);
179 PUTXDWORD(reply, realRead);
180 Send(reply, sizeof(reply));
181 Send(readBuf, realRead);
186 SizePacket packet = (SizePacket) packetHeader;
187 byte reply[4] = XDWORD(0);
188 uint handle = GETXDWORD(packet.handle);
189 Logf("Size %d\n",handle);
190 if(handle > 0 && handle <= MAX_HANDLES)
192 File file = handles[handle-1];
198 PUTXDWORD(reply, size);
201 Send(reply, sizeof(reply));
205 Log("Unknown packet type\n");
207 Log("Request processed\n");
208 return GETXDWORD(packetHeader.size);
214 void OnDisconnect(int code)
217 ((NetworkServer)service).clients.Remove(this);
221 NetworkServer tcpServer { port = SERVER_PORT };
223 class ServerApp : GuiApplication
227 // SetLoggingMode(stdout, null);
228 SetLoggingMode(0, null);
229 if(tcpServer.Start())
231 Log("Server started\n");
235 ProcessNetworkEvents();