как использовать readline без и EOF символов Java - PullRequest
0 голосов
/ 31 марта 2011

Я пытаюсь реализовать простое серверное приложение на Java.

все, что он делает, это читает сообщение в tcp / ip и сохраняет его как строку, это мой код.

    try{
        in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    } catch (IOException e) {
        System.out.println("cannot open input buffer");
        System.exit(-1);
    }

    clientSocket.setSoTimeout(5000);

    //read first bit of message
    message = in.readLine();
    System.out.println(message);
    //as message is an undefined length we need to loop and check for the springer miller 
    //end mark /Request
    while(message.contains("/Request") == false  )
    {
        try {
        message = in.readLine();
        System.out.println(message);
        }
        catch (IOException e) {
            System.out.println("cannot open input buffer");
            System.exit(-1);
        }
    }       

    //reply
    out.println(outputLine);

Проблема, с которой я столкнулся, заключается в том, что в сообщении отсутствует EOF. это протокол другой компании, который я перевожу на мой, это цель программы, поэтому я не могу добавить EOF к сообщению

информация, которую я получаю, если я запускаю программу:

POST / HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: http://htng.org/1.1/Listener.Wsdl#ReceiveMessageAsync
User-Agent: Java/1.6.0_24
Host: 192.168.0.32:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 3009

затем он зависает, когда должен прочитать тело сообщения.

Я никогда в своей жизни не использовал java и не хочу писать двоичный сокет для чтения моего собственного EOF.

есть ли способ прочитать в течение х секунд, а затем вернуть

спасибо за любую помощь.

P.S уже успешно собрал программу на C ++, но ему нужно портировать на java, потому что конечный компьютер неизвестен.

Ответы [ 2 ]

1 голос
/ 31 марта 2011

BufferedReader.readline вернет ноль в EOF и не сгенерирует исключение.

Более того, «протокол других компаний» выглядит как SOAP поверх HTTP. Может быть, вы хотите использовать библиотеку HTTP или SOAP? Другие здесь смогут давать указатели ...

В противном случае вы можете использовать следующий подход: Один раз прочитайте строку, чтобы проверить, действительно ли метод POST (в противном случае заголовок Content-Length мог бы отсутствовать) и правильный путь.
readLine, пока он не вернет пустую строку (или ноль), чтобы прочитать все заголовки HTTP. При этом обратите внимание на строку, начинающуюся с Content-Length, чтобы определить длину следующих XML-данных. создайте char [] правильной длины и используйте in.read(cbuf, 0, cbuf.length), чтобы прочитать xml в созданный буфер cbuf. * ​​1009 *

0 голосов
/ 31 марта 2011

Реализация протоколов поверх TCP / IP довольно сложна и требует большого понимания того, как работают сети, сокеты и операционные системы ввода-вывода.

Кроме того, реализация HTTP на удивление сложна - вдобавок к сложности сети.

Я вежливо предполагаю, что вы, вероятно, находитесь в глубокой воде, поскольку вы должны задавать вопросы на этом уровне и, возможно, нуждаетесь в большей помощи, чем вы можете получить на SO.

... в любом случае.

Если сервер, с которого вы читаете, пытается установить http, используйте для него существующий компонент. Apache HttpComponents, если, вероятно, хороший выбор. Я на самом деле не покупаю, что это подделывает http заголовки, и я предлагаю вам пропустить свой «легкий» подход.

Вот некоторые основные факты о сетевом вводе-выводе.

Сетевые записи ориентированы на пакеты. Tcp / ip обычно старается как можно больше вложить в каждый пакет (используя некоторые умные алгоритмы). Это означает, что если вы записываете 4000 байтов, сообщение разбивается на несколько пакетов произвольного размера, но обычно меньше 1500 байт - в зависимости от сетевого оборудования. Это также означает, что если вы пишете меньше пакета, ваши записи могут быть объединены в один пакет. (Пакеты также могут быть разделены и объединены по пути.)

Чтобы отправлять сообщения по потоку (который сам транспортируется в пакетах ...), вам нужно заранее знать, как долго эти сообщения, или прочитать полный пакет (сделать .read () в большой буфер), анализировать содержимое, извлекать и создавать полные сообщения каким-либо разумным способом. Именно то, что делает http. (среди прочего)

TCP / IP определенно НЕ ориентирован на строки, поэтому ваши переводы строк полностью игнорируются. HTTP использует длину содержимого (и некоторые другие приемы, которые не всегда могут быть определены) для отправки «сообщений» по одному потоку tcp / ip, которые могут закрываться или не закрываться при полной отправке сообщения.

...