Reputation: 2131
I am trying to implement a simple client-server communication. Here my client is an Android device which uses org.apache.http library to send some data using POST method and a java server handles the request.
Client side:
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();
}
}
}
Server side:
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());
}
}
}
However the server side output always hangs just before the post data is shown (but, it outputs the post headers, content-length etc.) - until the connection is reset by client (at this point, the post data is shown in the console). So, post data is already received by server, but somehow doesn't show up. What do you think about this problem?
Upvotes: 1
Views: 2398
Reputation: 310850
The server reads until line == null, which only happens at EOS, which only happens when the client disconnects, which is deferred in HTTP 1.1 because of connection keep-alive. What you should be doing is this:
(a) read all the headers until you get an empty line
(b) find the Content-Length: header
(c) read that many bytes from the input stream.
This will force you into using DataInputStream and its deprecated readLine() function, because chars ain't bytes and your BufferedReader will almost certainly steal some of the content bytes.
You shouldn't be dealing with this issue at all actually. Java comes with an HTTP server framework now, you should really be using that instead. Or deploy Tomcat or Jetty and just write a servlet.
Upvotes: 4