zenilib: zenilib/jni/external/sdl_net/chatd.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
chatd.c
Go to the documentation of this file.
1 /*
2 CHATD: A chat server using the SDL example network library
3 Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20 */
21
22 /* Note that this isn't necessarily the way to run a chat system.
23 This is designed to excercise the network code more than be really
24 functional.
25 */
26
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 #include "SDL.h"
32 #include "SDL_net.h"
33 #include "chat.h"
34
35 /* This is really easy. All we do is monitor connections */
36
37 static TCPsocket servsock = NULL;
38 static SDLNet_SocketSet socketset = NULL;
39 static struct {
40 int active;
41 TCPsocket sock;
42 IPaddress peer;
43 Uint8 name[256+1];
44 } people[CHAT_MAXPEOPLE];
45
46
47 void HandleServer(void)
48 {
49 TCPsocket newsock;
50 int which;
51 unsigned char data;
52
53 newsock = SDLNet_TCP_Accept(servsock);
54 if ( newsock == NULL ) {
55 return;
56 }
57
58 /* Look for unconnected person slot */
59 for ( which=0; which<CHAT_MAXPEOPLE; ++which ) {
60 if ( ! people[which].sock ) {
61 break;
62 }
63 }
64 if ( which == CHAT_MAXPEOPLE ) {
65 /* Look for inactive person slot */
66 for ( which=0; which<CHAT_MAXPEOPLE; ++which ) {
67 if ( people[which].sock && ! people[which].active ) {
68 /* Kick them out.. */
69 data = CHAT_BYE;
70 SDLNet_TCP_Send(people[which].sock, &data, 1);
71 SDLNet_TCP_DelSocket(socketset,
72 people[which].sock);
73 SDLNet_TCP_Close(people[which].sock);
74 #ifdef DEBUG
75 fprintf(stderr, "Killed inactive socket %d\n", which);
76 #endif
77 break;
78 }
79 }
80 }
81 if ( which == CHAT_MAXPEOPLE ) {
82 /* No more room... */
83 data = CHAT_BYE;
84 SDLNet_TCP_Send(newsock, &data, 1);
85 SDLNet_TCP_Close(newsock);
86 #ifdef DEBUG
87 fprintf(stderr, "Connection refused -- chat room full\n");
88 #endif
89 } else {
90 /* Add socket as an inactive person */
91 people[which].sock = newsock;
92 people[which].peer = *SDLNet_TCP_GetPeerAddress(newsock);
93 SDLNet_TCP_AddSocket(socketset, people[which].sock);
94 #ifdef DEBUG
95 fprintf(stderr, "New inactive socket %d\n", which);
96 #endif
97 }
98 }
99
100 /* Send a "new client" notification */
101 void SendNew(int about, int to)
102 {
103 char data[512];
104 int n;
105
106 n = strlen((char *)people[about].name)+1;
107 data[0] = CHAT_ADD;
108 data[CHAT_ADD_SLOT] = about;
109 memcpy(&data[CHAT_ADD_HOST], &people[about].peer.host, 4);
110 memcpy(&data[CHAT_ADD_PORT], &people[about].peer.port, 2);
111 data[CHAT_ADD_NLEN] = n;
112 memcpy(&data[CHAT_ADD_NAME], people[about].name, n);
113 SDLNet_TCP_Send(people[to].sock, data, CHAT_ADD_NAME+n);
114 }
115
116 void HandleClient(int which)
117 {
118 char data[512];
119 int i;
120
121 /* Has the connection been closed? */
122 if ( SDLNet_TCP_Recv(people[which].sock, data, 512) <= 0 ) {
123 #ifdef DEBUG
124 fprintf(stderr, "Closing socket %d (was%s active)\n",
125 which, people[which].active ? "" : " not");
126 #endif
127 /* Notify all active clients */
128 if ( people[which].active ) {
129 people[which].active = 0;
130 data[0] = CHAT_DEL;
131 data[CHAT_DEL_SLOT] = which;
132 for ( i=0; i<CHAT_MAXPEOPLE; ++i ) {
133 if ( people[i].active ) {
134 SDLNet_TCP_Send(people[i].sock,data,CHAT_DEL_LEN);
135 }
136 }
137 }
138 SDLNet_TCP_DelSocket(socketset, people[which].sock);
139 SDLNet_TCP_Close(people[which].sock);
140 people[which].sock = NULL;
141 } else {
142 switch (data[0]) {
143 case CHAT_HELLO: {
144 /* Yay! An active connection */
145 memcpy(&people[which].peer.port,
146 &data[CHAT_HELLO_PORT], 2);
147 memcpy(people[which].name,
148 &data[CHAT_HELLO_NAME], 256);
149 people[which].name[256] = 0;
150 #ifdef DEBUG
151 fprintf(stderr, "Activating socket %d (%s)\n",
152 which, people[which].name);
153 #endif
154 /* Notify all active clients */
155 for ( i=0; i<CHAT_MAXPEOPLE; ++i ) {
156 if ( people[i].active ) {
157 SendNew(which, i);
158 }
159 }
160
161 /* Notify about all active clients */
162 people[which].active = 1;
163 for ( i=0; i<CHAT_MAXPEOPLE; ++i ) {
164 if ( people[i].active ) {
165 SendNew(i, which);
166 }
167 }
168 }
169 break;
170 default: {
171 /* Unknown packet type?? */;
172 }
173 break;
174 }
175 }
176 }
177
178 static void cleanup(int exitcode)
179 {
180 if ( servsock != NULL ) {
181 SDLNet_TCP_Close(servsock);
182 servsock = NULL;
183 }
184 if ( socketset != NULL ) {
185 SDLNet_FreeSocketSet(socketset);
186 socketset = NULL;
187 }
188 SDLNet_Quit();
189 SDL_Quit();
190 exit(exitcode);
191 }
192
193 main(int argc, char *argv[])
194 {
195 IPaddress serverIP;
196 int i;
197
198 /* Initialize SDL */
199 if ( SDL_Init(0) < 0 ) {
200 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
201 exit(1);
202 }
203
204 /* Initialize the network */
205 if ( SDLNet_Init() < 0 ) {
206 fprintf(stderr, "Couldn't initialize net: %s\n",
207 SDLNet_GetError());
208 SDL_Quit();
209 exit(1);
210 }
211
212 /* Initialize the channels */
213 for ( i=0; i<CHAT_MAXPEOPLE; ++i ) {
214 people[i].active = 0;
215 people[i].sock = NULL;
216 }
217
218 /* Allocate the socket set */
219 socketset = SDLNet_AllocSocketSet(CHAT_MAXPEOPLE+1);
220 if ( socketset == NULL ) {
221 fprintf(stderr, "Couldn't create socket set: %s\n",
222 SDLNet_GetError());
223 cleanup(2);
224 }
225
226 /* Create the server socket */
227 SDLNet_ResolveHost(&serverIP, NULL, CHAT_PORT);
228 printf("Server IP: %x, %d\n", serverIP.host, serverIP.port);
229 servsock = SDLNet_TCP_Open(&serverIP);
230 if ( servsock == NULL ) {
231 fprintf(stderr, "Couldn't create server socket: %s\n",
232 SDLNet_GetError());
233 cleanup(2);
234 }
235 SDLNet_TCP_AddSocket(socketset, servsock);
236
237 /* Loop, waiting for network events */
238 for ( ; ; ) {
239 /* Wait for events */
240 SDLNet_CheckSockets(socketset, ~0);
241
242 /* Check for new connections */
243 if ( SDLNet_SocketReady(servsock) ) {
244 HandleServer();
245 }
246
247 /* Check for events on existing clients */
248 for ( i=0; i<CHAT_MAXPEOPLE; ++i ) {
249 if ( SDLNet_SocketReady(people[i].sock) ) {
250 HandleClient(i);
251 }
252 }
253 }
254 cleanup(0);
255
256 /* Not reached, but fixes compiler warnings */
257 return 0;
258 }
259
SDLNet_TCP_Send
DECLSPEC int SDLCALL SDLNet_TCP_Send(TCPsocket sock, const void *data, int len)
Definition: SDLnetTCP.c:236
SDLNet_CheckSockets
DECLSPEC int SDLCALL SDLNet_CheckSockets(SDLNet_SocketSet set, Uint32 timeout)
Definition: SDLnetselect.c:110
active
volatile SDL_bool active
Definition: SDL_events.c:76
IPaddress::host
Uint32 host
Definition: SDL_net.h:91
main
int main(int argc, char **argv)
Definition: bootstrap.cpp:102
socketset
static SDLNet_SocketSet socketset
Definition: chatd.c:38
SDLNet_SocketReady
#define SDLNet_SocketReady(sock)
Definition: SDL_net.h:347
NULL
#define NULL
Definition: ftobjs.h:61
n
GLclampd n
Definition: glew.h:7287
SDLNet_FreeSocketSet
DECLSPEC void SDLCALL SDLNet_FreeSocketSet(SDLNet_SocketSet set)
Definition: SDLnetselect.c:156
IPaddress
Definition: SDL_net.h:90
SDLNet_Init
DECLSPEC int SDLCALL SDLNet_Init(void)
Definition: SDLnet.c:86
CHAT_ADD_SLOT
#define CHAT_ADD_SLOT
Definition: chat.h:41
CHAT_ADD_NLEN
#define CHAT_ADD_NLEN
Definition: chat.h:44
CHAT_DEL_LEN
#define CHAT_DEL_LEN
Definition: chat.h:48
chat.h
name
EGLImageKHR EGLint * name
Definition: eglext.h:284
CHAT_BYE
#define CHAT_BYE
Definition: chat.h:49
people
static struct @98 people[CHAT_MAXPEOPLE]
SDL_Quit
DECLSPEC void SDLCALL SDL_Quit(void)
Definition: SDL.c:342
SDL_GetError
DECLSPEC const char *SDLCALL SDL_GetError(void)
Definition: SDL_error.c:204
SDLNet_TCP_Accept
DECLSPEC TCPsocket SDLCALL SDLNet_TCP_Accept(TCPsocket server)
Definition: SDLnetTCP.c:166
CHAT_ADD_HOST
#define CHAT_ADD_HOST
Definition: chat.h:42
SDLNet_TCP_GetPeerAddress
DECLSPEC IPaddress *SDLCALL SDLNet_TCP_GetPeerAddress(TCPsocket sock)
Definition: SDLnetTCP.c:223
SendNew
void SendNew(int about, int to)
Definition: chatd.c:101
CHAT_DEL_SLOT
#define CHAT_DEL_SLOT
Definition: chat.h:47
CHAT_DEL
#define CHAT_DEL
Definition: chat.h:46
SDLNet_TCP_AddSocket
static __inline__ int SDLNet_TCP_AddSocket(SDLNet_SocketSet set, TCPsocket sock)
Definition: SDL_net.h:313
CHAT_HELLO_NAME
#define CHAT_HELLO_NAME
Definition: chat.h:39
CHAT_ADD_PORT
#define CHAT_ADD_PORT
Definition: chat.h:43
SDLNet_SocketSet
struct _SDLNet_SocketSet * SDLNet_SocketSet
Definition: SDL_net.h:298
HandleServer
void HandleServer(void)
Definition: chat.cpp:242
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
peer
IPaddress peer
Definition: chatd.c:42
SDLNet_TCP_Open
DECLSPEC TCPsocket SDLCALL SDLNet_TCP_Open(IPaddress *ip)
Definition: SDLnetTCP.c:46
CHAT_ADD
#define CHAT_ADD
Definition: chat.h:40
CHAT_HELLO
#define CHAT_HELLO
Definition: chat.h:36
IPaddress::port
Uint16 port
Definition: SDL_net.h:92
SDLNet_Quit
DECLSPEC void SDLCALL SDLNet_Quit(void)
Definition: SDLnet.c:110
cleanup
void cleanup(int exitcode)
Definition: chat.cpp:339
SDLNet_ResolveHost
DECLSPEC int SDLCALL SDLNet_ResolveHost(IPaddress *address, const char *host, Uint16 port)
Definition: SDLnet.c:138
CHAT_HELLO_PORT
#define CHAT_HELLO_PORT
Definition: chat.h:37
TCPsocket
struct _TCPsocket * TCPsocket
Definition: SDL_net.h:131
memcpy
#define memcpy
Definition: SDL_malloc.c:634
sock
TCPsocket sock
Definition: chatd.c:41
Uint8
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
SDLNet_TCP_DelSocket
static __inline__ int SDLNet_TCP_DelSocket(SDLNet_SocketSet set, TCPsocket sock)
Definition: SDL_net.h:325
String.h
CHAT_MAXPEOPLE
#define CHAT_MAXPEOPLE
Definition: chat.h:53
SDL_Init
DECLSPEC int SDLCALL SDL_Init(Uint32 flags)
Definition: SDL.c:235
SDLNet_AllocSocketSet
DECLSPEC SDLNet_SocketSet SDLCALL SDLNet_AllocSocketSet(int maxsockets)
Definition: SDLnetselect.c:44
SDLNet_TCP_Recv
DECLSPEC int SDLCALL SDLNet_TCP_Recv(TCPsocket sock, void *data, int maxlen)
Definition: SDLnetTCP.c:269
servsock
static TCPsocket servsock
Definition: chatd.c:37
i
int i
Definition: pngrutil.c:1377
CHAT_PORT
#define CHAT_PORT
Definition: chat.h:33
SDLNet_TCP_Close
DECLSPEC void SDLCALL SDLNet_TCP_Close(TCPsocket sock)
Definition: SDLnetTCP.c:289
CHAT_ADD_NAME
#define CHAT_ADD_NAME
Definition: chat.h:45
SDLNet_GetError
DECLSPEC const char *SDLCALL SDLNet_GetError(void)
Definition: SDLnet.c:76
HandleClient
void HandleClient(void)
Definition: chat.cpp:270