When you establish a connection in erlang with tcp sockets, you can make the socket active or not active.
If the socket is active, every time you receive some data from the client, it is send as an Erlang message with the format {tcp, Socket, Data}
, tcp
is just the tuple id, Socket
is a variable where you have all the information regarding the Socket, like on which local port you are listening, on which interface, and the port/ip of the peer sending data, and Data
is the data sent.
That's the reason you don't need to remember the Socket, because every time you receive a package, you will have the Socket
as an argument on the message.
If you set the socket as non active, you will need to use the function recv/2
in order to receive any data. Active sockets are easier to use, but if you have too much traffic it can overload the Erlang messaging system, so when you expect high load you always use non active sockets.
A "data package" is basically a package being sent over the connection, in this example the command send by the client is just sent in one data package because its a small package, but imagine that the data that the client has to send you, instead of being 10 or 20 chars, is like 100kb, you won't get it in one single package, you will get the data in different packages, and its your responsability as a programmer to put all the data that you get on multiple data packages all together.
In Erlang, when you do pattern matching, you can match anything with an underscore, like
{expected, _} = {expected, Anything}
No matter what you have bound on the variable Anything, that pattern matching will always be true. Now, imagine you have underscores all over the code, some times it gets confused an you want to add better code documentation, so you add someting after the underscore, like
{expected, _MiddleName} = {expected, Anything}
So now you don't care about the Middle Name because you don't need it at all, yet you documented on the code that the second value of the tuple should have the content of a Middle Name.
The garbage collector won't collect a Socket in use.
gen_server
is just a generic server written in Erlang, its actually a big topic because its part of the OTP architecture, you can find a good totorial on this link, but in few words, when you start doing erlang, you realize you write the same code for initializing the server (I'm not talking about a tcp server here, but about an Erlang server, which is a process which listen for Erlang messages and when receives any it acts and answer, or not, it will answer on a synchronic message and won't answer on an asyncrhonic message). So as I was saying, over time you realize that you write over and over again the same initialization, the same init functions, etc.
otp_server is just an Erlang module that abstract that same code that you use that repeats over and over again, and lets you just to focus on the task to write the real code that does some customized functions in order to serve its clients, and because it used by everyone, it gives a fixed structure that every erlang programmer understand and that every programmer can follow without major issues. On the link I gave you, it shows a perfect example of writing an Erlang server module without otp, on writing a generic server module template for all your next server modules, and it ends explaining that its exactly what OTP does for you.