|
9 | 9 | including commercial applications, and to alter it and redistribute it |
10 | 10 | freely. |
11 | 11 | */ |
12 | | -#define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ |
| 12 | + |
| 13 | +/* this creates a stream socket server, waits for connections, then |
| 14 | + echoes back anything they send. Connect to the server with telnet |
| 15 | + or netcat on port 7241 and type things! */ |
| 16 | + |
13 | 17 | #include <SDL3/SDL.h> |
14 | 18 | #include <SDL3/SDL_main.h> |
15 | 19 | #include <SDL3_net/SDL_net.h> |
16 | 20 |
|
17 | | -static SDL_Window *window = NULL; |
18 | | -static SDL_Renderer *renderer = NULL; |
19 | | - |
20 | | -/* This function runs once at startup. */ |
21 | | -SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) |
| 21 | +int main(int argc, char **argv) |
22 | 22 | { |
23 | | - /* Create the window */ |
24 | | - if (!SDL_CreateWindowAndRenderer("Hello World", 800, 600, SDL_WINDOW_FULLSCREEN, &window, &renderer)) { |
25 | | - SDL_Log("Couldn't create window and renderer: %s\n", SDL_GetError()); |
26 | | - return SDL_APP_FAILURE; |
| 23 | + const int SERVER_PORT = 7241; |
| 24 | + |
| 25 | + if (!NET_Init()) { |
| 26 | + SDL_Log("NET_Init failed: %s\n", SDL_GetError()); |
| 27 | + SDL_Quit(); |
| 28 | + return 1; |
27 | 29 | } |
28 | 30 |
|
29 | | - return SDL_APP_CONTINUE; |
30 | | -} |
| 31 | + NET_Server *server = NET_CreateServer(NULL, SERVER_PORT, 0); |
| 32 | + if (!server) { |
| 33 | + SDL_Log("Failed to create server: %s", SDL_GetError()); |
| 34 | + } else { |
| 35 | + SDL_Log("Server is ready! Connect to port %d and send text!", (int) SERVER_PORT); |
| 36 | + int num_vsockets = 1; |
| 37 | + void *vsockets[128]; |
| 38 | + SDL_zeroa(vsockets); |
| 39 | + vsockets[0] = server; |
| 40 | + while (NET_WaitUntilInputAvailable(vsockets, num_vsockets, -1) >= 0) { |
| 41 | + NET_StreamSocket *streamsocket = NULL; |
| 42 | + if (!NET_AcceptClient(server, &streamsocket)) { |
| 43 | + SDL_Log("NET_AcceptClient failed: %s", SDL_GetError()); |
| 44 | + break; |
| 45 | + } else if (streamsocket) { // new connection! |
| 46 | + SDL_Log("New connection from %s!", NET_GetAddressString(NET_GetStreamSocketAddress(streamsocket))); |
| 47 | + if (num_vsockets >= (int) (SDL_arraysize(vsockets) - 1)) { |
| 48 | + SDL_Log(" (too many connections, though, so dropping immediately.)"); |
| 49 | + NET_DestroyStreamSocket(streamsocket); |
| 50 | + } else { |
| 51 | + vsockets[num_vsockets++] = streamsocket; |
| 52 | + } |
| 53 | + } |
31 | 54 |
|
32 | | -/* This function runs when a new event (mouse input, keypresses, etc) occurs. */ |
33 | | -SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) |
34 | | -{ |
35 | | - if (event->type == SDL_EVENT_KEY_DOWN || |
36 | | - event->type == SDL_EVENT_QUIT) { |
37 | | - return SDL_APP_SUCCESS; /* end the program, reporting success to the OS. */ |
| 55 | + // see if anything has new stuff. |
| 56 | + char buffer[1024]; |
| 57 | + for (int i = 1; i < num_vsockets; i++) { |
| 58 | + bool kill_socket = false; |
| 59 | + streamsocket = (NET_StreamSocket *) vsockets[i]; |
| 60 | + const int br = NET_ReadFromStreamSocket(streamsocket, buffer, sizeof (buffer)); |
| 61 | + if (br < 0) { // uhoh, socket failed! |
| 62 | + kill_socket = true; |
| 63 | + } else if (br > 0) { |
| 64 | + const char *addrstr = NET_GetAddressString(NET_GetStreamSocketAddress(streamsocket)); |
| 65 | + SDL_Log("Got %d more bytes from '%s'", br, addrstr); |
| 66 | + if (!NET_WriteToStreamSocket(streamsocket, buffer, br)) { |
| 67 | + SDL_Log("Failed to echo data back to '%s': %s", addrstr, SDL_GetError()); |
| 68 | + kill_socket = true; |
| 69 | + } |
| 70 | + } |
| 71 | + |
| 72 | + if (kill_socket) { |
| 73 | + SDL_Log("Dropping connection to '%s'", NET_GetAddressString(NET_GetStreamSocketAddress(streamsocket))); |
| 74 | + NET_DestroyStreamSocket(streamsocket); |
| 75 | + vsockets[i] = NULL; |
| 76 | + if (i < (num_vsockets - 1)) { |
| 77 | + SDL_memmove(&vsockets[i], &vsockets[i+1], sizeof (vsockets[0]) * ((num_vsockets - i) - 1)); |
| 78 | + } |
| 79 | + num_vsockets--; |
| 80 | + i--; |
| 81 | + } |
| 82 | + } |
| 83 | + } |
| 84 | + |
| 85 | + SDL_Log("Destroying server..."); |
| 86 | + NET_DestroyServer(server); |
38 | 87 | } |
39 | | - return SDL_APP_CONTINUE; |
40 | | -} |
41 | 88 |
|
42 | | -/* This function runs once per frame, and is the heart of the program. */ |
43 | | -SDL_AppResult SDL_AppIterate(void *appstate) |
44 | | -{ |
45 | | - return SDL_APP_CONTINUE; |
| 89 | + SDL_Log("Shutting down..."); |
| 90 | + NET_Quit(); |
| 91 | + SDL_Quit(); |
| 92 | + return 0; |
46 | 93 | } |
47 | 94 |
|
48 | | -/* This function runs once at shutdown. */ |
49 | | -void SDL_AppQuit(void *appstate, SDL_AppResult result) |
50 | | -{ |
51 | | -} |
|
0 commit comments