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 }