more example stubs

more changes to rnet
i'm tired, it's 2am why am i doing this
This commit is contained in:
Jak Barnes 2019-02-24 01:59:09 +00:00
parent bde0b6cd75
commit ee85f59643
14 changed files with 1782 additions and 431 deletions

View File

@ -25,7 +25,7 @@
int main() int main()
{ {
// Setup // Setup
int screenWidth = 800; int screenWidth = 800;
int screenHeight = 450; int screenHeight = 450;
InitWindow( InitWindow(
screenWidth, screenHeight, "raylib [network] example - ping pong"); screenWidth, screenHeight, "raylib [network] example - ping pong");
@ -38,23 +38,26 @@ int main()
// Create the server // Create the server
SocketConfig server_cfg = { SocketConfig server_cfg = {
.host = "127.0.0.1", .host = "127.0.0.1",
.port = 8080, .port = "8080",
.server = true, .server = true,
.nonblocking = true, .nonblocking = true
}; };
SocketResult server_res; SocketResult server_res;
memset(&server_res, 0, sizeof(SocketResult)); memset(&server_res, 0, sizeof(SocketResult));
{ {
bool ok = SocketOpen(&server_cfg, &server_res); bool ok = SocketOpen(&server_cfg, &server_res);
if (!ok) { return false; } if (!ok)
{
return false;
}
} }
// Create the client // Create the client
SocketConfig client_cfg = { SocketConfig client_cfg = {
.host = "127.0.0.1", .host = "127.0.0.1",
.port = 8080, .port = "8080"
}; };
SocketResult client_res; SocketResult client_res;
@ -63,8 +66,8 @@ int main()
bool ok = SocketOpen(&client_cfg, &client_res); bool ok = SocketOpen(&client_cfg, &client_res);
if (!ok) if (!ok)
{ {
printf("failed to open: status %d, errno %d\n", printf("failed to open: status %d, errno %d\n", client_res.status,
client_res.status, client_res.saved_errno); client_res.socket.error);
return false; return false;
} }
} }
@ -76,6 +79,8 @@ int main()
char recvBuffer[512]; char recvBuffer[512];
bool connected = false; bool connected = false;
memset(&recvBuffer, 0, 8); memset(&recvBuffer, 0, 8);
char pingmsg[6] = "Ping!";
char pongmsg[6] = "Pong!";
// Main game loop // Main game loop
while (!WindowShouldClose()) while (!WindowShouldClose())
@ -91,7 +96,7 @@ int main()
{ {
if (SocketAccept(server_res.socket.handle, &connection)) if (SocketAccept(server_res.socket.handle, &connection))
{ {
ping = true; ping = true;
connected = true; connected = true;
} }
} }
@ -99,18 +104,18 @@ int main()
// Connected // Connected
if (connected) if (connected)
{ {
int bytesRecv = SocketReceive(&connection.socket, recvBuffer, 5); int bytesRecv = SocketReceive(&connection.socket, recvBuffer, sizeof(pingmsg));
if (bytesRecv > 0) if (bytesRecv > 0)
{ {
if (strcmp(recvBuffer, "Ping!") == 0) if (strcmp(recvBuffer, pingmsg) == 0)
{ {
pong = true; pong = true;
printf("Ping!\n"); printf("%s\n", pingmsg);
} }
if (strcmp(recvBuffer, "Pong!") == 0) if (strcmp(recvBuffer, pongmsg) == 0)
{ {
ping = true; ping = true;
printf("Pong!\n"); printf("%s\n", pongmsg);
} }
} }
@ -120,12 +125,12 @@ int main()
if (ping) if (ping)
{ {
ping = false; ping = false;
SocketSend(&client_res.socket, "Ping!", 5); SocketSend(&client_res.socket, pingmsg, sizeof(pingmsg));
} }
else if (pong) else if (pong)
{ {
pong = false; pong = false;
SocketSend(&client_res.socket, "Pong!", 5); SocketSend(&client_res.socket, pongmsg, sizeof(pongmsg));
} }
elapsed = 0.0f; elapsed = 0.0f;
} }

View File

@ -38,8 +38,8 @@ int main()
AddressInformation addr; AddressInformation addr;
ResolveHost("www.google.com", "80", &addr); ResolveHost("www.google.com", "80", &addr);
// ResolveIP("8.8.8.8", NULL, NAME_INFO_DEFAULT); ResolveIP("8.8.8.8", NULL, NAME_INFO_DEFAULT);
// ResolveIP("2001:4860:4860::8888", "80", NAME_INFO_NUMERICSERV); ResolveIP("2001:4860:4860::8888", "80", NAME_INFO_NUMERICSERV);
// Main game loop // Main game loop
while (!WindowShouldClose()) while (!WindowShouldClose())

View File

@ -0,0 +1,93 @@
/*******************************************************************************************
*
* raylib [network] example - Resolve host
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This example has been created using raylib 2.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h
*for details)
*
* Copyright (c) 2013-2016 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include <string.h>
#define PORT "3490" // the port client will be connecting to
#define MAXDATASIZE 100 // max number of bytes we can get at once
int main()
{
// Setup
int screenWidth = 800;
int screenHeight = 450;
InitWindow(
screenWidth, screenHeight, "raylib [network] example - ping pong");
SetTargetFPS(60);
SetTraceLogLevel(LOG_DEBUG);
// Networking
InitNetwork();
int numbytes;
char buf[MAXDATASIZE];
// Create the client
SocketConfig client_cfg = {
.host = "127.0.0.1",
.port = "8080"
};
SocketResult client_res;
memset(&client_res, 0, sizeof(SocketResult));
{
bool ok = SocketOpen(&client_cfg, &client_res);
if (!ok)
{
printf("Failed to open: status %d, errno %d\n", client_res.status,
client_res.socket.error);
return false;
}
}
// Main game loop
while (!WindowShouldClose())
{
// Draw
BeginDrawing();
// Clear
ClearBackground(RAYWHITE);
// Receive bytes from the server
numbytes = SocketReceive(client_res.socket.handle, buf, MAXDATASIZE - 1);
if (numbytes == -1)
{
printf("Client: error recv '%s'\n", buf);
break;
}
buf[numbytes] = '\0';
printf("Client: received '%s'\n", buf);
break;
// End draw
EndDrawing();
}
// Cleanup
SocketClose(client_res.socket.handle);
CloseNetwork();
CloseWindow();
return 0;
}

View File

@ -0,0 +1,100 @@
/*******************************************************************************************
*
* raylib [network] example - Resolve host
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This example has been created using raylib 2.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h
*for details)
*
* Copyright (c) 2013-2016 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include <string.h>
int main()
{
// Setup
int screenWidth = 800;
int screenHeight = 450;
InitWindow(
screenWidth, screenHeight, "raylib [network] example - ping pong");
SetTargetFPS(60);
SetTraceLogLevel(LOG_DEBUG);
// Networking
InitNetwork();
// Create the server
SocketConfig server_cfg = {
.host = "127.0.0.1",
.port = "8080",
.server = true,
.nonblocking = true
};
SocketResult server_res;
memset(&server_res, 0, sizeof(SocketResult));
{
bool ok = SocketOpen(&server_cfg, &server_res);
if (!ok)
{
return false;
}
}
SocketResult connection;
memset(&connection, 0, sizeof(SocketResult));
char recvBuffer[512];
memset(&recvBuffer, 0, 8);
bool connected = false;
// Main game loop
while (!WindowShouldClose())
{
// Draw
BeginDrawing();
// Clear
ClearBackground(RAYWHITE);
// Wait for a valid connection
if (!connected)
{
if (SocketAccept(server_res.socket.handle, &connection))
{
connected = true;
}
}
if (connected)
{
SocketSend(&connection, "Hello, world!", 13);
}
// End draw
EndDrawing();
}
// Cleanup
CloseWindow();
return 0;
}

View File

@ -0,0 +1,74 @@
/*******************************************************************************************
*
* raylib [network] example - Resolve host
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This example has been created using raylib 2.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h
*for details)
*
* Copyright (c) 2013-2016 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include <string.h>
int main()
{
// Setup
int screenWidth = 800;
int screenHeight = 450;
InitWindow(
screenWidth, screenHeight, "raylib [network] example - ping pong");
SetTargetFPS(60);
SetTraceLogLevel(LOG_DEBUG);
// Networking
InitNetwork();
unsigned char buf[1024];
unsigned char magic;
int monkeycount;
long altitude;
double absurdityfactor;
char* s = "Great unmitigated Zot! You've found the Runestaff!";
char s2[96];
unsigned int packetsize, ps2;
packetsize = PackData(buf, "CHhlsd", 'B', 0, 37, -5, s, -3490.5);
packi16(buf + 1, packetsize); // store packet size in packet for kicks
printf("packet is %u bytes\n", packetsize);
UnpackData(buf, "CHhl96sd", &magic, &ps2, &monkeycount, &altitude, s2, &absurdityfactor);
printf("'%c' %hhu %u %ld \"%s\" %f\n", magic, ps2, monkeycount, altitude, s2, absurdityfactor);
// Main game loop
while (!WindowShouldClose())
{
// Draw
BeginDrawing();
// Clear
ClearBackground(RAYWHITE);
// End draw
EndDrawing();
}
// Cleanup
CloseWindow();
return 0;
}

View File

@ -0,0 +1,74 @@
/*******************************************************************************************
*
* raylib [network] example - Resolve host
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This example has been created using raylib 2.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h
*for details)
*
* Copyright (c) 2013-2016 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include <string.h>
int main()
{
// Setup
int screenWidth = 800;
int screenHeight = 450;
InitWindow(
screenWidth, screenHeight, "raylib [network] example - ping pong");
SetTargetFPS(60);
SetTraceLogLevel(LOG_DEBUG);
// Networking
InitNetwork();
unsigned char buf[1024];
unsigned char magic;
int monkeycount;
long altitude;
double absurdityfactor;
char* s = "Great unmitigated Zot! You've found the Runestaff!";
char s2[96];
unsigned int packetsize, ps2;
packetsize = PackData(buf, "CHhlsd", 'B', 0, 37, -5, s, -3490.5);
packi16(buf + 1, packetsize); // store packet size in packet for kicks
printf("packet is %u bytes\n", packetsize);
UnpackData(buf, "CHhl96sd", &magic, &ps2, &monkeycount, &altitude, s2, &absurdityfactor);
printf("'%c' %hhu %u %ld \"%s\" %f\n", magic, ps2, monkeycount, altitude, s2, absurdityfactor);
// Main game loop
while (!WindowShouldClose())
{
// Draw
BeginDrawing();
// Clear
ClearBackground(RAYWHITE);
// End draw
EndDrawing();
}
// Cleanup
CloseWindow();
return 0;
}

View File

@ -0,0 +1,173 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\raylib\raylib.vcxproj">
<Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\examples\network\network_tcp_client.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>network_tcp_client</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
<ProjectName>network_tcp_client</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)$(ProjectName)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)$(ProjectName)\$(Configuration)\temp</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,173 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\raylib\raylib.vcxproj">
<Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\examples\network\network_tcp_server.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>network_tcp_server</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
<ProjectName>network_tcp_server</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)$(ProjectName)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)$(ProjectName)\$(Configuration)\temp</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,173 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\raylib\raylib.vcxproj">
<Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\examples\network\network_udp_client.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>network_udp_client</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
<ProjectName>network_udp_client</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)$(ProjectName)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)$(ProjectName)\$(Configuration)\temp</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,173 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\raylib\raylib.vcxproj">
<Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\examples\network\network_udp_server.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>network_udp_server</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
<ProjectName>network_udp_server</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)$(ProjectName)\$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)$(ProjectName)\$(Configuration)\temp</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<DisableLanguageExtensions>false</DisableLanguageExtensions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -17,9 +17,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "network_chat_server", "exam
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "network_ping_pong", "examples\network_ping_pong.vcxproj", "{56EB485C-00A9-459E-B758-2E86316EB7FD}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "network_ping_pong", "examples\network_ping_pong.vcxproj", "{56EB485C-00A9-459E-B758-2E86316EB7FD}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "network_serialisation", "examples\network_resolve_host.vcxproj", "{A16D19CB-6AF4-4D17-8318-EABD8805247C}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "network_resolve_host", "examples\network_resolve_host.vcxproj", "{A16D19CB-6AF4-4D17-8318-EABD8805247C}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "network_resolve_host", "examples\network_serialisation.vcxproj", "{46B18968-56BC-4FB1-A7C0-FA418E095AFD}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "network_serialisation", "examples\network_serialisation.vcxproj", "{46B18968-56BC-4FB1-A7C0-FA418E095AFD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "network_tcp_client", "examples\network_tcp_client.vcxproj", "{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "network_tcp_server", "examples\network_tcp_server.vcxproj", "{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "network_udp_client", "examples\network_udp_client.vcxproj", "{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "network_udp_server", "examples\network_udp_server.vcxproj", "{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -149,6 +157,70 @@ Global
{46B18968-56BC-4FB1-A7C0-FA418E095AFD}.Release|x64.Build.0 = Release|x64 {46B18968-56BC-4FB1-A7C0-FA418E095AFD}.Release|x64.Build.0 = Release|x64
{46B18968-56BC-4FB1-A7C0-FA418E095AFD}.Release|x86.ActiveCfg = Release|Win32 {46B18968-56BC-4FB1-A7C0-FA418E095AFD}.Release|x86.ActiveCfg = Release|Win32
{46B18968-56BC-4FB1-A7C0-FA418E095AFD}.Release|x86.Build.0 = Release|Win32 {46B18968-56BC-4FB1-A7C0-FA418E095AFD}.Release|x86.Build.0 = Release|Win32
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Debug.DLL|x64.ActiveCfg = Debug|x64
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Debug.DLL|x64.Build.0 = Debug|x64
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Debug.DLL|x86.ActiveCfg = Debug|Win32
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Debug.DLL|x86.Build.0 = Debug|Win32
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Debug|x64.ActiveCfg = Debug|x64
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Debug|x64.Build.0 = Debug|x64
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Debug|x86.ActiveCfg = Debug|Win32
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Debug|x86.Build.0 = Debug|Win32
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Release.DLL|x64.ActiveCfg = Release|x64
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Release.DLL|x64.Build.0 = Release|x64
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Release.DLL|x86.ActiveCfg = Release|Win32
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Release.DLL|x86.Build.0 = Release|Win32
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Release|x64.ActiveCfg = Release|x64
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Release|x64.Build.0 = Release|x64
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Release|x86.ActiveCfg = Release|Win32
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5}.Release|x86.Build.0 = Release|Win32
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Debug.DLL|x64.ActiveCfg = Debug|x64
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Debug.DLL|x64.Build.0 = Debug|x64
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Debug.DLL|x86.ActiveCfg = Debug|Win32
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Debug.DLL|x86.Build.0 = Debug|Win32
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Debug|x64.ActiveCfg = Debug|x64
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Debug|x64.Build.0 = Debug|x64
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Debug|x86.ActiveCfg = Debug|Win32
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Debug|x86.Build.0 = Debug|Win32
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Release.DLL|x64.ActiveCfg = Release|x64
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Release.DLL|x64.Build.0 = Release|x64
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Release.DLL|x86.ActiveCfg = Release|Win32
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Release.DLL|x86.Build.0 = Release|Win32
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Release|x64.ActiveCfg = Release|x64
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Release|x64.Build.0 = Release|x64
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Release|x86.ActiveCfg = Release|Win32
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131}.Release|x86.Build.0 = Release|Win32
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Debug.DLL|x64.ActiveCfg = Debug|x64
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Debug.DLL|x64.Build.0 = Debug|x64
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Debug.DLL|x86.ActiveCfg = Debug|Win32
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Debug.DLL|x86.Build.0 = Debug|Win32
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Debug|x64.ActiveCfg = Debug|x64
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Debug|x64.Build.0 = Debug|x64
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Debug|x86.ActiveCfg = Debug|Win32
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Debug|x86.Build.0 = Debug|Win32
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Release.DLL|x64.ActiveCfg = Release|x64
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Release.DLL|x64.Build.0 = Release|x64
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Release.DLL|x86.ActiveCfg = Release|Win32
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Release.DLL|x86.Build.0 = Release|Win32
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Release|x64.ActiveCfg = Release|x64
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Release|x64.Build.0 = Release|x64
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Release|x86.ActiveCfg = Release|Win32
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D}.Release|x86.Build.0 = Release|Win32
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Debug.DLL|x64.ActiveCfg = Debug|x64
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Debug.DLL|x64.Build.0 = Debug|x64
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Debug.DLL|x86.ActiveCfg = Debug|Win32
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Debug.DLL|x86.Build.0 = Debug|Win32
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Debug|x64.ActiveCfg = Debug|x64
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Debug|x64.Build.0 = Debug|x64
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Debug|x86.ActiveCfg = Debug|Win32
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Debug|x86.Build.0 = Debug|Win32
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Release.DLL|x64.ActiveCfg = Release|x64
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Release.DLL|x64.Build.0 = Release|x64
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Release.DLL|x86.ActiveCfg = Release|Win32
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Release.DLL|x86.Build.0 = Release|Win32
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Release|x64.ActiveCfg = Release|x64
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Release|x64.Build.0 = Release|x64
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Release|x86.ActiveCfg = Release|Win32
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A}.Release|x86.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -161,6 +233,10 @@ Global
{56EB485C-00A9-459E-B758-2E86316EB7FD} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} {56EB485C-00A9-459E-B758-2E86316EB7FD} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}
{A16D19CB-6AF4-4D17-8318-EABD8805247C} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} {A16D19CB-6AF4-4D17-8318-EABD8805247C} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}
{46B18968-56BC-4FB1-A7C0-FA418E095AFD} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1} {46B18968-56BC-4FB1-A7C0-FA418E095AFD} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}
{3415FF09-CF64-451E-AC03-F2A30EC2AFD5} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}
{B7AA867E-AA24-4CD6-A61E-5A0B9A068131} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}
{0207D9BA-25E0-44A0-9B54-952FFDA3D58D} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}
{C8C754B7-E53D-4D7D-A3F7-F52F5B55FA2A} = {8716DC0F-4FDE-4F57-8E25-5F78DFB80FE1}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29}

View File

@ -168,7 +168,7 @@
#endif #endif
// Network typedefs // Network typedefs
typedef int SocketHandle; typedef unsigned int SocketHandle;
// Vector2 type // Vector2 type
typedef struct Vector2 { typedef struct Vector2 {
@ -440,7 +440,7 @@ typedef struct VrStereoConfig {
typedef struct IPAddress typedef struct IPAddress
{ {
unsigned char* host; /* 32-bit IPv4 host address */ unsigned char* host; /* 32-bit IPv4 host address */
unsigned char* port; /* 16-bit protocol port */ unsigned int port; /* 16-bit protocol port */
} IPAddress; } IPAddress;
// Used by the getaddrinfo function to hold host address information. // Used by the getaddrinfo function to hold host address information.
@ -456,8 +456,6 @@ typedef struct AddressInformation
struct AddressInformation *next; // Next structure in linked list struct AddressInformation *next; // Next structure in linked list
} AddressInformation; } AddressInformation;
// Used
//
// The sockaddr structure varies depending on the protocol selected. // The sockaddr structure varies depending on the protocol selected.
// Except for the sin*_family parameter, sockaddr contents are expressed // Except for the sin*_family parameter, sockaddr contents are expressed
// in network byte order. // in network byte order.
@ -474,96 +472,56 @@ typedef struct SocketOpt {
int valueLen; int valueLen;
} SocketOpt; } SocketOpt;
typedef enum
{
SOCKET_TCP = 1, // SOCK_STREAM
SOCKET_UDP = 2 // SOCK_DGRAM
} SocketType;
typedef struct Socket typedef struct Socket
{ {
int ready; // Is the socket ready? i.e. has information int ready; // Is the socket ready? i.e. has information
SocketHandle handle; // The socket handle id int error; // The last error code to have occured using this socket
IPAddress host; // The host/target ip for this socket bool isServer; // Is this socket a server socket (i.e. TCP/UDP Listen Server)
int sflag; // Is this socket a server socket (i.e. TCP/UDP Listen Server) IPAddress address; // The host/target ip for this socket
SocketType type; // Is this socket a TCP or UDP socket?
SocketHandle handle; // The socket handle id
} Socket; } Socket;
// Configuration for a socket. Not all of these fields need to // Configuration for a socket. Not all of these fields need to
// be set, and ones omitted from a C99-style "designated initializer" // be set, and ones omitted from a C99-style "designated initializer"
// struct literal will be zeroed out and replaced with defaults. // struct literal will be zeroed out and replaced with defaults.
typedef struct SocketConfig { typedef struct SocketConfig
/* Hostname and port, for TCP or UDP sockets. */ {
char *host; // Hostname and port, for TCP or UDP sockets. */
int port; char *host;
char *port;
/* Path, for Unix domain socket. */ // IPv4 or IPv6 address; if neither is specified, let OS decide.
char *path; // These fields should be used in place of 'host' above.
char *IPv4;
char *IPv6;
bool server; // Listen for incoming clients?
bool datagram; // TCP or UDP?
bool nonblocking; // non-blocking operation?
int backlog_size; // set a custom backlog size
/* IPv4 or IPv6 address; if neither is specified, let OS decide. SocketOpt sockopts[MAX_SOCK_OPTS];
* These fields should be used in place of 'host' above. */
char *IPv4;
char *IPv6;
bool server; /* Listen for incoming clients? */
bool datagram; /* UDP or datagram? */
bool nonblocking; /* non-blocking operation? */
int backlog_size; /* set a custom backlog size */
SocketOpt sockopts[MAX_SOCK_OPTS];
} SocketConfig; } SocketConfig;
enum SocketStatus { // Result from calling open with a given config.
typedef struct SocketResult
/* Socket created. */ {
SOCKET_OK = 0, int status;
Socket socket;
/* Failures from socket API functions; most also save errno. */
SOCKET_ERROR_GETADDRINFO = -1,
SOCKET_ERROR_SOCKET = -2,
SOCKET_ERROR_BIND = -3,
SOCKET_ERROR_LISTEN = -4,
SOCKET_ERROR_CONNECT = -5,
SOCKET_ERROR_FCNTL = -6,
SOCKET_ERROR_ACCEPT = -7,
SOCKET_ERROR_SEND = -8,
/* Failure from snprintf: name too long. */
SOCKET_ERROR_SNPRINTF = -100,
/* Invalid combination of options in configuration. */
SOCKET_ERROR_CONFIGURATION = -200,
/* Error in setsockopt(2). */
SOCKET_ERROR_SETSOCKOPT = -300,
/* Other unknown error. */
SOCKET_ERROR_UNKNOWN = -400,
};
/* Result from calling open with a given config. */
typedef struct SocketResult {
/* Result code and errno value from failure (if any). */
enum SocketStatus status;
/* File descriptor, set if status is SOCKET99_OK (success). */
Socket socket;
/* Address information populated from getaddrinfo() */
AddressInformation addrinfo; AddressInformation addrinfo;
/* Error code from socket(2), bind(2), etc. */
int saved_errno;
/* Error code from getaddrinfo, only set if status is
* SOCKET99_ERROR_GETADDRINFO. See: gai_strerror(3). */
int getaddrinfo_error;
} SocketResult; } SocketResult;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Enumerators Definition // Enumerators Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
typedef enum
{
SOCKET_TCP = 1, // SOCK_STREAM
SOCKET_UDP = 2 // SOCK_DGRAM
} SocketType;
// System config flags // System config flags
// NOTE: Used for bit masks // NOTE: Used for bit masks
typedef enum { typedef enum {
@ -1530,22 +1488,17 @@ RLAPI char* ResolveIP(const char *host, const char *port, int flags);
// Protocol-independent translation from an ANSI host name to an address. // Protocol-independent translation from an ANSI host name to an address.
RLAPI char* ResolveHost(const char *address, const char *port, AddressInformation *outaddr); RLAPI char* ResolveHost(const char *address, const char *port, AddressInformation *outaddr);
// IP
RLAPI void GetLocalAddresses();
// Socket API // Socket API
RLAPI bool SocketOpen(SocketConfig *cfg, SocketResult *res); RLAPI bool SocketOpen(SocketConfig *cfg, SocketResult *res);
RLAPI void SocketClose(SocketHandle socket); RLAPI void SocketClose(SocketHandle socket);
RLAPI bool SocketAccept(SocketHandle listener, SocketResult* res); RLAPI bool SocketAccept(SocketHandle listener, SocketResult* res);
RLAPI int SocketSend(Socket* socket, const void *datap, int len); RLAPI int SocketSend(Socket* socket, const void *datap, int len);
RLAPI int SocketReceive(Socket* socket, void *data, int maxlen); RLAPI int SocketReceive(Socket* socket, void *data, int maxlen);
RLAPI int SocketGetError(char *buf, int buf_size, SocketResult *res);
RLAPI void SocketPrintError(SocketResult *res);
RLAPI void SocketSetHints(SocketConfig *cfg, AddressInformation *hints); RLAPI void SocketSetHints(SocketConfig *cfg, AddressInformation *hints);
// Utility print methods // Utility print methods
RLAPI char *SocketAddressToString(SocketAddress *sockaddr, char buffer[]); RLAPI char *SocketAddressToString(SocketAddress *sockaddr, char buffer[], int* port);
RLAPI void PrintSocket(SocketAddress *addr, const int family, const int socktype, const int protocol); RLAPI void PrintSocket(SocketAddress *addr, const int family, const int socktype, const int protocol);
// Network conversion methods // Network conversion methods

View File

@ -43,6 +43,12 @@
# include "config.h" // Defines module configuration flags # include "config.h" // Defines module configuration flags
#endif #endif
//----------------------------------------------------------------------------------
// Module defines
//----------------------------------------------------------------------------------
#define SOCKET_BACKLOG_SIZE 20
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module dependencies // Module dependencies
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -52,26 +58,58 @@
#include "sysnet.h" #include "sysnet.h"
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module defines // Module variables
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#if PLATFORM_WINDOWS //----------------------------------------------------------------------------------
# define errno WSAGetLastError() // Support UNIX socket error codes // Module methods
#endif //----------------------------------------------------------------------------------
#define DEF_BACKLOG_SIZE SOMAXCONN static bool IsSocketValid(SocketHandle handle);
#define PORT_STR_BUFSZ 6 static void SocketSetLastError(int err);
static int SocketGetLastError();
static char* SocketGetLastErrorString();
static char* SocketErrorCodeToString(int err);
static bool SocketSetDefaults(SocketConfig* config);
static bool InitSocket(Socket* outsock);
static bool CreateSocket(SocketConfig* config, SocketResult* outresult);
static int BindSocket(SocketHandle handle, SocketConfig* config, struct addrinfo* iterator);
static int ConnectSocket(SocketHandle handle, SocketConfig* config, struct addrinfo* iterator);
static bool SocketSetNonBlocking(SocketResult* out);
static bool SocketSetOptions(SocketConfig* config, SocketHandle handle);
static void* GetSocketAddressPtr(struct sockaddr* sa);
static void* GetSocketPortPtr(struct sockaddr* sa);
static bool SocketSetDefaults(SocketConfig* cfg); //
static bool CreateSocket(SocketConfig* cfg, SocketResult* out); void* GetSocketPortPtr(struct sockaddr* sa)
static bool SocketSetNonBlocking(SocketResult* out); {
static bool SocketSetOptions(SocketConfig* cfg, SocketResult* out, int fd); if (sa->sa_family == AF_INET)
static const char* SocketStatusToString(enum SocketStatus s); {
return &(((struct sockaddr_in*) sa)->sin_port);
}
/* Static network API methods */ return &(((struct sockaddr_in6*) sa)->sin6_port);
}
//
void* GetSocketAddressPtr(struct sockaddr* sa)
{
if (sa->sa_family == AF_INET)
{
return &(((struct sockaddr_in*) sa)->sin_addr);
}
return &(((struct sockaddr_in6*) sa)->sin6_addr);
}
//
static bool IsSocketValid(SocketHandle handle)
{
return (handle != INVALID_SOCKET);
}
// Sets the error code that can be retrieved through the WSAGetLastError function. // Sets the error code that can be retrieved through the WSAGetLastError function.
static void SocketSetError(int err) static void SocketSetLastError(int err)
{ {
#if PLATFORM == PLATFORM_WINDOWS #if PLATFORM == PLATFORM_WINDOWS
WSASetLastError(err); WSASetLastError(err);
@ -93,216 +131,294 @@ static int SocketGetLastError()
// Returns a human-readable string representing the last error message // Returns a human-readable string representing the last error message
static char* SocketGetLastErrorString() static char* SocketGetLastErrorString()
{ {
return gai_strerror(SocketGetLastError()); return SocketErrorCodeToString(SocketGetLastError());
} }
static bool SocketSetDefaults(SocketConfig* cfg) // Returns a human-readable string representing the error message (err)
static char* SocketErrorCodeToString(int err)
{ {
if (cfg->backlog_size == 0) #if PLATFORM == PLATFORM_WINDOWS
static char gaiStrErrorBuffer[GAI_STRERROR_BUFFER_SIZE];
sprintf(gaiStrErrorBuffer, "%ws", gai_strerror(err));
return gaiStrErrorBuffer;
#else
return gai_strerror(err);
#endif
}
//
static bool SocketSetDefaults(SocketConfig* config)
{
if (config->backlog_size == 0)
{ {
cfg->backlog_size = DEF_BACKLOG_SIZE; config->backlog_size = SOCKET_BACKLOG_SIZE;
} }
/* Screen out contradictory settings */ if (config->IPv6 && config->IPv4)
if (cfg->IPv6 && cfg->IPv4)
{ {
return false; return false;
} }
return true; return true;
} }
static bool SocketSaveError(SocketResult* out, enum SocketStatus status) // Create the socket handle
static bool InitSocket(Socket* outsock)
{ {
out->status = status; switch (outsock->type)
out->saved_errno = SocketGetLastError(); {
SocketSetError(0); case SOCKET_TCP:
return false; outsock->handle = socket(AF_INET, SOCK_STREAM, 0);
break;
case SOCKET_UDP:
outsock->handle = socket(AF_INET, SOCK_DGRAM, 0);
break;
default:
break;
}
return IsSocketValid(outsock->handle);
} }
static bool CreateSocket(SocketConfig* cfg, SocketResult* out) // CreateSocket() - Interally called by OpenSocket()
//
// This here is the bread and butter of the socket API, This function will
// attempt to open a socket, bind and listen to it based on the config passed in
//
// SocketConfig* config - Configuration for which socket to open
// SocketResult* result - The results of this function (if any, including errors)
//
// e.g.
// SocketConfig server_cfg = { SocketConfig client_cfg = {
// .host = "127.0.0.1", .host = "127.0.0.1",
// .port = 8080, .port = 8080,
// .server = true, };
// .nonblocking = true,
// };
// SocketResult server_res; SocketResult client_res;
static bool CreateSocket(SocketConfig* config, SocketResult* outresult)
{ {
struct addrinfo hints; int status; // Status value to return (0) is success
struct addrinfo* res = NULL; struct addrinfo hints; // Address flags (IPV4, IPV6, UDP?)
struct addrinfo* res; // A pointer to the resulting address list
Socket* outsocket;
outsocket = &outresult->socket;
outsocket->handle = INVALID_SOCKET;
outresult->status = RESULT_FAILURE;
int fd = -1; // Set the socket type
char port_str[PORT_STR_BUFSZ]; outresult->socket.type = (config->datagram) ? SOCKET_UDP : SOCKET_TCP;
memset(port_str, 0, PORT_STR_BUFSZ);
SocketSetHints(cfg, &hints); // Set the hints based on information in the config
//
// AI_CANONNAME Causes the ai_canonname of the result to the filled out with the host's canonical (real) name.
// AI_PASSIVE: Causes the result's IP address to be filled out with INADDR_ANY (IPv4)or in6addr_any (IPv6);
// Note: This causes a subsequent call to bind() to auto-fill the IP address
// of the struct sockaddr with the address of the current host.
//
SocketSetHints(config, &hints);
if (PORT_STR_BUFSZ < snprintf(port_str, PORT_STR_BUFSZ, "%u", cfg->port)) // Populate address information
status = getaddrinfo(config->host, // e.g. "www.example.com" or IP (Can be null if AI_PASSIVE flag is set
config->port, // e.g. "http" or port number
&hints, // e.g. SOCK_STREAM/SOCK_DGRAM
&res // The struct to populate
);
// Did we succeed?
if (status != 0)
{ {
return SocketSaveError(out, SOCKET_ERROR_SNPRINTF); outsocket->error = SocketGetLastError();
} TraceLog(
LOG_DEBUG, "Socket Error: %s", SocketErrorCodeToString(outsocket->error));
struct addrinfo* ai = NULL; SocketSetLastError(0);
int addr_res = getaddrinfo(cfg->host, port_str, &hints, &res); TraceLog(LOG_WARNING,
if (addr_res != 0) "Failed to get resolve host %s:%s: %s",
{ config->host,
out->getaddrinfo_error = addr_res; config->port,
SocketGetLastErrorString());
freeaddrinfo(res); freeaddrinfo(res);
return SocketSaveError(out, SOCKET_ERROR_GETADDRINFO); return false;
} }
memcpy(&out->addrinfo, res, sizeof(struct addrinfo)); else
for (ai = res; ai != NULL; ai = ai->ai_next)
{ {
fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); TraceLog(
if (fd == -1) LOG_INFO, "Successfully resolved host %s:%s", config->host, config->port);
}
memcpy(&outresult->addrinfo, res, sizeof(struct addrinfo));
// Walk the addrinfo struct
struct addrinfo* it;
for (it = res; it != NULL; it = it->ai_next)
{
// Initialise the socket
if (!InitSocket(outsocket))
{ {
/* Save errno, but will be clobbered if others succeed. */ outsocket->error = SocketGetLastError();
out->status = SOCKET_ERROR_SOCKET; TraceLog(
out->saved_errno = SocketGetLastError(); LOG_DEBUG, "Socket Error: %s", SocketErrorCodeToString(outsocket->error));
SocketSetError(0); SocketSetLastError(0);
continue; continue;
} }
if (!SocketSetOptions(cfg, out, fd)) // Set socket options
if (!SocketSetOptions(config, outsocket->handle))
{ {
outsocket->error = SocketGetLastError();
TraceLog(
LOG_DEBUG, "Socket Error: %s", SocketErrorCodeToString(outsocket->error));
SocketSetLastError(0);
freeaddrinfo(res); freeaddrinfo(res);
return false; return false;
} }
if (cfg->server) // Only bind to sockets marked as server
if (config->server)
{ {
int bind_res = bind(fd, res->ai_addr, res->ai_addrlen); if (BindSocket(outsocket->handle, config, it))
if (bind_res == -1)
{ {
TraceLog(LOG_INFO, "Successfully bound socket.");
}
else
{
outsocket->error = SocketGetLastError();
TraceLog(LOG_DEBUG,
"Socket Error: %s",
SocketErrorCodeToString(outsocket->error));
SocketSetLastError(0);
freeaddrinfo(res); freeaddrinfo(res);
return SocketSaveError(out, SOCKET_ERROR_BIND); return false;
} }
if (!cfg->datagram)
{
int listen_res = listen(fd, cfg->backlog_size);
if (listen_res == -1)
{
freeaddrinfo(res);
return SocketSaveError(out, SOCKET_ERROR_LISTEN);
}
}
break;
} }
else /* client */ else
{ {
if (cfg->datagram) if (ConnectSocket(outsocket->handle, config, it))
{
break;
}
int connect_res = connect(fd, ai->ai_addr, ai->ai_addrlen);
if (connect_res == 0)
{ {
TraceLog(LOG_INFO, "Successfully connected to socket.");
break; break;
} }
else else
{ {
close(fd); outsocket->error = SocketGetLastError();
fd = -1; TraceLog(LOG_DEBUG,
out->status = SOCKET_ERROR_CONNECT; "Socket Error: %s",
SocketErrorCodeToString(outsocket->error));
SocketSetLastError(0);
SocketClose(outsocket->handle);
continue; continue;
} }
} }
} }
if (fd == -1) if (!IsSocketValid(outsocket->handle))
{ {
if (out->status == SOCKET_OK) outsocket->error = SocketGetLastError();
{ TraceLog(
freeaddrinfo(res); LOG_DEBUG, "Socket Error: %s", SocketErrorCodeToString(outresult->status));
return SocketSaveError(out, SOCKET_ERROR_UNKNOWN); SocketSetLastError(0);
} freeaddrinfo(res);
else return false;
{
out->saved_errno = SocketGetLastError();
SocketSetError(0);
freeaddrinfo(res);
return false;
}
} }
out->status = SOCKET_OK; outresult->status = RESULT_SUCCESS;
outresult->socket.ready = 0;
outresult->socket.error = 0;
outresult->socket.isServer = config->server;
outresult->socket.address.host = (char*) malloc(INET6_ADDRSTRLEN);
SocketAddressToString(res->ai_addr, outresult->socket.address.host, &outresult->socket.address.port);
freeaddrinfo(res); freeaddrinfo(res);
out->saved_errno = 0;
out->socket.handle = fd;
out->socket.ready = 0;
out->socket.host.host = ((struct sockaddr_in*) res->ai_addr)->sin_addr.s_addr;
out->socket.host.port = ((struct sockaddr_in*) res->ai_addr)->sin_port;
out->socket.sflag = cfg->server;
return true; return true;
} }
//
static bool BindSocket(SocketHandle handle, SocketConfig* config, struct addrinfo* iterator)
{
// Attempt to bind the socket
if (bind(handle, iterator->ai_addr, iterator->ai_addrlen) == SOCKET_ERROR)
{
SocketClose(handle);
return false;
}
// Don't listen on UDP sockets
if (!config->datagram)
{
if (listen(handle, config->backlog_size) != 0)
{
return false;
}
else
{
TraceLog(LOG_INFO, "Started listening on socket...");
}
}
return true;
}
//
static bool ConnectSocket(SocketHandle handle, SocketConfig* config, struct addrinfo* iterator)
{
// Don't connect datagram sockets
if (config->datagram)
{
return true;
}
// Did we connect successfully?
if (connect(handle, iterator->ai_addr, iterator->ai_addrlen) != SOCKET_ERROR)
{
return true;
}
else
{
return false;
}
}
//
static bool SocketSetBlocking(SocketResult* out)
{
#if PLATFORM == PLATFORM_WINDOWS
unsigned long mode = 0;
ioctlsocket(out->socket.handle, FIONBIO, &mode);
#else
int flags = fcntl(out->socket.handle, F_GETFL, 0);
fcntl(out->socket.handle, F_SETFL, flags & ~O_NONBLOCK);
#endif
}
//
static bool SocketSetNonBlocking(SocketResult* out) static bool SocketSetNonBlocking(SocketResult* out)
{ {
#if PLATFORM == PLATFORM_WINDOWS #if PLATFORM == PLATFORM_WINDOWS
unsigned long mode = 1; unsigned long mode = 1;
if (ioctlsocket(out->socket.handle, FIONBIO, &mode) != 0) ioctlsocket(out->socket.handle, FIONBIO, &mode);
{
return SocketSaveError(out, SOCKET_ERROR_FCNTL);
}
#else #else
int flags = fcntl(out->socket.handle, F_GETFL, 0); fcntl(out->socket.handle, F_SETFL, O_NONBLOCK);
if (flags == -1)
{
return SocketSaveError(out, SOCKET_ERROR_FCNTL);
}
if (fcntl(out->socket, F_SETFL, flags | O_NONBLOCK) < 0)
{
return SocketSaveError(out, SOCKET_ERROR_FCNTL);
}
#endif #endif
return true; return true;
} }
static bool SocketSetOptions(SocketConfig* cfg, SocketResult* out, int fd) //
static bool SocketSetOptions(SocketConfig* config, SocketHandle handle)
{ {
for (int i = 0; i < MAX_SOCK_OPTS; i++) for (int i = 0; i < MAX_SOCK_OPTS; i++)
{ {
SocketOpt* opt = &cfg->sockopts[i]; SocketOpt* opt = &config->sockopts[i];
if (opt->id == 0) if (opt->id == 0)
{ {
break; break;
} }
if (setsockopt(fd, SOL_SOCKET, opt->id, opt->value, opt->valueLen) < 0) if (setsockopt(handle, SOL_SOCKET, opt->id, opt->value, opt->valueLen) < 0)
{ {
return SocketSaveError(out, SOCKET_ERROR_SETSOCKOPT); return false;
} }
} }
return true; return true;
} }
static const char* SocketStatusToString(enum SocketStatus s)
{
switch (s)
{
case SOCKET_OK:
return "ok";
case SOCKET_ERROR_GETADDRINFO:
return "getaddrinfo";
case SOCKET_ERROR_SOCKET:
return "socket";
case SOCKET_ERROR_BIND:
return "bind";
case SOCKET_ERROR_LISTEN:
return "listen";
case SOCKET_ERROR_CONNECT:
return "connect";
case SOCKET_ERROR_FCNTL:
return "fcntl";
case SOCKET_ERROR_SNPRINTF:
return "snprintf";
case SOCKET_ERROR_CONFIGURATION:
return "configuration";
case SOCKET_ERROR_SETSOCKOPT:
return "setsockopt";
case SOCKET_ERROR_UNKNOWN:
default:
return "unknown";
}
}
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module implementation // Module implementation
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -396,7 +512,7 @@ char* ResolveIP(const char* ip, const char* port, int flags)
// Did we succeed? // Did we succeed?
if (status != 0) if (status != 0)
{ {
TraceLog(LOG_WARNING, "Failed to get resolve host %s:%s: %ls", ip, port, gai_strerror(errno)); TraceLog(LOG_WARNING, "Failed to get resolve host %s:%s: %s", ip, port, gai_strerror(errno));
} }
else else
{ {
@ -431,7 +547,7 @@ char* ResolveIP(const char* ip, const char* port, int flags)
// Did we succeed? // Did we succeed?
if (status != 0) if (status != 0)
{ {
TraceLog(LOG_WARNING, "Failed to resolve ip %s: %ls", ip, SocketGetLastErrorString()); TraceLog(LOG_WARNING, "Failed to resolve ip %s: %s", ip, SocketGetLastErrorString());
} }
else else
{ {
@ -457,6 +573,8 @@ char* ResolveHost(const char* address, const char* port, AddressInformation* out
int status; // Status value to return (0) is success int status; // Status value to return (0) is success
struct addrinfo hints; // Address flags (IPV4, IPV6, UDP?) struct addrinfo hints; // Address flags (IPV4, IPV6, UDP?)
struct addrinfo* results; // A pointer to the resulting address list struct addrinfo* results; // A pointer to the resulting address list
char ip[INET6_ADDRSTRLEN]; // Enough pace to hold a IPv6 string
int portptr;
// Set the hints // Set the hints
memset(&hints, 0, sizeof hints); memset(&hints, 0, sizeof hints);
@ -481,7 +599,7 @@ char* ResolveHost(const char* address, const char* port, AddressInformation* out
// Did we succeed? // Did we succeed?
if (status != 0) if (status != 0)
{ {
TraceLog(LOG_WARNING, "Failed to get resolve host %s:%s: %ls", address, port, gai_strerror(errno)); TraceLog(LOG_WARNING, "Failed to get resolve host %s:%s: %s", address, port, gai_strerror(errno));
} }
else else
{ {
@ -489,7 +607,7 @@ char* ResolveHost(const char* address, const char* port, AddressInformation* out
} }
struct addrinfo* iterator; struct addrinfo* iterator;
for (iterator = outaddr; iterator != NULL; iterator = iterator->ai_next) for (iterator = results; iterator != NULL; iterator = iterator->ai_next)
{ {
TraceLog(LOG_DEBUG, "GetAddressInformation"); TraceLog(LOG_DEBUG, "GetAddressInformation");
TraceLog(LOG_DEBUG, "\tFlags: 0x%x", iterator->ai_flags); TraceLog(LOG_DEBUG, "\tFlags: 0x%x", iterator->ai_flags);
@ -505,7 +623,7 @@ char* ResolveHost(const char* address, const char* port, AddressInformation* out
freeaddrinfo(results); freeaddrinfo(results);
// Return the resulting hostname // Return the resulting hostname
return SocketAddressToString(outaddr->ai_addr); return SocketAddressToString(outaddr->sockaddr, ip, &portptr);
} }
// This here is the bread and butter of the socket API, This function will // This here is the bread and butter of the socket API, This function will
@ -524,23 +642,27 @@ char* ResolveHost(const char* address, const char* port, AddressInformation* out
// SocketResult server_res; SocketResult client_res; // SocketResult server_res; SocketResult client_res;
bool SocketOpen(SocketConfig* config, SocketResult* result) bool SocketOpen(SocketConfig* config, SocketResult* result)
{ {
// Make sure we've not received a null config or result pointer
if (config == NULL || result == NULL) if (config == NULL || result == NULL)
{ {
return false; return false;
} }
memset(result, 0, sizeof(*result)); memset(result, 0, sizeof(*result));
// Set the defaults based on the config
if (!SocketSetDefaults(config)) if (!SocketSetDefaults(config))
{ {
result->status = SOCKET_ERROR_CONFIGURATION; TraceLog(LOG_DEBUG, "Configuration Error.");
return false; return false;
} }
// Create the socket
if (!CreateSocket(config, result)) if (!CreateSocket(config, result))
{ {
return false; return false;
} }
// If the config states non-blocking, set the socket to non-blocking
if (config->nonblocking) if (config->nonblocking)
{ {
if (!SocketSetNonBlocking(result)) if (!SocketSetNonBlocking(result))
@ -563,86 +685,134 @@ void SocketClose(SocketHandle socket)
} }
} }
// The accept function permits an incoming connection attempt on a socket. // The accept function permits an incoming connection attempt on a socket.
// //
// SocketHandle listener - The socket to listen for incoming connections on (i.e. server)
// SocketResult* out - The result of this function (if any, including errors)
//
// e.g.
//
// SocketResult connection;
// bool connected = false;
// if (!connected)
// {
// if (SocketAccept(server_res.socket.handle, &connection))
// {
// connected = true;
// }
// }
bool SocketAccept(SocketHandle listener, SocketResult* out) bool SocketAccept(SocketHandle listener, SocketResult* out)
{ {
struct sockaddr_in sock_addr; char ip[INET6_ADDRSTRLEN];
socklen_t sock_alen; struct sockaddr_storage sockAddr;
sock_alen = sizeof(sock_addr); socklen_t sockAddrLen;
out->socket.handle = accept(listener, (struct sockaddr*) &sock_addr, &sock_alen); sockAddrLen = sizeof(sockAddr);
out->socket.handle = accept(listener, (struct sockaddr*) &sockAddr, &sockAddrLen);
if (out->socket.handle == INVALID_SOCKET) if (out->socket.handle == INVALID_SOCKET)
{ {
/* Save errno, but will be clobbered if others succeed. */ out->socket.error = SocketGetLastError();
out->status = SOCKET_ERROR_ACCEPT; TraceLog(
out->saved_errno = SocketGetLastError(); LOG_DEBUG, "Socket Error: %s", SocketErrorCodeToString(out->socket.error));
SocketSetError(0); SocketSetLastError(0);
return false; return false;
} }
memcpy(&out->addrinfo, &sock_addr, sizeof(struct sockaddr)); memcpy(&out->addrinfo, &sockAddr, sizeof(struct sockaddr));
out->socket.host.host = sock_addr.sin_addr.s_addr; out->socket.address.host = inet_ntop(sockAddr.ss_family, GetSocketAddressPtr((struct sockaddr*) &sockAddr), ip, sizeof ip);
out->socket.host.port = sock_addr.sin_port; out->socket.address.port = ntohs(GetSocketPortPtr((struct sockaddr*) &sockAddr));
TraceLog(LOG_DEBUG, "Server: Got connection from %s\n", out->socket.address.host);
return true; return true;
} }
/* Send 'len' bytes of 'data' over the non-server socket 'sock' // Send 'len' bytes of 'data' over the non-server socket 'sock'
This function returns the actual amount of data sent. If the return value //
is less than the amount of data sent, then either the remote connection was // Example
closed, or an unknown socket error occurred. int SocketSend(Socket* socket, const char* buffer, int length)
*/
int SocketSend(Socket* socket, const void* datap, int len)
{ {
const unsigned char* data = (const unsigned char*) datap; /* For pointer arithmetic */ int sentTotal = 0; // How many bytes we've sent
int sent, left; int bytesleft = length; // How many do we have left to send
int actuallySent; // How many bytes did we send this tick?
struct sockaddr_in dest; // The datagram (UDP) destination
dest.sin_addr.s_addr = socket->address.host;
dest.sin_port = socket->address.port;
// /* Server sockets are for accepting connections only */ // Which socket are we trying to send data on
if (socket->sflag) switch (socket->type)
{ {
// out->status = SOCKET_ERROR_SEND; case SOCKET_TCP:
// out->saved_errno = SocketGetLastError(); if (IsSocketValid(socket->handle))
// SocketSetError(0); {
return (-1); if ((length > 0) && (buffer != NULL))
{
SocketSetLastError(0);
do
{
actuallySent = send(socket->handle, buffer + sentTotal, bytesleft, 0);
if (actuallySent > 0)
{
sentTotal += actuallySent;
bytesleft -= actuallySent;
}
} while ((bytesleft > 0) && // While we still have bytes left to send
((actuallySent > 0) || // The amount of bytes we actually sent is > 0
(SocketGetLastError() == EINTR)) // The socket was interupted
);
}
}
break;
case SOCKET_UDP:
if (IsSocketValid(socket->handle))
{
if ((length > 0) && (buffer != NULL))
{
SocketSetLastError(0);
do
{
actuallySent = sendto(socket->handle, buffer + sentTotal, bytesleft, 0, (struct sockaddr*) &dest, sizeof dest);
if (actuallySent > 0)
{
sentTotal += actuallySent;
bytesleft -= actuallySent;
}
} while ((bytesleft > 0) && // While we still have bytes left to send
((actuallySent > 0) || // The amount of bytes we actually sent is > 0
(SocketGetLastError() == EINTR)) // The socket was interupted
);
}
}
break;
default:
break;
} }
/* Keep sending data until it's sent or an error occurs */ // Server sockets are for accepting connections only
left = len; if (socket->isServer)
sent = 0;
SocketSetError(0);
do
{ {
len = send(socket->handle, (const char*) data, left, 0); TraceLog(LOG_WARNING, "Cannot send information on a server socket");
if (len > 0) return -1;
{ }
sent += len;
left -= len;
data += len;
}
} while ((left > 0) && ((len > 0) || (SocketGetLastError() == EINTR)));
return (sent); return sentTotal;
} }
/* Receive up to 'maxlen' bytes of data over the non-server socket 'sock', // Receive up to 'maxlen' bytes of data over the non-server socket 'sock',
and store them in the buffer pointed to by 'data'. // and store them in the buffer pointed to by 'data'.
This function returns the actual amount of data received. If the return // This function returns the actual amount of data received. If the return
value is less than or equal to zero, then either the remote connection was // value is less than or equal to zero, then either the remote connection was
closed, or an unknown socket error occurred. // closed, or an unknown socket error occurred.
*/
int SocketReceive(Socket* socket, void* data, int maxlen) int SocketReceive(Socket* socket, void* data, int maxlen)
{ {
int len; int len;
/* Server sockets are for accepting connections only */ /* Server sockets are for accepting connections only */
if (socket->sflag) if (socket->isServer)
{ {
// out->status = SOCKET_ERROR_RECEIVE; // out->status = SOCKET_ERROR_RECEIVE;
// out->saved_errno = SocketGetLastError(); // out->saved_errno = SocketGetLastError();
// SocketSetError(0); // SocketSetLastError(0);
return (-1); return (-1);
} }
SocketSetError(0); SocketSetLastError(0);
do do
{ {
len = recv(socket->handle, (char*) data, maxlen, 0); len = recv(socket->handle, (char*) data, maxlen, 0);
@ -652,30 +822,7 @@ int SocketReceive(Socket* socket, void* data, int maxlen)
return (len); return (len);
} }
/* Construct an error message in BUF, based on the status codes // Set "hints" in an addrinfo struct, to be passed to getaddrinfo.
* in *RES. This has the same return value and general behavior
* as snprintf -- if the return value is >= buf_size, the string
* has been truncated. Returns -1 if either BUF or RES are NULL. */
int SocketGetError(char* buf, size_t buf_size, SocketResult* res)
{
if (buf == NULL || res == NULL)
{
return 0;
}
return snprintf(buf, buf_size, "%s: %ls", SocketStatusToString(res->status), (res->status == SOCKET_ERROR_GETADDRINFO ? gai_strerror(res->getaddrinfo_error) : strerror(res->saved_errno)));
}
/* Print an error message based on the status contained in *RES. */
void SocketPrintError(SocketResult* res)
{
if (res == NULL)
{
return;
}
printf("%s: %ls\n", SocketStatusToString(res->status), (res->status == SOCKET_ERROR_GETADDRINFO ? gai_strerror(res->getaddrinfo_error) : strerror(res->saved_errno)));
}
/* Set "hints" in an addrinfo struct, to be passed to getaddrinfo. */
void SocketSetHints(SocketConfig* cfg, struct addrinfo* hints) void SocketSetHints(SocketConfig* cfg, struct addrinfo* hints)
{ {
if (cfg == NULL || hints == NULL) if (cfg == NULL || hints == NULL)
@ -685,11 +832,7 @@ void SocketSetHints(SocketConfig* cfg, struct addrinfo* hints)
memset(hints, 0, sizeof(*hints)); memset(hints, 0, sizeof(*hints));
/* if .IPv4 or .IPv6 are used, set and use that instead of *host */ /* if .IPv4 or .IPv6 are used, set and use that instead of *host */
if (cfg->path) if (cfg->IPv6)
{
hints->ai_family = AF_UNIX;
}
else if (cfg->IPv6)
{ {
hints->ai_family = AF_INET6; hints->ai_family = AF_INET6;
} }
@ -728,6 +871,7 @@ void PrintSocket(struct SocketAddress* addr, const int family, const int socktyp
{ {
struct sockaddr* sockaddr_ip; struct sockaddr* sockaddr_ip;
char ip[INET6_ADDRSTRLEN]; // Enough pace to hold a IPv6 string char ip[INET6_ADDRSTRLEN]; // Enough pace to hold a IPv6 string
int port;
switch (family) switch (family)
{ {
case AF_UNSPEC: case AF_UNSPEC:
@ -738,13 +882,13 @@ void PrintSocket(struct SocketAddress* addr, const int family, const int socktyp
case AF_INET: case AF_INET:
{ {
TraceLog(LOG_DEBUG, "\tFamily: AF_INET (IPv4)"); TraceLog(LOG_DEBUG, "\tFamily: AF_INET (IPv4)");
TraceLog(LOG_INFO, "\t- IPv4 address %s", SocketAddressToString(addr, ip)); TraceLog(LOG_INFO, "\t- IPv4 address %s", SocketAddressToString(addr, ip, &port));
} }
break; break;
case AF_INET6: case AF_INET6:
{ {
TraceLog(LOG_DEBUG, "\tFamily: AF_INET6 (IPv6)"); TraceLog(LOG_DEBUG, "\tFamily: AF_INET6 (IPv6)");
TraceLog(LOG_INFO, "\t- IPv6 address %s", SocketAddressToString(addr, ip)); TraceLog(LOG_INFO, "\t- IPv6 address %s", SocketAddressToString(addr, ip, &port));
} }
break; break;
case AF_NETBIOS: case AF_NETBIOS:
@ -802,18 +946,22 @@ void PrintSocket(struct SocketAddress* addr, const int family, const int socktyp
} }
// Convert network ordered socket address to human readable string (127.0.0.1) // Convert network ordered socket address to human readable string (127.0.0.1)
char* SocketAddressToString(struct SocketAddress* sockaddr, char buffer[]) char* SocketAddressToString(struct SocketAddress* sockaddr, char buffer[], int* port)
{ {
switch (sockaddr->family) switch (sockaddr->family)
{ {
case AF_INET: case AF_INET:
{ {
return inet_ntop(AF_INET, &((struct sockaddr_in*) sockaddr)->sin_addr, buffer, INET_ADDRSTRLEN); struct sockaddr_in* s = ((struct sockaddr_in*) sockaddr);
*port = ntohs(s->sin_port);
return inet_ntop(AF_INET, &s->sin_addr, buffer, INET_ADDRSTRLEN);
} }
break; break;
case AF_INET6: case AF_INET6:
{ {
return inet_ntop(AF_INET6, &((struct sockaddr_in6*) sockaddr)->sin6_addr, buffer, INET6_ADDRSTRLEN); struct sockaddr_in6* s = ((struct sockaddr_in6*) sockaddr);
*port = ntohs(s->sin6_port);
return inet_ntop(AF_INET6, &s->sin6_addr, buffer, INET6_ADDRSTRLEN);
} }
break; break;
default: default:
@ -824,19 +972,17 @@ char* SocketAddressToString(struct SocketAddress* sockaddr, char buffer[])
} }
} }
/* // PackData() -- store data dictated by the format string in the buffer
** PackData() -- store data dictated by the format string in the buffer //
** // bits |signed unsigned float string
** bits |signed unsigned float string // -----+----------------------------------
** -----+---------------------------------- // 8 | c C
** 8 | c C // 16 | h H f
** 16 | h H f // 32 | l L d
** 32 | l L d // 64 | q Q g
** 64 | q Q g // - | s
** - | s //
** // (16-bit unsigned length is automatically prepended to strings)
** (16-bit unsigned length is automatically prepended to strings)
*/
unsigned int PackData(unsigned char* buf, char* format, ...) unsigned int PackData(unsigned char* buf, char* format, ...)
{ {
va_list ap; va_list ap;
@ -964,20 +1110,18 @@ unsigned int PackData(unsigned char* buf, char* format, ...)
return size; return size;
} }
/* // UnpackData() -- unpack data dictated by the format string into the buffer
** UnpackData() -- unpack data dictated by the format string into the buffer //
** // bits |signed unsigned float string
** bits |signed unsigned float string // -----+----------------------------------
** -----+---------------------------------- // 8 | c C
** 8 | c C // 16 | h H f
** 16 | h H f // 32 | l L d
** 32 | l L d // 64 | q Q g
** 64 | q Q g // - | s
** - | s //
** // (string is extracted based on its stored length, but 's' can be
** (string is extracted based on its stored length, but 's' can be // prepended with a max length)
** prepended with a max length)
*/
void UnpackData(unsigned char* buf, char* format, ...) void UnpackData(unsigned char* buf, char* format, ...)
{ {
va_list ap; va_list ap;

View File

@ -1,47 +1,93 @@
/**********************************************************************************************
*
* sysnet - Provides cross-platform network defines, macros etc
*
* DEPENDENCIES:
* <limits.h> - Used for cross-platform type specifiers
*
* INSPIRED BY:
* SFML Sockets - https://www.sfml-dev.org/documentation/2.5.1/classsf_1_1Socket.php
* SDL_net - https://www.libsdl.org/projects/SDL_net/
* BSD Sockets - https://www.gnu.org/software/libc/manual/html_node/Sockets.html
* BEEJ - https://beej.us/guide/bgnet/html/single/bgnet.html
* Winsock2 - https://docs.microsoft.com/en-us/windows/desktop/api/winsock2
*
*
* CONTRIBUTORS:
* Jak Barnes (github: @syphonx) (Feb. 2019):
* - Initial version
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
//----------------------------------------------------------------------------------
// Platform type sizes
//----------------------------------------------------------------------------------
#include <limits.h>
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Undefine any conflicting windows.h symbols // Undefine any conflicting windows.h symbols
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// If defined, the following flags inhibit definition of the indicated items. // If defined, the following flags inhibit definition of the indicated items.
#define NOGDICAPMASKS // CC_*, LC_*, PC_*, CP_*, TC_*, RC_ #define NOGDICAPMASKS // CC_*, LC_*, PC_*, CP_*, TC_*, RC_
#define NOVIRTUALKEYCODES // VK_* #define NOVIRTUALKEYCODES // VK_*
#define NOWINMESSAGES // WM_*, EM_*, LB_*, CB_* #define NOWINMESSAGES // WM_*, EM_*, LB_*, CB_*
#define NOWINSTYLES // WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_* #define NOWINSTYLES // WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_*
#define NOSYSMETRICS // SM_* #define NOSYSMETRICS // SM_*
#define NOMENUS // MF_* #define NOMENUS // MF_*
#define NOICONS // IDI_* #define NOICONS // IDI_*
#define NOKEYSTATES // MK_* #define NOKEYSTATES // MK_*
#define NOSYSCOMMANDS // SC_* #define NOSYSCOMMANDS // SC_*
#define NORASTEROPS // Binary and Tertiary raster ops #define NORASTEROPS // Binary and Tertiary raster ops
#define NOSHOWWINDOW // SW_* #define NOSHOWWINDOW // SW_*
#define OEMRESOURCE // OEM Resource values #define OEMRESOURCE // OEM Resource values
#define NOATOM // Atom Manager routines #define NOATOM // Atom Manager routines
#define NOCLIPBOARD // Clipboard routines #define NOCLIPBOARD // Clipboard routines
#define NOCOLOR // Screen colors #define NOCOLOR // Screen colors
#define NOCTLMGR // Control and Dialog routines #define NOCTLMGR // Control and Dialog routines
#define NODRAWTEXT // DrawText() and DT_* #define NODRAWTEXT // DrawText() and DT_*
#define NOGDI // All GDI defines and routines #define NOGDI // All GDI defines and routines
#define NOKERNEL // All KERNEL defines and routines #define NOKERNEL // All KERNEL defines and routines
#define NOUSER // All USER defines and routines #define NOUSER // All USER defines and routines
#define NONLS // All NLS defines and routines #define NONLS // All NLS defines and routines
#define NOMB // MB_* and MessageBox() #define NOMB // MB_* and MessageBox()
#define NOMEMMGR // GMEM_*, LMEM_*, GHND, LHND, associated routines #define NOMEMMGR // GMEM_*, LMEM_*, GHND, LHND, associated routines
#define NOMETAFILE // typedef METAFILEPICT #define NOMETAFILE // typedef METAFILEPICT
#define NOMINMAX // Macros min(a,b) and max(a,b) #define NOMINMAX // Macros min(a,b) and max(a,b)
#define NOMSG // typedef MSG and associated routines #define NOMSG // typedef MSG and associated routines
#define NOOPENFILE // OpenFile(), OemToAnsi, AnsiToOem, and OF_* #define NOOPENFILE // OpenFile(), OemToAnsi, AnsiToOem, and OF_*
#define NOSCROLL // SB_* and scrolling routines #define NOSCROLL // SB_* and scrolling routines
#define NOSERVICE // All Service Controller routines, SERVICE_ equates, etc. #define NOSERVICE // All Service Controller routines, SERVICE_ equates, etc.
#define NOSOUND // Sound driver routines #define NOSOUND // Sound driver routines
#define NOTEXTMETRIC // typedef TEXTMETRIC and associated routines #define NOTEXTMETRIC // typedef TEXTMETRIC and associated routines
#define NOWH // SetWindowsHook and WH_* #define NOWH // SetWindowsHook and WH_*
#define NOWINOFFSETS // GWL_*, GCL_*, associated routines #define NOWINOFFSETS // GWL_*, GCL_*, associated routines
#define NOCOMM // COMM driver routines #define NOCOMM // COMM driver routines
#define NOKANJI // Kanji support stuff. #define NOKANJI // Kanji support stuff.
#define NOHELP // Help engine interface. #define NOHELP // Help engine interface.
#define NOPROFILER // Profiler interface. #define NOPROFILER // Profiler interface.
#define NODEFERWINDOWPOS // DeferWindowPos routines #define NODEFERWINDOWPOS // DeferWindowPos routines
#define NOMCX // Modem Configuration Extensions #define NOMCX // Modem Configuration Extensions
#define MMNOSOUND #define MMNOSOUND
@ -50,52 +96,146 @@
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#define PLATFORM_WINDOWS 1 #define PLATFORM_WINDOWS 1
#define PLATFORM_UNIX 2 #define PLATFORM_LINUX 2
#if defined(__WIN32__) || defined(WIN32) #if defined(__WIN32__) || defined(WIN32)
# define PLATFORM PLATFORM_WINDOWS # define PLATFORM PLATFORM_WINDOWS
#else #elif defined(_LINUX)
# define PLATFORM PLATFORM_UNIX # define PLATFORM PLATFORM_LINUX
#endif #endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Platform specific network includes // Platform type definitions
// From: https://github.com/DFHack/clsocket/blob/master/src/Host.h
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#if PLATFORM_WINDOWS #ifndef __WORDSIZE
#define __USE_W32_SOCKETS # define __WORDSIZE 32
#pragma comment(lib, "ws2_32.lib") #endif
#include <winsock2.h>
#include <ws2tcpip.h> #if defined(_LINUX) || defined(_DARWIN)
#include <iphlpapi.h> typedef unsigned char uint8;
#else /* UNIX */ typedef char int8;
#include <sys/types.h> typedef unsigned short uint16;
#include <sys/ioctl.h> typedef short int16;
#include <sys/time.h> typedef unsigned int uint32;
#include <unistd.h> typedef int int32;
#include <fcntl.h> typedef int SOCKET;
#include <netinet/in.h> #endif
#include <netinet/tcp.h>
#include <sys/socket.h> #ifdef WIN32
#include <net/if.h> typedef unsigned char uint8;
#include <netdb.h> typedef char int8;
typedef unsigned short uint16;
typedef short int16;
typedef unsigned int uint32;
typedef int int32;
#endif
#ifdef WIN32
typedef int socklen_t;
#endif
#if defined(WIN32)
typedef unsigned long long int uint64;
typedef long long int int64;
#elif (__WORDSIZE == 32)
__extension__ typedef long long int int64;
__extension__ typedef unsigned long long int uint64;
#elif (__WORDSIZE == 64)
typedef unsigned long int uint64;
typedef long int int64;
#endif
#ifdef WIN32
# ifndef UINT8_MAX
# define UINT8_MAX (UCHAR_MAX)
# endif // UINT8_MAX
# ifndef UINT16_MAX
# define UINT16_MAX (USHRT_MAX)
# endif // UINT16_MAX
# ifndef UINT32_MAX
# define UINT32_MAX (ULONG_MAX)
# endif // UINT32_MAX
# if __WORDSIZE == 64
# define SIZE_MAX (18446744073709551615UL)
# else
# ifndef SIZE_MAX
# define SIZE_MAX (4294967295U)
# endif // SIZE_MAX
# endif // __WORDSIZE == 64
#endif // WIN32
#if defined(WIN32)
# define ssize_t size_t
#endif // WIN32
#ifndef TRUE
# define TRUE 1
#endif // TRUE
#ifndef FALSE
# define FALSE 0
#endif // FALSE
#ifndef RESULT_SUCCESS
# define RESULT_SUCCESS 0
#endif // RESULT_SUCCESS
#ifndef RESULT_FAILURE
# define RESULT_FAILURE 1
#endif // RESULT_FAILURE
#ifndef htonll
# ifdef _BIG_ENDIAN
# define htonll(x) (x)
# define ntohll(x) (x)
# else
# define htonll(x) ((((uint64) htonl(x)) << 32) + htonl(x >> 32))
# define ntohll(x) ((((uint64) ntohl(x)) << 32) + ntohl(x >> 32))
# endif // _BIG_ENDIAN
#endif // htonll
//----------------------------------------------------------------------------------
// Platform specific network includes
// From: https://github.com/SDL-mirror/SDL_net/blob/master/SDLnetsys.h
//----------------------------------------------------------------------------------
// Include system network headers
#ifdef _WIN32
# pragma comment(lib, "ws2_32.lib")
# define __USE_W32_SOCKETS
# include <Ws2tcpip.h>
# include <io.h>
# include <winsock2.h>
# define IPTOS_LOWDELAY 0x10
#else /* UNIX */
# include <sys/types.h>
# include <fcntl.h>
# include <netinet/in.h>
# include <sys/ioctl.h>
# include <sys/time.h>
# include <unistd.h>
# include <net/if.h>
# include <netdb.h>
# include <netinet/tcp.h>
# include <sys/socket.h>
#endif /* WIN32 */ #endif /* WIN32 */
/* System-dependent definitions */ #ifndef INVALID_SOCKET
# define INVALID_SOCKET ~(0)
#endif
#ifndef __USE_W32_SOCKETS #ifndef __USE_W32_SOCKETS
# define closesocket close # define closesocket close
# define SOCKET int # define SOCKET int
# define INVALID_SOCKET -1 # define INVALID_SOCKET -1
# define SOCKET_ERROR -1 # define SOCKET_ERROR -1
#endif /* __USE_W32_SOCKETS */ #endif
#ifdef __USE_W32_SOCKETS #ifdef __USE_W32_SOCKETS
# define RNet_GetLastError WSAGetLastError
# define RNet_SetLastError WSASetLastError
# ifndef EINTR # ifndef EINTR
# define EINTR WSAEINTR # define EINTR WSAEINTR
# endif # endif
#else
int RNet_GetLastError(void);
void RNet_SetLastError(int err);
#endif #endif