Java服务器在接收HTTP post请求时挂起

时间:2011-03-30 20:55:48

标签: java android client

我正在尝试实现简单的客户端 - 服务器通信。这里我的客户端是一个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 个答案:

答案 0 :(得分:4)

服务器读取直到line == null,这只发生在EOS,这只发生在客户端断开连接时,由于连接保持活动而在HTTP 1.1中延迟。你应该做的是:

(a)读取所有标题,直到获得

(b)找到Content-Length:标题

(c)从输入流中读取许多字节。

这会强制你使用DataInputStream及其弃用的readLine()函数,因为字符不是字节,你的BufferedReader几乎肯定会窃取一些内容字节。

你根本不应该处理这个问题。 Java现在带有一个HTTP服务器框架,您应该真正使用它。或者部署Tomcat或Jetty并编写一个servlet。