Server.start
Test the server
telnet 127.0.0.1 8000
> Hello World
Server.start
In another terminal
{:ok, pid} = Client.start
Client.send_message(pid, "Hello World")
defmodule Client do | |
require Logger | |
use GenServer | |
@ip {127, 0, 0, 1} | |
@port 8000 | |
def send_message(pid, message) do | |
GenServer.cast(pid, {:message, message}) | |
end | |
def start do | |
GenServer.start(__MODULE__, %{socket: nil}) | |
end | |
def init(state) do | |
send(self(), :connect) | |
{:ok, state} | |
end | |
def handle_info(:connect, state) do | |
Logger.info "Connecting to #{:inet.ntoa(@ip)}:#{@port}" | |
case :gen_tcp.connect(@ip, @port, [:binary, active: true]) do | |
{:ok, socket} -> | |
{:noreply, %{state | socket: socket}} | |
{:error, reason} -> | |
disconnect(state, reason) | |
end | |
end | |
def handle_info({:tcp, _, data}, state) do | |
Logger.info "Received #{data}" | |
{:noreply, state} | |
end | |
def handle_info({:tcp_closed, _}, state), do: {:stop, :normal, state} | |
def handle_info({:tcp_error, _}, state), do: {:stop, :normal, state} | |
def handle_cast({:message, message}, %{socket: socket} = state) do | |
Logger.info "Sending #{message}" | |
:ok = :gen_tcp.send(socket, message) | |
{:noreply, state} | |
end | |
def disconnect(state, reason) do | |
Logger.info "Disconnected: #{reason}" | |
{:stop, :normal, state} | |
end | |
end |
defmodule Server do | |
require Logger | |
use GenServer | |
@port 8000 | |
def start do | |
GenServer.start(__MODULE__, %{socket: nil}) | |
end | |
def init(state) do | |
{:ok, socket} = :gen_tcp.listen(@port, [:binary, active: true]) | |
send(self(), :accept) | |
Logger.info "Accepting connection on port #{@port}..." | |
{:ok, %{state | socket: socket}} | |
end | |
def handle_info(:accept, %{socket: socket} = state) do | |
{:ok, _} = :gen_tcp.accept(socket) | |
Logger.info "Client connected" | |
{:noreply, state} | |
end | |
def handle_info({:tcp, socket, data}, state) do | |
Logger.info "Received #{data}" | |
Logger.info "Sending it back" | |
:ok = :gen_tcp.send(socket, data) | |
{:noreply, state} | |
end | |
def handle_info({:tcp_closed, _}, state), do: {:stop, :normal, state} | |
def handle_info({:tcp_error, _}, state), do: {:stop, :normal, state} | |
end |