Я хочу написать клиента, который может связываться с Vowpal Wabbit через TCP. По сути, мне нужно отправлять сообщения типа a b | c d e на хост VW через порт 26542. VW отвечает сообщением типа 0.400000 0.200000 0.200000 0.200000 (не знаю, чем заканчивается сообщение).
Итак, мне нужно сделать это несколько раз - отправить сообщение, получить сообщение, отправить сообщение, получить сообщение и так далее.
У меня есть следующий код на Java.
public class MyClient {
protected String host;
protected int port;
protected Socket socket;
protected PrintWriter outputWriter;
protected BufferedReader inputReader;
public MyClient(String host, int port) throws IOException {
socket = new Socket(host, port);
outputWriter = new PrintWriter(socket.getOutputStream());
inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
public void send(final String message) throws IOException {
outputWriter.print(message+"\n"); // important to add a newline
outputWriter.flush();
String responseStr = inputReader.readLine();
System.out.println(responseStr);
if (StringUtils.isBlank(responseStr)) {
return;
}
}
}
Я использую этот класс следующим образом:
MyClient client = new MyClient("host_ip", 26542); // the port used by VW
client.send("1:0.5:0.3 | feature11 feature21 feature31");
client.send("1:0.5:0.3 | feature12 feature22 feature32");
client.send("1:0.5:0.3 | feature13 feature23 feature33");
В приведенном выше коде печатается только ответ первой «отправки». Два других возвращают ответы null.
Я также пробовал использовать только код "отправить":
public void send(final String message) throws IOException {
outputWriter.print(message+"\n"); // important to add a newline
outputWriter.flush();
}
Оказывается, отправляется только первое сообщение (у меня есть способ проверить / зарегистрировать на стороне сервера то, что он получает от моего клиента).
Почему только первая отправка завершается успешно, а все остальные не проходят (хотя исключение не возникает)? Как я могу это исправить?
Ввод правильный. Есть и другие форматы, в которых мы можем отправить сообщение VW. Я использую другой формат (для контекстных бандитов). Я также проверил сообщение с echo '1:0.5:0.3 | feature11 feature21 feature31' | nc vw_host 26542 и получил верное ответное сообщение.




Если readLine() возвращает null, одноранговый узел закрыл соединение.
Итак, как мне обойти эту проблему? Стоит ли делать new Socket() для каждого сообщения? Это не кажется правильным.
Вы устраняете проблему, из-за которой сервер закрывает соединение, проверяя его ответ, и проверяете свое предположение, что сервер будет читать несколько ответов через одно и то же соединение. В любом случае, если он закрывает соединение, вы должны сделать то же самое и подключить новую розетку.
Я не знаю, закрывает ли VW соединение после каждого обмена, но я изменил свой код, чтобы создавать новое соединение каждый раз, когда я хочу отправить сообщение. Благодаря этому я могу правильно отправлять и получать сообщения. Так что, возможно, VW действительно закрывает соединение после каждого обмена.
Что ж, в данном конкретном случае это, безусловно, закрывает соединение. null так говорит.
Какой ответ на первое сообщение? Вы уверены, что ваш формат ввода правильный и что вы не получаете ответ об ошибке на свое первое сообщение? Разве это не должно быть
1 0.5 0.3 | feature11 feature21 feature31(пробелы вместо двоеточия)? Глядя на github.com/JohnLangford/vowpal_wabbit/wiki/Daemon-example, кажется, что это так.