Erlang UDP Server and C++ SFML Client
Introduction
The code for this post can be found here.
Erlang (Server)
sudo apt-get install erlang
Once you have Erlang installed you can test that it has installed properly by running:
erl
This is Erlangs interactive console. Don’t forget your full stops!Before writing this post I had never used UDP in Erlang and so I follow a tutorial which can be found here. Upon reading more about it I found that it is based on an OTP protocol so I could have made the application with rebar and made it much more concurrent. However, I wanted to create two simple applications to play around with the sending and receiving from two different client languages.
The server code looks something like this:
-module(server). -export([start/1]). start(Port) -> spawn(fun() -> server(Port) end). server(Port) -> {ok, Socket} = gen_udp:open(Port, [binary, {active, false}]), io:format("Server opened socket: ~p~n", [Socket]), loop(Socket). loop(Socket) -> inet:setopts(Socket, [{active, once}]), receive {udp, Socket, Host, Port, Bin} -> %%Convert incoming binary message to a string Message = binary_to_list(Bin), io:format("Server received: "), io:format(Message), io:format("\n"), gen_udp:send(Socket, Host, Port, <<"Thanks for the packet, here is my reply packet!">>), loop(Socket) end.
To run the server open a terminal in the directory where you’ve created the server code and run the commands:
erl
c(server).
server:start(54321).
*If you’re on Windows you can open the Erlang application and change the current directory by:
cd(“Path to directory”).
C++ SFML (Client)
#include <SFML/Network.hpp>
#include <iostream>
#include <string>
int main()
{
//Set the port number
int Port = 12345;
//Set the server address
char serverAddress[] = “127.0.0.1”;
int serverPort = 54321;
//Create the socket
sf::UdpSocket socket;
//Bind the socket
socket.bind(Port);
std::cout << “Socket Bound” << std::endl;
//Send a message to the server server
std::string message = “Here is my game stuff in a packet”;
std::cout << “Message: “ << message << std::endl;
socket.send(message.c_str(), message.size() + 1, serverAddress, serverPort);
std::cout << “Mesage sent.” << std::endl;
//Recieve a message from the server.
char buffer[1024];
std::size_t received = 0;
sf::IpAddress sender;
unsigned short port;
socket.receive(buffer, sizeof(buffer), received, sender, port);
std::cout << “Reply: “ << buffer << std::endl;
return 0;
}
To compile it, I used the console commands:
g++ -c main.cpp
g++ main.o -o client -lsfml-network -lsfml-system
If you’re using an IDE your compile instructions will probably be different.
It’s all coming together
First start the server by navigating to the server folder in a terminal and running:
erl
c(server).
server:start(54321).
Secondly start up the client and watch it fire across a message by doing this in the client code folder:
g++ -c main.cpp
g++ main.o -o client -lsfml-network -lsfml-system
./client
You should now see that the client sends a message to the server, the server displays that message and replies to the client. The client then displays the reply message and ends. The server will stay running, waiting for the next client to connect.Where to go from here?
The first one would be prompting the user for the message to send on the client.
The second one could be storing the number of connections and returning them to the client.
Lastly you could make the client have a main loop more like a game that fires off to the server constantly polling for data.
Conclusion
This post started as a small experiment for my own mind. I really wanted to know how difficult this was going to be and if there was going to be any weird quirks with the binarys going back and forth between the languages.It turned out to be super easy and smooth which is a pleasant surprise.
At some point in the future I’m going to implement a proper game with an Erlang backend as a better example.
Thanks for reading and hopefully you’ve learned something (I know I did.).