Не работает socket receive

213
23 августа 2018, 06:10

Пробую сделать бота на java для торгового терминала quik. Для того чтобы передавать информацию из квика в java сделал сокет клиент на lua, вот его код:

local socket = require('socket')
c = assert(socket.connect("localhost", 1111))
assert(c:send("message:HELLO LUA"))
s = c:receive()
message(s)
c:close()

Сокет сервер на java:

package bot.ext;
import bot.App;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server implements Runnable {
private ServerSocket serverSocket;
private boolean accept = true;
private String messageDelim = "message:";
private void message(String message, DataOutputStream out) {
    App.appendLog("Новое сообщение: " + message);
    try {
        out.write(("Receive: " + message).getBytes());
    } catch (IOException e) {
        e.printStackTrace();
    }
}
@Override
public void run() {
    try (ServerSocket server = new ServerSocket(1111)) {
        serverSocket = server;
        App.appendLog("Сервер запущен на порту: " + server.getLocalPort());
        while (accept && !server.isClosed()) {
            Socket client = server.accept();
            // Новый поток на обработку сообщений
            Thread receiveThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    App.appendLog("Новый запрос");
                    try {
                        DataInputStream in = new DataInputStream(client.getInputStream());
                        DataOutputStream out = new DataOutputStream(client.getOutputStream());
                        while (!client.isClosed()) {
                            if (in.available() == 0) continue;
                            byte[] barr = new byte[in.available()];
                            in.read(barr);
                            String entry = new String(barr);
                            if(!entry.contains(messageDelim)) continue;
                            String[] messages = entry.split(messageDelim);
                            for (String message:messages) {
                                if (message.equals("")) {
                                    continue;
                                } else if (message.equals("close")) {
                                    client.close();
                                }
                                message(message, out);
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
            receiveThread.start();
        }
    } catch (IOException e) {
        App.appendLog("Не удалось запустить сервер");
    }
}
public boolean getAccept() {
    return accept;
}
public void setAccept(boolean accept) {
    this.accept = accept;
}

}

Почему-то не получается получить ответ от сокет сервера. Lua скрипт зависает на методе receive. Есть еще проблема, если вызвать несколько методов send из lua, java сервер получит все эти сообщения в одном.

UPD: Похоже это какой-то баг http://lua-users.org/lists/lua-l/2007-04/msg00695.html

Если использовать receive так local s, status = c:receive(10, s) То он начинает принимать сообщения. Если повысить число байт до 100 или 1000, то ничего считывать не будет.

Answer 1

Попробуйте так :

require("socket")
local c = socket.tcp()
c:setoption('reuseaddr',true)
c:setoption('tcp-nodelay',true)
local res = c:connect("localhost", 1111)  
  if res then
    c:send("message:HELLO LUA")
    local s, status = c:receive("*a")     -- принять весь блок
    print(s)
    c:close()
  else print("Connect error!")
  end

2)

local line, str = 0, ""
local s, status
while true do
      s, status = c:receive('*l') 
      print(status)
      if s~=nil and status ~="closed" then 
              str=str..s
              line=line+1       
              if ( line>30 ) then print("Too many lines...\n".. str)  break end   -- слишком много строк
      else break
      end
end
print(str)
Answer 2

Сделал как-то так, спасибо Mike V )

local socket = require('socket')
c = assert(socket.connect("localhost", 1111))
c:send("message:HELLO LUA")
local mes = ""
local i = 0
local s
 while true do
 s = c:receive(i, s)
 if s ~= "" then
    i = i + 1
    mes = s
  else
    break
  end
  end
  message(mes)
  c:close()
READ ALSO
Сигнатуры методов HashMap

Сигнатуры методов HashMap

Почему метод put принимает на вход key параметр типа K:

195
Вывод данных в ReclerView Firebase

Вывод данных в ReclerView Firebase

Есть база данных Firebase с такой структурой:

196
Экранирование в POST запросе

Экранирование в POST запросе

У меня есть REST-сервис:

208