From 9d2096c2a57a08f6714ffec6fdb285b7afb7d86b Mon Sep 17 00:00:00 2001 From: "Matsievskiy S.V" Date: Mon, 6 Apr 2020 22:49:13 +0300 Subject: [PATCH 1/2] add TCP and UDP server samples --- samples/tcpsrv.lua | 54 ++++++++++++++++++++++++++++++++++++++++++++++ samples/udpsrv.lua | 47 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100755 samples/tcpsrv.lua create mode 100755 samples/udpsrv.lua diff --git a/samples/tcpsrv.lua b/samples/tcpsrv.lua new file mode 100755 index 00000000..4c5365e3 --- /dev/null +++ b/samples/tcpsrv.lua @@ -0,0 +1,54 @@ +#! /usr/bin/env lua + +-- +-- Sample TCP echo server. Listens on 3333 port +-- Use netcat to send strings to server (ncat 127.0.0.1 3333) +-- + +local lgi = require 'lgi' +local Gio = lgi.Gio + +local app = Gio.Application{application_id = 'org.test.tcptest', + flags = Gio.ApplicationFlags.NON_UNIQUE} + +local service = Gio.SocketService.new() +service:add_address( + Gio.InetSocketAddress.new_from_string("127.0.0.1", 3333), + Gio.SocketType.STREAM, + Gio.SocketProtocol.TCP) + +local function get_message(conn, istream, ostream) + ostream:async_write("> ") + local bytes = istream:async_read_bytes(4096) + while bytes:get_size() > 0 do + print(string.format("Data: %s", + bytes.data:sub(1, bytes:get_size()-1))) + ostream:async_write(bytes.data) + ostream:async_write("> ") + bytes = istream:async_read_bytes(4096) + end + print("Closing connection") + conn:close() +end + +function service:on_incoming(conn) + local istream = conn:get_input_stream() + local ostream = conn:get_output_stream() + local rc = conn:get_remote_address() + print(string.format("Incoming connection from %s:%s", + rc:get_address():to_string(), + rc:get_port())) + Gio.Async.call(function(ostream) + ostream:async_write("Connected\n") + end)(ostream) + Gio.Async.start(get_message)(conn, istream, ostream) + return false +end + +service:start() + +function app:on_activate() + app:hold() +end + +app:run({arg[0]}) diff --git a/samples/udpsrv.lua b/samples/udpsrv.lua new file mode 100755 index 00000000..2604c41c --- /dev/null +++ b/samples/udpsrv.lua @@ -0,0 +1,47 @@ +#! /usr/bin/env lua + +-- +-- Sample UDP server. Listens on 3333 port +-- Use netcat to send strings to server (ncat -u 127.0.0.1 3333) +-- + +local lgi = require 'lgi' +local GLib = lgi.GLib +local Gio = lgi.Gio + +local app = Gio.Application{application_id = 'org.v1993.udptest', + flags = Gio.ApplicationFlags.NON_UNIQUE} + +local socket = lgi.Gio.Socket.new(Gio.SocketFamily.IPV4, + Gio.SocketType.DATAGRAM, + Gio.SocketProtocol.UDP) +local sa = lgi.Gio.InetSocketAddress.new( + Gio.InetAddress.new_loopback(Gio.SocketFamily.IPV4), + 3333) +assert(socket:bind(sa, true)) + +do + -- To avoid extra allocations + local buf = require("lgi.core").bytes.new(4096) + local source = socket:create_source(GLib.IOCondition.IN) + source:set_callback(function() + print('Data incoming') + local len, src = socket:receive_from(buf) + if len > 0 then + print(('%s:%d %s'):format(src:get_address():to_string(), + src:get_port(), + tostring(buf):sub(1, len))) + else + print('Failed to read data') + end + return true + end) + + source:attach(lgi.GLib.MainContext.default()) +end + +function app:on_activate() + app:hold() +end + +app:run({arg[0]}) From 7b816132ff9a3f6bde88d0c2a4a69cf06b9a10be Mon Sep 17 00:00:00 2001 From: "Matsievskiy S.V" Date: Thu, 9 Apr 2020 15:03:13 +0300 Subject: [PATCH 2/2] add assertions --- samples/tcpsrv.lua | 35 +++++++++++++++---------------- samples/udpsrv.lua | 51 +++++++++++++++++++++++----------------------- 2 files changed, 41 insertions(+), 45 deletions(-) diff --git a/samples/tcpsrv.lua b/samples/tcpsrv.lua index 4c5365e3..11f3d75a 100755 --- a/samples/tcpsrv.lua +++ b/samples/tcpsrv.lua @@ -7,8 +7,9 @@ local lgi = require 'lgi' local Gio = lgi.Gio +local assert = lgi.assert -local app = Gio.Application{application_id = 'org.test.tcptest', +local app = Gio.Application{application_id = 'org.lgi.samples.tcptest', flags = Gio.ApplicationFlags.NON_UNIQUE} local service = Gio.SocketService.new() @@ -17,36 +18,32 @@ service:add_address( Gio.SocketType.STREAM, Gio.SocketProtocol.TCP) -local function get_message(conn, istream, ostream) - ostream:async_write("> ") - local bytes = istream:async_read_bytes(4096) - while bytes:get_size() > 0 do - print(string.format("Data: %s", - bytes.data:sub(1, bytes:get_size()-1))) - ostream:async_write(bytes.data) - ostream:async_write("> ") - bytes = istream:async_read_bytes(4096) +local function do_echo_connection(conn, istream, ostream) + local wrote, err = ostream:async_write_all("Connected\n") + assert(wrote >= 0, err) + while true do + local bytes = assert(istream:async_read_bytes(4096)) + if bytes:get_size() == 0 then break end + local data = bytes.data:gsub("\n", "") + print(string.format("Data: %s", data)) + wrote, err = ostream:async_write_all(bytes.data) + assert(wrote >= 0, err) end print("Closing connection") - conn:close() + conn:async_close() end function service:on_incoming(conn) - local istream = conn:get_input_stream() - local ostream = conn:get_output_stream() + local istream = assert(conn:get_input_stream()) + local ostream = assert(conn:get_output_stream()) local rc = conn:get_remote_address() print(string.format("Incoming connection from %s:%s", rc:get_address():to_string(), rc:get_port())) - Gio.Async.call(function(ostream) - ostream:async_write("Connected\n") - end)(ostream) - Gio.Async.start(get_message)(conn, istream, ostream) + Gio.Async.start(do_echo_connection)(conn, istream, ostream) return false end -service:start() - function app:on_activate() app:hold() end diff --git a/samples/udpsrv.lua b/samples/udpsrv.lua index 2604c41c..3eccfbe7 100755 --- a/samples/udpsrv.lua +++ b/samples/udpsrv.lua @@ -6,39 +6,38 @@ -- local lgi = require 'lgi' +local core = require 'lgi.core' local GLib = lgi.GLib local Gio = lgi.Gio +local assert = lgi.assert -local app = Gio.Application{application_id = 'org.v1993.udptest', +local app = Gio.Application{application_id = 'org.lgi.samples.udptest', flags = Gio.ApplicationFlags.NON_UNIQUE} -local socket = lgi.Gio.Socket.new(Gio.SocketFamily.IPV4, - Gio.SocketType.DATAGRAM, - Gio.SocketProtocol.UDP) -local sa = lgi.Gio.InetSocketAddress.new( - Gio.InetAddress.new_loopback(Gio.SocketFamily.IPV4), - 3333) +local socket = Gio.Socket.new(Gio.SocketFamily.IPV4, + Gio.SocketType.DATAGRAM, + Gio.SocketProtocol.UDP) +local sa = Gio.InetSocketAddress.new_from_string("127.0.0.1", 3333) assert(socket:bind(sa, true)) -do - -- To avoid extra allocations - local buf = require("lgi.core").bytes.new(4096) - local source = socket:create_source(GLib.IOCondition.IN) - source:set_callback(function() - print('Data incoming') - local len, src = socket:receive_from(buf) - if len > 0 then - print(('%s:%d %s'):format(src:get_address():to_string(), - src:get_port(), - tostring(buf):sub(1, len))) - else - print('Failed to read data') - end - return true - end) - - source:attach(lgi.GLib.MainContext.default()) -end +local buf = core.bytes.new(4096) +local source = assert(socket:create_source(GLib.IOCondition.IN)) + +source:set_callback(function() + local len, src = assert(socket:receive_from(buf)) + if len > 0 then + local data = tostring(buf):sub(1, len):gsub("\n", "") + print(string.format("%s:%d %s", + src:get_address():to_string(), + src:get_port(), + data)) + else + print('Failed to read data') + end + return true +end) + +source:attach(GLib.MainContext.default()) function app:on_activate() app:hold()