Commit 827d9d19 authored by Colomban Wendling's avatar Colomban Wendling
Browse files

Server: implement a (still dummy) server that answers to connections

parent 3f5c5f69
......@@ -19,11 +19,161 @@
*/
public class Server: ThreadedSocketService
{
protected MainLoop loop = new MainLoop (null, false);
public string name { get; construct; }
public uint port { get; construct; default = 0xdead; }
public signal void stopped ();
/* receive a line from @socket */
private static string receive_line (Socket socket,
uint max_len = 255)
throws Error
{
var buf = new char[max_len + 1];
var rcv = socket.receive ((string)buf, max_len);
buf[rcv] = 0;
return ((string)buf).strip ();
}
private static bool send_line (Socket socket,
string line)
throws Error
{
var msg = line.strip () + "\n";
return socket.send (msg, msg.length) >= 0;
}
private bool handle_connection (ThreadedSocketService service,
SocketConnection connection,
Object? source)
{
debug ("New connection");
var socket = connection.socket;
try {
send_line (socket, "Welcome to server %s".printf (this.name));
} catch {
}
bool running = true;
uint bad_count = 0;
while (running)
{
try {
bool bad = false;
string? msg = null;
var line = receive_line (socket).down ();
debug ("""received "%s"""", line);
switch (line) {
case "sht":
case "shutdown":
msg = "YOU KILLED ME ;(";
running = false;
this.stop();
break;
case "\004": // EOF
case "eof":
msg = "Bye!";
running = false;
break;
case "hlo":
case "hello":
case "hi":
msg = "Hi you!";
break;
case "who":
msg = """Server name is "%s"""".printf (this.name);
break;
case "42":
msg = "You just LOST the game!";
break;
default:
bad = true;
msg = "Sorry, I don't undesrtand what you mean";
break;
}
if (bad) {
bad_count ++;
if (bad_count > 2) {
msg = "We don't seem to speak the same language, sorry.";
running = false;
}
} else if (bad_count > 0) {
bad_count--;
}
if (msg != null) {
debug ("""answering "%s"""", msg);
send_line (socket, msg);
}
} catch (Error e) {
warning ("error receiving data: %s", e.message);
break;
}
}
connection.socket.close ();
debug ("Closed connection");
return true;
}
construct
{
try {
var inetaddr = new InetAddress.from_string ("::1");
var inetsockaddr = new InetSocketAddress (inetaddr, (uint16)port);
this.add_address (inetsockaddr, SocketType.STREAM, SocketProtocol.DEFAULT,
null, null);
} catch (Error e) {
critical ("failed to add address: %s", e.message);
}
this.run.connect (handle_connection);
}
public Server (string name,
uint16 port = 0xdead)
{
Object (name: name, port: port);
}
/* a bit ugly since a direct call to parent method will not trigger the
* :stopped signal */
public new void stop ()
{
base.stop ();
this.stopped ();
}
}
public static int main (string[] args)
{
foreach (var arg in args) {
stdout.printf("%s\n", arg);
string name = "Unnamed server";
uint16 port = 0xdead;
if (args.length > 1) {
name = args[1];
}
if (args.length > 2) {
port = (uint16)int.parse (args[2]);
}
var loop = new MainLoop (null, false);
var server = new Server (name, port);
server.stopped.connect (() => loop.quit ());
server.start ();
loop.run ();
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment