Проблема с сокетом - readline не будет работать должным образом - PullRequest
1 голос
/ 16 декабря 2010

Я пытаюсь закодировать соединение клиента и сервера, используя сокет.Проблема в том, что мой клиент не может прочитать ответ с сервера (он зависает на readline).

Вот часть кода.

Сервер:

    try {
        // Create the server socket.
        portNumber = Integer.parseInt(myParam.get("socket.portNumber"));
        System.out.println(portNumber);
        mainSocket = new ServerSocket(portNumber);

    } catch (IOException ioe) {
        System.out.println("Error Message : "+ioe.getMessage());
    }

    while(true)
    {     
        try
        {
            // Accept connections
            Socket clientSocket = mainSocket.accept();
            SocketServerThread st = new SocketServerThread (clientSocket);
            st.start();
        }
        catch(IOException ioe)
        {
            System.out.println("Error message :"+ioe.getMessage());
        }
    }

Тема:

public void run() {

    BufferedReader in = null;
    PrintWriter out = null;
    String clientResponse = null;

    try {
        in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

        //Read The Message
        String clientRequest = in.readLine();
        System.out.println("Message recieved : " + clientRequest);

        //Process the message

        // Send response
        out.println(clientResponse+"\n");
        out.flush();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // Clean up
        try {
            in.close();
            out.close();
            clientSocket.close();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

Клиент:

    try {
        // Create the server socket.
        simSocket = new Socket("192.168.52.27", portNumber);
    } catch (IOException ioe) {
        System.out.println("Error Message : " + ioe.getMessage());
    }
    BufferedReader in = null;
    PrintWriter out = null;
    try {
        in = new BufferedReader(new InputStreamReader(simSocket.getInputStream()));
        out = new PrintWriter(new OutputStreamWriter(simSocket.getOutputStream()));

            out.write("My message");
            out.flush();

            do{
            response = in.readLine(); //This is where the code hang
            }while (response.length()<= 0);

            System.out.print(response);

    } catch (IOException ioe) {
        System.out.println("Error message :" + ioe.getMessage());
    } finally {
        try {
            in.close();
            out.close();
            simSocket.close();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
    }

Не могли бы вы, ребята, сказать мне, в чем проблема?Большое спасибо за любую помощь

Ответы [ 5 ]

8 голосов
/ 16 декабря 2010

Хорошо, я понял это.Это не клиент, который висит, это сервер.Он пытается прочитать строку текста с клиента, но клиент не отправляет разделитель строк:

    out.write("My message");
    out.flush();

Замените write () на println () здесь.

2 голосов
/ 16 декабря 2010

ОК, я сделал несколько изменений в коде, и теперь он работает хорошо:

Сервер:

    try {
        // Create the server socket.
        portNumber = Integer.parseInt(myParam.get("socket.portNumber"));
        mainSocket = new ServerSocket(portNumber);

    } catch (IOException ioe) {
        System.out.println("Error Message : " + ioe.getMessage());
    }

    // Accept connections    
    try {
        clientSocket = mainSocket.accept();
    } catch (IOException ioe) {
        System.out.println("Error Message : " + ioe.getMessage());
    }
    BufferedReader in = null;
    PrintWriter out = null;

    while (true) {
        try {
            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
            //Read The Message
            **StringBuffer buffer = new StringBuffer();
            while (true) {
                int ch = in.read();
                if ((ch < 0) || (ch == '\n')) {
                    break;
                }
                buffer.append((char) ch);
            }
            String clientRequest = buffer.toString();**

            SocketServerThread st = new SocketServerThread(clientRequest, out);
            st.start();
        } catch (IOException ioe) {
            System.out.println("Can't accept connection. Error message :" + ioe.getMessage());
        }
    }

Я изменяю readline на read, и он работает, поэтому предположение, что проблема с \ n, является правильным.

Тема: незначительное изменение в потоке (удалите часть запроса на чтение, так как я уже сделал это на сервере)

Клиент: измените readline на read, как серверный.

Спасибо всем за помощь

0 голосов
/ 17 декабря 2010
out.write("My message");

Это не отправляет терминатор строки, поэтому он никогда не может быть прочитан.Используйте println ().

out.println(clientResponse+"\n");

, который отправит clientResponse плюс символ новой строки плюс \ n.Последняя часть, вероятно, будет интерпретирована как пустая строка.В этом нет особого смысла.Удалите \ n.

do{
    response = in.readLine(); //This is where the code hang
}while (response.length()<= 0);

Это неправильный способ чтения строк.Он получит NPE в EOS;длина ответа никогда не может быть отрицательной;и зачем вы отправляете себе пустые строки?Правильный путь таков:

while ((response = in.readLine()) != null) {
    // if (response.length() == 0) continue; // if you must
    // process the line
}
// when you get here EOS has occurred.
0 голосов
/ 16 декабря 2010

Согласно javaDoc, ответ сервера на самом деле

"My Message:\n"+System.getProperty("line.separator")

Бьюсь об заклад, in.readLine() работает нормально хотя бы один раз - но вы просто игнорируете ответ, потому что команда печати находится вне цикла.Переместите его вверх, и вы должны увидеть ответы на консоли.

Существует (очень маленький) шанс, что серверы println() на самом деле не отправляют символ \n.Так что вы можете попробовать это в коде потока:

 out.print(clientResponse+"\n\n");  // exchanged println with an extra \n char
0 голосов
/ 16 декабря 2010

Может ли это быть из-за того, что clientResponse (отправлено серверным потоком) равно null и клиент ожидает размер ответа> 0?

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