How to create multiple pages on the server with socket? - android

while(isRunning == true) {
if (SSocket != null) {
try {
Socket socket = SSocket.accept();
PrintStream PStream = new PrintStream(socket.getOutputStream());
BufferedReader BReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String info = null;
while ((info = BReader.readLine()) != null) {
System.out.println("now got " + info);
if (info.equals("")) {
break;
}
}
String content = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Main></Main>";
PStream.println("HTTP/1.0 200 OK");
PStream.println("Content-Type: text/xml");
PStream.println("Content-Length: " + content.length());
PStream.println("");
PStream.println(content);
PStream.close();
BReader.close();
socket.close();
Thread.sleep(10);
} catch (Exception e) {
}
}
}
This code makes the server display a xml, but when I go to another page (e.g. http://10.0.0.101:39878/otherpage.html), the content is the same. How do I do to change the contents of each page and enter a 404 when it does not exist?

You have to parse the client's request to find out which page is being requested, and then send the appropriate content. The code you showed is not doing any parsing at all. In fact, it is not even reading the client's full request to begin with, only the first line of it, which is not enough. You need to read RFC 2616, which defines the HTTP protocol. And then consider NOT implementing an HTTP server manually, but use a pre-made library instead. See How to create a HTTP server in Android? for some suggestions.

Related

post android simple app

I need a simple androd application, which POST a word to the server and recive the answer from server. I creat a form, which have two line and one button. In first line user write the word and click the button. In this time the app send this word to the server. When server send back response we show this respons in other line.
I right some code but this code don`t work on android 23. I also try to do this with retrofit, but I have varios problem with understending of this fiture.
I know that just need use POST, but don`t know how.
And can I send the ip adress of my android to the server?
Try this code:
It will also return the response from that page as a String
public static String postRequest(String post_url, String data) {
try {
URL url = new URL(post_url);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
BufferedReader br;
StringBuilder sb = new StringBuilder();
String line;
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setReadTimeout(10000);
Writer writer = new OutputStreamWriter(connection.getOutputStream());
writer.write(data);
writer.flush();
writer.close();
if (200 <= connection.getResponseCode() && connection.getResponseCode() <= 299) {
br = new BufferedReader(new InputStreamReader((connection.getInputStream())));
} else {
br = new BufferedReader(new InputStreamReader((connection.getErrorStream())));
}
while ((line = br.readLine()) != null) {
sb.append(line);
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
And call it by:
postRequest("http://your-url", "name=value&anothername=somevalue");
I think volley will fit your needs, it's a very simple library that can handle asynchronous requests :
https://developer.android.com/training/volley/index.html
"And can I send the ip adress of my android to the server?"
Sure, to get your android ip just use a code like this on server side, assuming you're using PHP :
<?
$ip = $_SERVER["REMOTE_ADDR"];
echo "<br />Your IP is : $ip";
?>
EDIT : NodsJS example
app.post('/getip', function (req, res) {
var ip = req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress;
})

URLConnection - Cannot write request body after response has been read [duplicate]

I'm writing a program that connects to a servlet thanks to a HttpURLConnection but I stuck while checking the url
public void connect (String method) throws Exception {
server = (HttpURLConnection) url.openConnection ();
server.setDoInput (true);
server.setDoOutput (true);
server.setUseCaches (false);
server.setRequestMethod (method);
server.setRequestProperty ("Content-Type", "application / xml");
server.connect ();
/*if (server.getResponseCode () == 200)
{
System.out.println ("Connection OK at the url:" + url);
System.out.println ("------------------------------------------- ------- ");
}
else
System.out.println ("Connection failed");
}*/
I got the error :
java.net.ProtocolException: Cannot write output after reading input.
if i check the url with the code in comments but it work perfectly without it
unfortunately, I need to check the url so i think the problem comes from the getResponseCode method but i don t know how to resolve it
Thank you very much
The HTTP protocol is based on a request-response pattern: you send your request first and the server responds. Once the server responded, you can't send any more content, it wouldn't make sense. (How could the server give you a response code before it knows what is it you're trying to send?)
So when you call server.getResponseCode(), you effectively tell the server that your request has finished and it can process it. If you want to send more data, you have to start a new request.
Looking at your code you want to check whether the connection itself was successful, but there's no need for that: if the connection isn't successful, an Exception is thrown by server.connect(). But the outcome of a connection attempt isn't the same as the HTTP response code, which always comes after the server processed all your input.
I think the exception is not due toprinting url. There should some piece of code which is trying to write to set the request body after the response is read.
This exception will occur if you are trying to get HttpURLConnection.getOutputStream() after obtaining HttpURLConnection.getInputStream()
Here is the implentation of sun.net.www.protocol.http.HttpURLConnection.getOutputStream:
public synchronized OutputStream getOutputStream() throws IOException {
try {
if (!doOutput) {
throw new ProtocolException("cannot write to a URLConnection"
+ " if doOutput=false - call setDoOutput(true)");
}
if (method.equals("GET")) {
method = "POST"; // Backward compatibility
}
if (!"POST".equals(method) && !"PUT".equals(method) &&
"http".equals(url.getProtocol())) {
throw new ProtocolException("HTTP method " + method +
" doesn't support output");
}
// if there's already an input stream open, throw an exception
if (inputStream != null) {
throw new ProtocolException("Cannot write output after reading
input.");
}
if (!checkReuseConnection())
connect();
/* REMIND: This exists to fix the HttpsURLConnection subclass.
* Hotjava needs to run on JDK.FCS. Do proper fix in subclass
* for . and remove this.
*/
if (streaming() && strOutputStream == null) {
writeRequests();
}
ps = (PrintStream)http.getOutputStream();
if (streaming()) {
if (strOutputStream == null) {
if (fixedContentLength != -) {
strOutputStream =
new StreamingOutputStream (ps, fixedContentLength);
} else if (chunkLength != -) {
strOutputStream = new StreamingOutputStream(
new ChunkedOutputStream (ps, chunkLength), -);
}
}
return strOutputStream;
} else {
if (poster == null) {
poster = new PosterOutputStream();
}
return poster;
}
} catch (RuntimeException e) {
disconnectInternal();
throw e;
} catch (IOException e) {
disconnectInternal();
throw e;
}
}
I have this problem too, what surprises me is that the error is caused by my added code System.out.println(conn.getHeaderFields());
Below is my code:
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
configureConnection(conn);
//System.out.println(conn.getHeaderFields()); //if i comment this code,everything is ok, if not the 'Cannot write output after reading input' error happens
conn.connect();
OutputStream os = conn.getOutputStream();
os.write(paramsContent.getBytes());
os.flush();
os.close();
I had the same problem.
The solution for the problem is that you need to use the sequence
openConnection -> getOutputStream -> write -> getInputStream -> read
That means..:
public String sendReceive(String url, String toSend) {
URL url = new URL(url);
URLConnection conn = url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.sets...
OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
out.write(toSend);
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String receive = "";
do {
String line = in.readLine();
if (line == null)
break;
receive += line;
} while (true);
in.close();
return receive;
}
String results1 = sendReceive("site.com/update.php", params1);
String results2 = sendReceive("site.com/update.php", params2);
...

HTTPResponseCache stores but never hits

I'm working on a application in Android which has a heavy load of web service requests.
I already have a LoginActivity in which the user introduces the username and the password and the server responses with the result and a token. Then, several activities (all of them extend from a common BaseActivity) do the heavy requests.
I have also a ServiceManager class which is responsible for all the service requests and HTTP petitions.
I'm working on implementing the HttpResponseCache to relieve this net load. Right now I have the following code:
In my LoginActivity's (the first being launched) onCreate:
//HTTP cache
try {
File httpCacheDir = new File(this.getCacheDir(), "http");
long httpCacheSize = 10 * 1024 * 1024; //10 MiB
HttpResponseCache.install(httpCacheDir, httpCacheSize);
Log.d(TAG, "Cache installed");
} catch (IOException e) {
Log.i(TAG, "HTTP response cache installation failed:" + e);
}
In my ServiceManager's httpRequest function, which is the one actually being executed every time I try to make an HTTP request:
//HTTPS connection
URL requestedUrl = new URL(uri);
httpsConnection = (HttpURLConnection) requestedUrl.openConnection();
httpsConnection.setUseCaches(true);
httpsConnection.setDefaultUseCaches(true);
httpsConnection.setRequestMethod("GET");
BufferedReader br = new BufferedReader(
new InputStreamReader(httpsConnection.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
httpResponse += line;
}
br.close();
httpsConnection.disconnect();
HttpResponseCache cache = HttpResponseCache.getInstalled();
Log.d(TAG, "Cache: " + cache);
if (cache != null) {
Log.d(TAG, "Net count: " + cache.getNetworkCount());
Log.d(TAG, "Hit count: " + cache.getHitCount());
Log.d(TAG, "Request count: " + cache.getRequestCount());
cache.flush();
}
try{
URI uriCached = new URI("<myurl>");
CacheResponse cr = cache.get(uriCached, "GET", null);
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(cr.getBody()));
while ((line = br.readLine()) != null) {
Log.d(TAG, line);
}
} catch (URISyntaxException e1) {
e1.printStackTrace();
} catch (IOException e2) {
e2.printStackTrace();
}
Right now, since the server side is not ready, the URL I'm doing the requests to is always the same.
As you can see, I'm debugging a few things, these are the results:
Cache installed
Cache: android.net.http.HttpResponseCache#b3e3b6
Net count: X
Hit count: 0
Request count: X
{myJson}
As you can see, the cache is able to read my JSON when I get it via the cache.get() method, but it's never hitting.
My server side directive Cache-Control in the header of the response is:
Cache-Control:public
Cache-Control:max-age=3800
Why is the cache never hitting?
Thank you very much!
I found the problem.
I was trying to cache petitions to a PHP that returns JSON. PHP is always considered as dynamic content (and it actually is), and it's never cached.
The path to follow when trying to cache JSON y application-side only and not server-side. This way, it won't event make a request.
Best.
EDIT
Best solution for this kind of trouble is, undoubtedly, to use Volley

How to handle huge data response from server in android

I am using eclipse ADT for my android development. let me explain my problem. I can receive the response from my server api, the problem is, the data is very huge and am unable to display entire response in my logcat. I used AsynTask for getting response.
DoinBackground method
getBookingResults = ServerConnection.getbookings(
BookingsActivity.this, Utils.URL + "users/"
+ "123145/" + "subscribed");
This is my Get() in separate class
public static String getData(Context ctx, String uri) {
BufferedReader reader = null;
StringBuilder sb = null;
try {
Log.d("Serverconnection URL ", uri);
URL url = new URL(uri);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(200000);
// save status code
Utils.statusCode = con.getResponseCode();
// String responseBody = EntityUtils.toString(response.getEntity());
sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
Log.d("server connection getData", "" + sb.toString());
return sb.toString();
} catch (SocketTimeoutException e) {
Log.d("server connection getData Error ", "" + e);
} catch (IOException e) {
e.printStackTrace();
return " ";
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
return " ";
}
}
}
return sb.toString();
}
When i am checking the response string in my logcat is shows string length 11743. The logcat is not displaying entire response
Help me out to handle huge data response
Thanks in advance
Thing is that you cannot blindly allocate all the data from server otherwise risk of OOM is very high. You should use technique similar to what android suggests with list, keep in memory only those elements visible to user. In other words, first you have to figure out what the size is or expect that size may be huge. Then load data chunk by chunk to some UI element and implement some kind of "load by scroll". In case you cannot load from the net as you scroll, perhaps due to nature of the connection, then you should load chunk by chunk and save the data to local store. And then display it chunk by chunk as described above. This is how I would do it. Sorry, not exactly the answer you look for.

Handling HTTP Get/ Delete Android using REST

I m implementing a REST based HTTP server in Android. The server responds for GET, DELETE and POST requests. Two android devices communicate using HTTP Post (I m using a service, where a device keeps listening on a port and post to next device and this keeps going on).
I m testing the GET and DELETE using Mozilla Poster. Should I add a separate socket/port to handle the same? Because when I try now, sometimes I get timeout error or no response found. However, I am able to see server response in Logcat window. Please help me.
Code to handle GET request:
if(method.equals("GET"))
{
if(checkFileExisting())
{
BufferedReader reader = new BufferedReader(new FileReader(new File(getFilesDir()+File.separator+"script.json")));
String read;
StringBuilder builder = new StringBuilder("");
while((read = reader.readLine()) != null)
{
builder.append(read);
}
String JSONContents = builder.toString();
reader.close();
JSONObject jsonObject;
try {
jsonObject = new JSONObject(JSONContents);
String name = jsonObject.getString("name");
JSONObject stateObject = jsonObject.getJSONObject("state");
String stateValue = stateObject.getString("value");
if(name.equals(target))
{
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK");
response.setEntity(new StringEntity("State is:" + stateValue));
conn.sendResponseHeader(response);
conn.sendResponseEntity(response);
}
else
{
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 404, "Not Found");
response.setEntity(new StringEntity("The requested resource " + target + " could not be found due to mismatch!!"));
conn.sendResponseHeader(response);
conn.sendResponseEntity(response);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
else
{
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, 404, "Not Found");
response.setEntity(new StringEntity("The requested resource " + target + " could not be found!!"));
conn.sendResponseHeader(response);
conn.sendResponseEntity(response);
}
}
The link http://www.integratingstuff.com/2011/10/24/adding-a-webserver-to-an-android-app/ has a very good example. I missed conn.close() in my code.

Categories

Resources