1 /*******************************************************************************************
2 *
3 *   raylib [network] example - TCP Server
4 *
5 *   This example has been created using raylib 3.0 (www.raylib.com)
6 *   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
7 *
8 *   Copyright (c) 2019-2020 Jak Barnes (@syphonx) and Ramon Santamaria (@raysan5)
9 *
10 ********************************************************************************************/
11 
12 #include "raylib.h"
13 
14 #define RNET_IMPLEMENTATION
15 #include "rnet.h"
16 
main(void)17 int main(void)
18 {
19     // Initialization
20     //--------------------------------------------------------------------------------------
21     const int screenWidth = 800;
22     const int screenHeight = 450;
23 
24     InitWindow(screenWidth, screenHeight, "raylib [network] example - tcp server");
25 
26     InitNetworkDevice();    // Init network communications
27 
28     const char *pingmsg = "Ping!";
29     const char *pongmsg = "Pong!";
30 
31     bool ping = false;
32     bool pong = false;
33     float elapsed = 0.0f;
34     float delay = 1.0f;
35     bool connected = false;
36 
37     SocketConfig serverConfig = {
38         .host = "127.0.0.1",
39         .port = "4950",
40         .type = SOCKET_TCP,
41         .server = true,
42         .nonblocking = true
43     };
44 
45     SocketConfig connectionConfig = { .nonblocking = true };
46 
47     Socket *connection = NULL;
48     SocketSet *socketSet = NULL;
49     SocketResult *serverResult = NULL;
50     char receiveBuffer[512] = { 0 };
51 
52     //  Create the server: getaddrinfo + socket + setsockopt + bind + listen
53     serverResult = LoadSocketResult();
54     if (!SocketCreate(&serverConfig, serverResult))
55     {
56         TraceLog(LOG_WARNING, "Failed to open server: status %d, errno %d", serverResult->status, serverResult->socket->status);
57     }
58     else
59     {
60         if (!SocketBind(&serverConfig, serverResult))
61         {
62             TraceLog(LOG_WARNING, "Failed to bind server: status %d, errno %d", serverResult->status, serverResult->socket->status);
63         }
64         else
65         {
66             if (!(serverConfig.type == SOCKET_UDP))
67             {
68                 if (!SocketListen(&serverConfig, serverResult)) TraceLog(LOG_WARNING, "Failed to start listen server: status %d, errno %d", serverResult->status, serverResult->socket->status);
69             }
70         }
71     }
72 
73     // Create and add sockets to the socket set
74     socketSet = LoadSocketSet(2);
75     AddSocket(socketSet, serverResult->socket);
76 
77     SetTargetFPS(60);               // Set our game to run at 60 frames-per-second
78     //--------------------------------------------------------------------------------------
79 
80     // Main game loop
81     while (!WindowShouldClose())    // Detect window close button or ESC key
82     {
83         // Update
84         //----------------------------------------------------------------------------------
85         if (connected)
86         {
87             // Once connected to the network, check the sockets for pending information
88             // and when information is ready, send either a Ping or a Pong.
89 
90             // CheckSockets, if any of the sockets in the socketSet are pending (received data, or requests)
91             // then mark the socket as being ready. You can check this with IsSocketReady(client_res->socket)
92             int active = CheckSockets(socketSet, 0);
93             if (active != 0) TraceLog(LOG_DEBUG, "There are currently %d socket(s) with data to be processed.", active);
94 
95             // IsSocketReady, if the socket is ready, attempt to receive data from the socket
96             int bytesRecv = 0;
97             if (IsSocketReady(connection)) bytesRecv = SocketReceive(connection, receiveBuffer, (int)strlen(pingmsg) + 1);
98 
99             // If we received data, was that data a "Ping!" or a "Pong!"
100             if (bytesRecv > 0)
101             {
102                 if (strcmp(receiveBuffer, pingmsg) == 0) { pong = true; }
103                 if (strcmp(receiveBuffer, pongmsg) == 0) { ping = true; }
104             }
105 
106             // After each delay has expired, send a response "Ping!" for a "Pong!" and vice versa
107             elapsed += GetFrameTime();
108             if (elapsed > delay)
109             {
110                 if (ping)
111                 {
112                     ping = false;
113                     SocketSend(connection, pingmsg, (int)strlen(pingmsg) + 1);
114                 }
115                 else if (pong)
116                 {
117                     pong = false;
118                     SocketSend(connection, pongmsg, (int)strlen(pingmsg) + 1);
119                 }
120 
121                 elapsed = 0.0f;
122             }
123         }
124         else
125         {
126             // Attempt to connect to the network (Either TCP, or UDP)
127             int active = CheckSockets(socketSet, 0);
128             if (active != 0) TraceLog(LOG_DEBUG, "There are currently %d socket(s) with data to be processed.", active);
129 
130             if (active > 0)
131             {
132                 if ((connection = SocketAccept(serverResult->socket, &connectionConfig)) != NULL)
133                 {
134                     AddSocket(socketSet, connection);
135                     connected = true;
136                     ping = true;
137                 }
138             }
139         }
140         //----------------------------------------------------------------------------------
141 
142         // Draw
143         //----------------------------------------------------------------------------------
144         BeginDrawing();
145 
146             ClearBackground(RAYWHITE);
147 
148             // TODO: Draw relevant connection info
149 
150         EndDrawing();
151         //----------------------------------------------------------------------------------
152     }
153 
154     // De-Initialization
155     //--------------------------------------------------------------------------------------
156     CloseNetworkDevice();   // Close network communication
157 
158     CloseWindow();          // Close window and OpenGL context
159     //--------------------------------------------------------------------------------------
160 
161     return 0;
162 }