Java-сервер зависает при получении HTTP-запроса - PullRequest
1 голос
/ 31 марта 2011

Я пытаюсь реализовать простое соединение клиент-сервер. Здесь мой клиент - это устройство Android, которое использует библиотеку org.apache.http для отправки некоторых данных методом POST, а java-сервер обрабатывает запрос.

Клиентская сторона:

    public class Client implements LogTag {
        HttpClient client;
        HttpParams params;
        HttpPost post;
        String address = "example.com";

        public Client() {
             client = new DefaultHttpClient();
             post = new HttpPost(address);
        }

        public void postData(String data) {
            try {
                Log.i(TAG, "Sending...: " + data);
                List<NameValuePair> pairs = new ArrayList<NameValuePair>();
                pairs.add(new BasicNameValuePair("data", data));
                Log.i(TAG, "This is the data: " + pairs.get(0));

                AbstractHttpEntity ent = new UrlEncodedFormEntity(pairs, HTTP.UTF_8);       
                post.setEntity(ent);
                //post.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);

                HttpResponse response = client.execute(post);
                if (response != null) {
                    String responseBody = EntityUtils.toString(response.getEntity());
                    Log.i(TAG, "Server response: " + responseBody);
                }
            } catch (UnsupportedEncodingException e1) {
                e1.printStackTrace();
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            //} catch (URISyntaxException e) {
            //  e.printStackTrace();
            }
        }

    }

Серверная сторона:

public class Server extends Thread {
    private Socket clientSocket;
    private BufferedReader fromClient;
    private DataOutputStream toClient;

    Server(Socket socket) {
        this.clientSocket = socket;
    }

    public static void main (String args[]) throws Exception {
        ServerSocket serverSocket = new ServerSocket (
            8888, 10, InetAddress.getByName("example.com"));
        System.out.println("Server started running on [" + 
            serverSocket.getInetAddress() + ":" + serverSocket.getLocalPort() + "] @ " + getNow());

        while(true) {
            Socket connected = serverSocket.accept();
            Server pts = new Server(connected);
            pts.start();
        }
    }

    public void run() {
        String line = null;
        String contentLength = null;
        String clientInfo = null;
        try {   
            clientInfo = clientSocket.getInetAddress() + ":" + clientSocket.getPort();
            System.out.println("---------------------");
            System.out.println("Client [" + clientInfo + "] is connected @ " + getNow());

            fromClient = new BufferedReader(
                    new InputStreamReader(clientSocket.getInputStream()));
            toClient = new DataOutputStream(clientSocket.getOutputStream());

            line = fromClient.readLine();
            String header = line;
            System.out.println(header);
            StringTokenizer tokenizer = new StringTokenizer(header);
            String httpMethod = tokenizer.nextToken();

            if (httpMethod.equals("POST")) {
                while ((line = fromClient.readLine()) != null) {
                    System.out.println("line: " + line);
                }
            } else {
                System.out.println("Received something-else-request.");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println(clientInfo + " logout @ " + getNow());
        }
    }
}

Однако вывод на стороне сервера всегда зависает непосредственно перед отображением данных публикации (но он выводит заголовки сообщений, длину содержимого и т. Д.) - до тех пор, пока клиент не сбросит соединение (в этот момент данные сообщений отображаются в консоли). Итак, почтовые данные уже получены сервером, но почему-то не отображаются. Что вы думаете об этой проблеме?

1 Ответ

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

Сервер читает до строки == null, что происходит только в EOS, что происходит только при отключении клиента, что отложено в HTTP 1.1 из-за поддержания соединения. Что вы должны делать, это:

(a) читайте все заголовки, пока не получите пустую строку

(b) найдите Content-Length: header

(c) прочитать столько байтов из входного потока.

Это заставит вас использовать DataInputStream и его устаревшую функцию readLine (), потому что символы не являются байтами, и ваш BufferedReader почти наверняка украдет некоторые байты содержимого.

Вы вообще не должны заниматься этой проблемой. Java теперь поставляется с HTTP-фреймворком, вы должны использовать его вместо этого. Или разверните Tomcat или Jetty и просто напишите сервлет.

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