7 #define WIN32_LEAN_AND_MEAN
11 static WSADATA wsaData;
13 #elif defined(__unix__) || defined(__APPLE__)
20 #include <netinet/in.h>
22 #include <sys/select.h>
23 #include <sys/socket.h>
25 #include <sys/types.h>
27 #include <arpa/inet.h>
31 typedef struct hostent HOSTENT;
32 typedef struct sockaddr SOCKADDR;
33 typedef struct sockaddr_in SOCKADDR_IN;
34 typedef struct in_addr IN_ADDR;
35 #define closesocket(s) close(s)
39 import "GuiApplication"
43 private struct NetworkData
45 // Connections to the outside world
49 // Ongoing Connections
50 OldList connectSockets;
52 fd_set readSet, writeSet, exceptSet;
53 fd_set selectRS, selectWS, selectES;
57 // Synchronization Elements
59 Semaphore socketsSemaphore;
60 Semaphore selectSemaphore;
63 bool networkInitialized;
64 bool networkTerminated;
65 uint errorLevel, lastErrorCode;
77 static class NetworkThread : Thread
82 while(!network.networkTerminated)
88 struct timeval tv = { 0, 0 }; // TESTING 0 INSTEAD OF (int)(1000000 / 18.2) };
90 network.selectRS = network.readSet, network.selectWS = network.writeSet, network.selectES = network.exceptSet;
92 network.mutex.Release();
94 Log("[N] Waiting for network event...\n");
96 if(select(ns, &network.selectRS, &network.selectWS, &network.selectES, &tv))
99 network.networkEvent = true;
101 Log("[N] Signaling Network event\n");
103 guiApp.SignalEvent();
105 Log("[N] Waiting for select semaphore in Network Thread...\n");
107 network.mutex.Release();
108 network.selectSemaphore.Wait();
109 network.mutex.Wait();
113 ecere::sys::Sleep(1 / 18.2f);
114 network.mutex.Wait();
119 network.mutex.Release();
120 network.socketsSemaphore.Wait();
121 network.mutex.Wait();
125 network.mutex.Release();
130 void Network_DetermineMaxSocket()
135 network.mutex.Wait();
137 for(socket = network.sockets.first; socket; socket = socket.next)
138 if(!socket.processAlone && !socket.destroyed && socket.s >= network.ns)
139 network.ns = (int)(socket.s + 1);
140 for(socket = network.connectSockets.first; socket; socket = socket.next)
141 if(!socket.destroyed && socket.s >= network.ns)
142 network.ns = (int)(socket.s + 1);
144 for(service = network.services.first; service; service = service.next)
146 if(!service.destroyed && !service.processAlone)
148 if(service.s >= network.ns)
149 network.ns = (int)(service.s + 1);
151 for(socket = service.sockets.first; socket; socket = socket.next)
152 if(!socket.destroyed && !socket.processAlone && socket.s >= network.ns)
153 network.ns = (int)(socket.s + 1);
155 network.mutex.Release();
158 // --- Network System ---
161 bool Network_Initialize()
164 if(!network.networkInitialized)
166 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
167 network.networkInitialized = true;
168 network.networkTerminated = false;
169 #if defined(__WIN32__)
170 WSAStartup(0x0002, &wsaData);
173 network.services.Clear();
175 network.services.offset = (uint)&((Service)0).prev;
176 network.sockets.Clear();
178 network.sockets.offset = (uint)&((Socket)0).prev;
180 network.connectSockets.Clear();
181 network.connectSockets.offset = (uint)&((Socket)0).prev;
183 FD_ZERO(&network.readSet);
184 FD_ZERO(&network.writeSet);
185 FD_ZERO(&network.exceptSet);
187 network.socketsSemaphore = Semaphore { };
188 network.selectSemaphore = Semaphore { };
189 network.networkThread = NetworkThread { };
190 incref network.networkThread;
192 network.errorLevel = 2;
194 network.processMutex = Mutex { };
195 network.mutex = Mutex { };
197 network.mainThreadID = GetCurrentThreadID();
199 network.networkThread.Create();
208 void Network_Terminate()
212 if(network.networkInitialized)
214 #if defined(__WIN32__) || defined(__unix__) || defined(__APPLE__)
218 guiApp.PauseNetworkEvents();
219 network.networkTerminated = true;
221 delete network.processMutex;
222 delete network.mutex;
224 for(socket = network.connectSockets.first; socket; socket = socket.next)
226 socket.connectThread.Wait();
227 delete socket.connectThread;
230 network.socketsSemaphore.Release();
231 network.selectSemaphore.Release();
233 network.networkThread.Wait();
234 delete network.networkThread;
236 // Cleanup External network.sockets
237 while((socket = network.sockets.first))
240 //network.sockets.Remove(socket); //THIS IS ALREADY DONE IN Socket::Free
242 if(socket._refCount > 1) socket._refCount--;
245 while((socket = network.connectSockets.first))
247 //network.connectSockets.Remove(socket); //THIS IS ALREADY DONE IN Socket::Free
252 // Cleanup network.services
253 while((service = network.services.first))
258 #if defined(__WIN32__)
262 delete network.selectSemaphore;
263 delete network.socketsSemaphore;
266 Log("[P] Network System Terminated\n");
268 network.networkInitialized = false;
275 public bool GetAddressFromName(char * hostName, char * inetAddress)
279 if(!Network_Initialize())
282 host = gethostbyname(hostName);
285 strcpy(inetAddress, inet_ntoa(*((IN_ADDR *)host->h_addr)));
291 public bool GetNameFromAddress(char * inetAddress, char * hostName)
296 if(!Network_Initialize())
299 in.s_addr = inet_addr(inetAddress);
300 host = gethostbyaddr((byte *)&in, 4, PF_INET);
303 strcpy(hostName, host->h_name);
309 public bool GetHostName(char * hostName, int size)
311 if(!Network_Initialize())
314 return !gethostname(hostName,size);