source: Daodan/src/Flatline_Net.c@ 573

Last change on this file since 573 was 484, checked in by gumby, 15 years ago

ZOMG FLATLINE

File size: 5.5 KB
Line 
1#include "Flatline.h"
2#include "Flatline_Server.h"
3
4
5#define TRACK_PACKETS
6thread int UDPServer_Socket = 0;
7
8
9
10
11bool NetUDPServer_Listen(uint16_t port, bool (*packet_callback)(char* data, int datalen, int from))
12{
13 UDPServer_Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
14
15 if (UDPServer_Socket < 0)
16 {
17 DDrConsole_PrintF("could not create socket");
18 return false;
19 }
20
21 sockaddr_in address;
22 memset(&address, 0, sizeof(sockaddr_in));
23 address.sin_family = AF_INET;
24 address.sin_addr.s_addr = htonl(INADDR_ANY);
25 address.sin_port = htons(port);
26
27 if (bind(UDPServer_Socket, (sockaddr*)&address, sizeof(sockaddr_in)) < 0)
28 {
29 DDrConsole_PrintF("could not bind port %d", port);
30 closesocket(UDPServer_Socket);
31 return false;
32 }
33
34 FLrServer_Initialize();
35
36 char data[65537];
37 data[65536] = '\0';
38 sockaddr_in from;
39 int recvlen;
40 for (;;)
41 {
42 int fromlen = sizeof(sockaddr_in);
43 memset(&from, 0, sizeof(sockaddr_in));
44 recvlen = recvfrom(UDPServer_Socket, data, sizeof(data) - 1, 0, (sockaddr*)&from, (void*)&fromlen);
45 if (!packet_callback(data, recvlen, ntohl(from.sin_addr.s_addr)))
46 break;
47 }
48 closesocket(UDPServer_Socket);
49 return true;
50}
51
52bool NetUDPServer_Send(sockaddr* address, char* data, int datalen)
53{
54 //DDrConsole_PrintF("Sending data size %u to %s on socket %i", datalen, inet_ntoa( ((sockaddr_in*)address)->sin_addr ), UDPServer_Socket);
55 return NetUDPSocket_Send(UDPServer_Socket, address, data, datalen);
56}
57
58int client_sock = 0;
59sockaddr_in client_address;
60
61int NetUDPSocket_Create(uint16_t port)
62{
63 int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
64
65 if (sock < 0)
66 {
67 DDrConsole_PrintF("could not create socket");
68 return -1;
69 }
70
71 sockaddr_in address;
72 memset(&client_address, 0, sizeof(sockaddr_in));
73 address.sin_family = AF_INET;
74 address.sin_addr.s_addr = htonl(INADDR_ANY);
75 address.sin_port = htons(port);
76
77 if (bind(sock, (sockaddr*)&address, sizeof(sockaddr_in)) < 0)
78 {
79 DDrConsole_PrintF("could not bind port %d", port);
80 return false;
81 }
82
83 unsigned long nonBlocking = 1;
84 if (ioctlsocket(sock, FIONBIO, &nonBlocking))
85 {
86 DDrConsole_PrintF("failed to set non-blocking socket");
87 return false;
88 }
89 client_sock = sock;
90 client_address = address;
91 return sock;
92}
93
94int NetTCPSocket_Create(uint16_t port)
95{
96 int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
97
98 if (sock < 0)
99 {
100 DDrConsole_PrintF("could not create socket");
101 return -1;
102 }
103
104 sockaddr_in address;
105 memset(&client_address, 0, sizeof(sockaddr_in));
106 address.sin_family = AF_INET;
107 address.sin_addr.s_addr = htonl(INADDR_ANY);
108 address.sin_port = htons(port);
109
110 if (bind(sock, (sockaddr*)&address, sizeof(sockaddr_in)) < 0)
111 {
112 DDrConsole_PrintF("could not bind port %d", port);
113 return false;
114 }
115
116 unsigned long nonBlocking = 1;
117 if (ioctlsocket(sock, FIONBIO, &nonBlocking))
118 {
119 DDrConsole_PrintF("failed to set non-blocking socket");
120 return false;
121 }
122 client_sock = sock;
123 client_address = address;
124 return sock;
125}
126
127
128void NetUDPSocket_Close(int socket)
129{
130 closesocket(socket);
131}
132
133int NetUDPSocket_Send(int socket, const sockaddr* address, const char* data, int datalen)
134{
135 //currently only protects against duplicate packets.
136#ifdef TRACK_PACKETS
137 static uint32_t packet_index = 0;
138 packet_index = (packet_index + 1);
139 ((flatline_packet*)(data))->packet_index = packet_index;
140#endif
141 int addr_size;
142 switch (address->sa_family)
143 {
144 case AF_INET:
145 addr_size = sizeof(sockaddr_in);
146 break;
147 case AF_INET6:
148 addr_size = sizeof(sockaddr_in6);
149 break;
150 default:
151 addr_size = sizeof(sockaddr_storage);
152 }
153 return sendto(socket, data, datalen, 0, address, addr_size);
154}
155
156#ifdef TRACK_PACKETS
157uint32_t last_packet = -1;
158#endif
159
160bool NetUDPSocket_Recieve(int socket, sockaddr_storage* address, char* data, uint16_t* datalen)
161{
162 int address_size = sizeof(sockaddr_storage);
163 uint32_t msg_size = recvfrom(socket, data, 1400, 0, (SOCKADDR *)address, &address_size);
164 if (msg_size == 0)
165 return false;
166 else if (msg_size == SOCKET_ERROR) {
167 int errorno = WSAGetLastError();
168 if (errorno == WSAEWOULDBLOCK) return false; //no packets.
169 else {
170 DDrConsole_PrintF("Packet type %i", ((flatline_packet*)data)->id);
171 NetCatchError();
172 return false;
173 }
174 }
175 /*
176#ifdef TRACK_PACKETS
177 if(client_connected && !server_started) {
178 uint32_t index_mkr = ((flatline_packet*)(data))->packet_index;
179 //fancy way of checking if index_mkr is on one side of the max size of an int and last_packet is on the other
180 if( ((index_mkr - last_packet < 0x80000000) && (index_mkr > last_packet))
181 //if it is, subtract half the size of an int from each. ^_^
182 || ((index_mkr - 0x80000000) > (last_packet - 0x80000000) ) )
183 {
184 return false;
185 }
186 else {
187 last_packet = index_mkr;
188 }
189 }
190
191#endif
192 */
193
194 *datalen = msg_size;
195 return true;
196
197}
198
199DWORD WINAPI StartServer(void* lol){
200 NetPlatform_Initalize();
201 FLrServer_Run();
202 return 0;
203}
204
205DWORD WINAPI StartClient(void* lol){
206 //NetPlatform_Initalize();
207 FLrClient_Run((flatline_packet*)lol);
208 return 0;
209}
210void NetCatchError(){
211 int errorno = WSAGetLastError();
212 if(errno == WSAEWOULDBLOCK) {
213 return;
214 }
215 #ifdef WIN32
216 char Message[1024];
217 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
218 FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, errorno,
219 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
220 (LPSTR) Message, 1024, NULL);
221 DDrConsole_Print(Message);
222 #endif
223
224}
Note: See TracBrowser for help on using the repository browser.