Lua TCP/IP simple Client Server connection - tcp

I'm looking for a simple client-server connection in Lua. Due to bad online documentation I'm quite helpless. I found two threads here in stackoverflow but they didn't help much. Here is what I have so far:
Client:
local socket = require("socket")
local host, port = "192.168.100.47", 51515
local tcp = assert(socket.tcp())
tcp:connect(host, port);
tcp:send("hello world\n");
while true do
local s, status, partial = tcp:receive()
print(s or partial)
if status == "closed" then
break
end
end
tcp:close()
Server:
local socket = require("socket")
local server = assert(socket.bind("*", 51515))
local tcp = assert(socket.tcp())
print(socket._VERSION)
print(tcp)
while 1 do
local client = server:accept()
line = client:receive()
client:send("it works\n")
end

Here is a working client/server example, which is based on luasocket documentation and SO answers. If you have issues with getting it to work, you need to provide specific details about those issues.

Related

Some questions about start a new stream in libp2p host

First question is: When a host try to start a new stream to a remote with some streamhandler in libp2p, it seems the remote peer would automatically start a goroutine to handle this stream, while the local peer need to manually start this handler. What is the purpose of such design?
Second question is: If some remote peer start a new stream or connect my local host, can I monitor the inbound stream or get the inbound stream. Something like net.Listener.Accept().If so which method should I use.
Thank you.

Client-Server chatting in Lua

Server Program
local socket = require("socket")
local server = socket.try(socket.bind("*", 1234))
local ip, port = server:getsockname()
while 1 do
local client = server:accept()
client:settimeout(10)
local line, err = client:receive()
print (line)
print("Enter input:")
if not err then client:send(io.read().."\n") end
client:close()
end
Client Program
local host, port = "*", 1234
local socket = require("socket")
local tcp = assert(socket.tcp())
tcp:connect(host, port);
tcp:send("Connection Established\n");
while 1 do
local s, status, partial = tcp:receive()
print(s or partial)
print("Enter input:")
tcp:send(io.read().."\n");
if status == "closed" then break end
end
tcp:close()
The server program can send the message to client but the client can't send message to server. Is there any way to do it..??
I don't have enough reputation to comment, but after 10 seconds or the server sending a message, whichever comes first, the server closes the connection. The client doesn't attempt to send a message until after the server has sent a message, and the way you've written your code the server immediately closes the connection at this point. If you want the two to communicate you'd be better off accepting the client outside of the loop like so:
Server Program
local socket = require("socket")
local server = socket.try(socket.bind("*", 1234))
local ip, port = server:getsockname()
local client = server:accept()
client:settimeout(10)
while 1 do
local line, err = client:receive()
print (line)
print("Enter input:")
if not err then client:send(io.read().."\n") end
end
client:close()
Now, this brings up the issue in which the server lacks the code to realize a client has disconnected and needs to find a new client, however it shouldn't be that difficult to implement.

Creating an HTTP server in NodeMCU through an access point created by the board

I am coding a robot, using NodeMCU (ESP8266) and want it to be remote controlled. My current solution is connecting to a nearby router, to the internet and creating a TCP HTTP server. Data is streamed from the mobile device (remote) to the NodeMCU (robot) via HTTP requests. The remote is loaded onto the mobile device through a browser with HTML/CSS/JavaScript.
What I want instead is for the NodeMCU to create its own hotspot, because:
A router is not required
The connection is more direct
I want the same TCP HTTP solution, but I don't know how to serve a webpage through a custom hotspot.
This is my code:
-- Connect to router
wifi.sta.config("ssid","password")
wifi.sta.connect()
-- Code for waiting for connection
-- Create server
srv = net.createServer(net.TCP)
srv:listen(80,function(conn)
conn:on("receive",function(conn,payload)
for line in string.gmatch(payload,'[^\r\n]+') do
s = string.find(line, "GET /&")
-- If query is there, control robot
if s ~= nil then
-- Do stuff with query
break;
-- If no query, serve webpage
else
file.open("index.html", "r")
while true do
s = file.read(1460)
if s == nil then
break
end
conn:send(s)
end
file.close()
end
break
end
conn:on("sent", function(conn) conn:close() end)
end)
end)
Creating custom hotspot:
wifi.setmode(wifi.STATIONAP)
cfg={}
cfg.ssid="custom_ssid"
cfg.pwd="custom_password"
wifi.ap.config(cfg)
So how do I make it so the mobile can access the server? How do I get/set the IP of the server? Basically, I just need it to work. Thanks!
Not sure I fully understand but I believe you're really close. Check the documentation for the AP functions at http://nodemcu.readthedocs.io/en/latest/en/modules/wifi/#wifiap-module.
wifi.ap.config(cfg) sets SSID and pwd as you noted. Your client then connects to this AP by joining the network.
If you then print wifi.ap.getip() you'll see that the device has the IP address 192.168.1.4 by default. Hence, for clients which joined this network your server is reachable at 192.168.1.4:80 unless you set a custom IP explicitly.
However, the sending of data seems broken. You have multiple conn:send(s) (in the loop) yet you also have conn:on("sent", function(conn) conn:close() end) which means that the connection will be closed after the first conn:send! Check the docs at http://nodemcu.readthedocs.io/en/latest/en/modules/net/#netsocketsend for an example as for how to do that properly.

H2 Database Server to serve TCP clients from connection pool

I have a H2 server that I start from console. The client from different machine accesses the server and calls a function alias (registered at the database). The problem is, this function is called more than a million times. So, in this case, the connection timesout but then I solved it with changing the client connection string to have AUTORECONNECT=TRUE. This solves the problem but adds a reconnection time delay (which I want to avoid).
Is there any flag/command that we can use to specify with Server to dedicate X amount of connections?
Also, I looked into the possibility of starting the server from within Application. Like,
JdbcConnectionPool cp = JdbcConnectionPool.create(
"jdbc:h2:tcp://IPADDRESS:9092/~/test", "sa", "");
cp.setMaxConnections(MAX_CONN_IN_POOL);
// start the TCP Server
Server server = Server.createTcpServer().start();
Connection conn = cp.getConnection();
Statement stat = conn.createStatement();
stat.execute("SELECT myFunctionAlias(arg)");
cp.dispose();
server.stop();
The above sample code does start the server and will only run once. I want the server to be open and keep listening to clients, and serve them from the connection pool. Any pointers?
You should start the server in AUTO_SERVER mode, this way a leader election algorithm will elect a leader who will read the database file and open a TCP server for all other clients.
Thsi way the server will be really fast to read the file while other clients will be as fast as the network is.
This is transparent to the user as long as you use the same connection string.
Connection connection;
String dataBaseString = "jdbc:h2:/path/to/db/" + File.separator + "db;create=true;AUTO_SERVER=TRUE;AUTO_RECONNECT=TRUE";
try
{
Class.forName("org.h2.Driver");
log.info("getConnection(), driver found");
}
catch (java.lang.ClassNotFoundException e)
{
log.error("getConnection(), ClassNotFoundException: " + e.getMessage(), e);
Main.quit();
}
try
{
connection = DriverManager.getConnection(dataBaseString);
}

JSch session.connect() hungs with CoreFTP

I have CoreFTP configured for localhost and the next code:
JSch.setLogger(new MyJschLogger()); //class for console output
Session session = jsch.getSession("user", "localhost", 21);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword("password");
session.connect();
when program achieves connect(), two messages appear at console output:
INFO: Connecting to localhost port 21
INFO: Connection established
...and nothing more happens. After some minutes, connection is closed by foreign host exception appears.
Why?
Thanks for all!
Port 21 is the normal port for FTP. JSch is only an SSH client, with support for SFTP in the ChannelSFTP class. JSch knows nothing about FTP (and SFTP is unrelated to FTP, other than by name and that it allows similar things).
You need to setup your server to use the SSH protocol (usually on port 22, but you can use any port, as long as you use the same port on the client). See the documentation - I think you have to check the SSH check box.
Also, if your code is nothing more than what you posted, then nothing more than connecting will happen. To transfer files, you will need to open a ChannelSFTP, and issue the right commands (e.g. call one or more of the put/get methods).
I also faced the similar issue:
"ERROR 2016-04-27 15:05:16,489 [CollectionThreadPool-0] com.dell.supportassist.collector.cli.executor.SSHExecutor: com.jcraft.jsch.JSchException: connection is closed by foreign host"
In my case, channel was getting closed randomly. And when we are trying to re-connect the channel then it was not re-connecting and failing.
This was happening due to looping logic while connecting, so I tried to connect the session without channel by calling method connectWithoutOpenChannel instead of connectinternal(). This resolved my issue.

Resources