Чтение из сокета - PullRequest
       5

Чтение из сокета

3 голосов
/ 18 августа 2011

У меня проблемы с работой этого простого класса.Он в основном подключается к серверу IMAP и читает баннер.Но после прочтения всех символов, это несколько висит.В отладчике я могу пройти по циклу while и увидеть, что все символы читаются и в конце концов он выходит из циклаНо последний оператор System.out.println никогда не достигается.

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.Socket;


public class TestClient
{

    /**

        @param args

     */
    public static void main( String[] args ) throws Exception
    {

        Socket socket = new Socket( "imap.1and1.com", 143 );

        DataOutputStream os = new DataOutputStream( socket.getOutputStream() );
        BufferedReader reader = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );

        StringBuilder sb = new StringBuilder();
        char ch = (char) reader.read();
        while ( ch != -1 ) {
            sb.append( ch );
            ch = (char) reader.read();

        }

        System.out.println( sb.toString() ); /// <--- never prints anything and program just hangs..
    }

}

Ответы [ 2 ]

2 голосов
/ 18 августа 2011

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

  • либо каким-либо образом отключить соединение после того, как все данные будут прочитаны (для этого вы должны определить, что все данные были прочитаны)

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

Еще одна вещь, поскольку read () блокирует,в ожидании дополнительных данных рекомендуется прочитать в фоновом потоке ..

0 голосов
/ 18 августа 2011

хорошо, это то, что я сделал, чтобы решить мою конкретную проблему.Обратите внимание, что использование методов ready () или available () не всегда надежно.Особенно, если ожидается, что сервер отправит данные, приостановит и затем отправит больше данных.В моем случае это работает, потому что я не ожидаю остановки сервера в середине ответа и повторного запуска.

Код явно не оптимизирован для реального использования.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;

/**
        @author Mir Shafiqul Islam &lt;mislam@mirislam.comt&gt;

 */
public class TestClient
{

    /**

        @param args

     */
    public static void main( String[] args ) throws Exception
    {
        // Open the socket
        Socket socket = new Socket( "localhost", 25143 );
        // Get a buffered reader
        BufferedReader reader = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );
        // At this point it is too early to read. So it most likely return false
        System.out.println( "Buffer Reader ready? " + reader.ready()); 
        // StringBuilder to hold the response
        StringBuilder sb = new StringBuilder();
        // Indicator to show if we have started to receive data or not
        boolean dataStreamStarted = false;
        // How many times we went to sleep waiting for data
        int sleepCounter = 0;
        // How many times (max) we will sleep before bailing out
        int sleepMaxCounter = 50;
        // Sleep max counter after data started
        int sleepMaxDataCounter = 3;
        // How long to sleep for each cycle
        int sleepTime = 50;
        // Start time
        long startTime = System.currentTimeMillis();
        // This is a tight loop. Not sure what it will do to CPU
        while( true ) {
            if ( reader.ready() )
            {
                sb.append( (char) reader.read() );
                // Once started we do not expect server to stop in the middle and restart
                dataStreamStarted = true; 
            } else {
                Thread.sleep( sleepTime );
                if ( dataStreamStarted && (sleepCounter >= sleepMaxDataCounter) ) {
                    System.out.println( "Reached max sleep time of " + (sleepMaxDataCounter*sleepTime) + " ms after data started" );
                    break;
                } else {
                    if (sleepCounter >= sleepMaxCounter) {
                        System.out.println( "Reached max sleep time of " + (sleepMaxCounter*sleepTime) + " ms. Bailing out" );
                        // Reached max timeout waiting for data. Bail..
                        break;
                    }
                }
                sleepCounter++;
            }

        }
        long endTime = System.currentTimeMillis();

        System.out.println( sb.toString() );
        System.out.println( "Time " + (endTime-startTime));
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...