HttpConnection sending another request after 30 sec - java

I'm writing one application in which I'm sending post request to server. The problem is that Nokia S40 series phone sends 2 request if it doesn't get response within 30 sec. I have checked the same with s60 series phone in my app is working fine.
One solution I found is to start timer while opening connection and terminate the connection after 25sec if connection not getting response. But it is also worthless. Here I'm attaching my code. Please review it and help me if possible.
try
{
param="function=CloseRecharge&LoginId="+SharedVariable.getUserInfo().getLoginID()
+"&BatchId="+SharedVariable.getSelectedProduct().getBatchID()
+"&SystemServiceID="+SharedVariable.getSelectedProduct().getSystemServiceID()
+"&ReferalNumber="+strMobileNo
+"&FromANI="+fromMoNo
+"&Email="+""
+"&Checksum="+Checksum;
connection = (HttpConnection) Connector.open(url);
timeout=0;
t.schedule(new TimerTask()
{
public void run()
{
try
{
timeout+=1;
System.out.println("Timeout value:"+timeout);
if(timeout>=25)
{
//timeout every 1 munite
timeout=0;
System.out.print("Connection is closing");
connection.close();
connection=null;
if(is!=null)
is.close();
Alert alert=new Alert("HttpConn Closed", "connection closed",null, AlertType.WARNING);
alert.setTimeout(Alert.FOREVER);
display.setCurrent(alert,new MainMenu("Menu", parent));
this.cancel();
}
}
catch(Exception e)
{
System.out.println("========Exception occured in Timer Task");
e.printStackTrace();
}
}
}
, 0, 1000);
connection.setRequestMethod(HttpConnection.POST);
connection.setRequestProperty("User-Agent", "Profile/MIDP-1.0 Configuration/CLDC-1.0");
connection.setRequestProperty("Accept_Language","en-US");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-length", ""+param.getBytes().length);
out = connection.openOutputStream();
out.write(param.getBytes());
out.flush();
param=null;
if (connection.getResponseCode() == HttpConnection.HTTP_OK )
{
t.cancel();
int len = (int)connection.getLength();
InputStream istrm = connection.openInputStream();
if (istrm == null)
{
throw new IOException("Cannot open HTTP InputStream, aborting");
}
if (len != -1)
{
data = new byte[len];
int bytesRead = istrm.read(data);
}
else
{
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int ch;
int count = 0;
while ((ch = istrm.read()) != -1)
{
bo.write(ch);
count++;
}
data = bo.toByteArray();
bo.close();
}
String response = new String(data);
displayResponse();
}//if
else
{
Alert error=new Alert("ResponseCode:"+connection.getResponseCode(),
null,
null,AlertType.INFO);
error.setTimeout(Alert.FOREVER);
display.setCurrent(error,new MainMenu("Menu", parent));
}
catch(Exception exception)
{
displayErrorMessage(exception);
}
finally
{
try
{
if(connection!=null)
connection.close();
if(is!=null)
is.close();
}
catch (IOException ex)
{
System.out.println("Exception in Finally block....");
ex.printStackTrace();
}
}

Related

How to send different data from different threads through the one socket and how to get

The task is to broadcast sound through a socket in one thread and in the other to send a string through the same socket. The result should be read on the client side. All this I do through DataInputStream and DataOutputStream and an array of bytes.
Receiving and transmitting data is normal, if the data is transmitted through a single thread. But if you send a text string during the transmission of the sound streaming, it creates the feeling that the data is mixed in a heap, because the sound rips, and the lines too are not possible to get.
Are there any guesses why this can happen?
This is the little samples of my code:
(Text sending)
public void sendMessage(byte[] msg, int key) {
OutputStream mOutputStream;
try {
Socket socket = getSocket();
if (socket == null) {
Log.d(CLIENT_TAG, "Socket is null, wtf?");
} else if (socket.getOutputStream() == null) {
Log.d(CLIENT_TAG, "Socket output stream is null, wtf?");
}
mOutputStream = getSocket().getOutputStream();
DataOutputStream dos = new DataOutputStream(mOutputStream);
dos.writeUTF("####");
dos.writeInt(key);
dos.writeInt(msg.length);
dos.flush();
dos.write(msg);
dos.flush();
logD("MESSAGE " + msg.length);
} catch (UnknownHostException e) {
Log.d(CLIENT_TAG, "Unknown Host", e);
} catch (IOException e) {
Log.d(CLIENT_TAG, "I/O Exception", e);
} catch (Exception e) {
Log.d(CLIENT_TAG, "Error3", e);
}
Log.d(CLIENT_TAG, "Client sent message: " + msg);
}
(Audio sending)
#Override
public void run() {
audioRecord.startRecording();
byte[] buffer = new byte[recBufSize];
DataOutputStream dataOutputStream = new DataOutputStream(mOutputStream);
if (mOutputStream != null) {
try {
dataOutputStream.writeInt(SOUND_KEY);
dataOutputStream.writeInt(recBufSize);
logD("AUDIO OUT " + buffer.length);
while (isRecording) {
int readSize = audioRecord.read(buffer, 0, recBufSize);
dataOutputStream.writeUTF("####");
dataOutputStream.writeInt(readSize);
dataOutputStream.write(buffer, 0, readSize);
dataOutputStream.flush();
double sum = 0;
for (int i = 0; i < readSize; i++) {
sum += buffer[i] * buffer[i];
}
if (readSize > 0) {
final double amplitude = sum / readSize;
int result = (int) avgQueue(Math.sqrt(amplitude), 10);
if (mSoundControl != null)
mSoundControl.setSoundLevel(result);
logD("AMPLITUDE " + result);
}
}
} catch (Exception e) {
logD(e.getMessage());
}
audioRecord.stop();
}
(Data receiving)
DataInputStream is = new DataInputStream(inStream);
while (!Thread.currentThread().isInterrupted()) {
try {
if (is.readUTF().equals("####")) {
token = is.readInt();
dataKey = token;
switch (token) {
case 0:
break;
case CONTROL_KEY:
readControlMessage(is);
break;
case IMAGE_KEY:
readImageMessage(is);
break;
case SOUND_KEY:
readSoundMessage(is);
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
Please, tell me what is wrong

Java socket can client can not read the data

The client send a message, then the server receives the message and response the message. I don't know why the client can not read the response. If I remove the read part in client, the server can get the message. However for the following code, nothing work. Also I tried the flush(), it still doesn't work.
For client
public void run() {
try (Socket echoSocket = new Socket(HOSTNAME, Integer.parseInt(PORTNUMBER));
DataOutputStream dOut = new DataOutputStream(echoSocket.getOutputStream());
DataInputStream dIn = new DataInputStream(echoSocket.getInputStream());
) {
while (true) {
command = UI.commandQueue.take()
dOut.writeInt(Message.toByteArray(command).length);
dOut.write(Message.toByteArray(command));
int length;
while((length = dIn.readInt()) != 0) {
if (length > 0){
byte[] messagebyte = new byte[length];
dIn.readFully(messagebyte, 0, messagebyte.length);
try {
msg = Message.fromByteArray(messagebyte);
testDisplay(msg);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
testDisplay(msg);
}
}
}
}catch (UnknownHostException e) {
UI.display("Don't know about host " + HOSTNAME);
} catch (IOException e) {
UI.display("Couldn't get I/O for the connection to " + HOSTNAME);
}
}
For server
public void run() {
try (ServerSocket serverSocket = new ServerSocket(Integer.parseInt(PORT_NUMBER));
Socket clientSocket = serverSocket.accept();
DataOutputStream dOut = new DataOutputStream(clientSocket.getOutputStream());
DataInputStream dIn = new DataInputStream(clientSocket.getInputStream());) {
int length;
while ((length = dIn.readInt()) != 0) {
if (length > 0) {
byte[] messagebyte = new byte[length];
dIn.readFully(messagebyte, 0, messagebyte.length); // read the
// message
Message msg;
try {
msg = Message.fromByteArray(messagebyte);
testDisplay(msg);
dOut.writeInt(Message.toByteArray(msg).length);
dOut.write(Message.toByteArray(msg));
UI.display("ack sent");
} catch (Exception e) {
// TODO Auto-generated catch block
UI.display(e.getMessage());
}
}
}
} catch (IOException e) {
UI.display(
"Exception caught when trying to listen on port " + PORT_NUMBER + " or listening for a connection");
UI.display(e.getMessage());
}
}
Your server is echoing one response per request, but your client is trying to read more than one response per request, which it will never get, so it blocks.

Server Application Eats Up CPU After 15 Minutes of Running

I coded a server application that constantly listens to data being sent to it. I took multi-threading into consideration by the way. I have the main thread, writer thread, and reader thread. When I launch the program, everything works perfectly. After about 15 minutes of up-time though, my CPU usage just randomly skyrockets. I believe it reaches about 40% just for the server application if I remember correctly. I think I'm doing something wrong with networking since this is my first time working with sockets.
This is what I use to read data:
public void run(){
Socket s = null;
InputStream in = null;
while (Main.running){
try {
s = network.getServerSocket().accept();
in = s.getInputStream();
} catch (IOException e){
e.printStackTrace();
}
if (in != null){
DataInputStream input = new DataInputStream(in);
try {
while (input.available() != -1) {
byte type = input.readByte();
PacketIn packet = Utils.getPacket(main, type);
packet.readData(input);
if (packet instanceof PacketInLogin) {
PacketInLogin login = (PacketInLogin) packet;
login.setSocket(s);
String server = login.getServer();
Socket socket = login.getSocket();
Main.log("Login request from server: '" + server + "'. Authenticating...");
boolean auth = login.authenticate();
Main.log("Authentication test for server: '" + server + "' = " + (auth ? "PASSED" : "FAILED"));
if (auth) {
main.getServers().put(server, new DataBridgeServer(main, server, socket));
}
main.getTransmitter().sendPacket(new PacketOutAuthResult(main, auth), socket);
} else if (packet instanceof PacketInDisconnect) {
PacketInDisconnect disconnect = (PacketInDisconnect) packet;
main.getServers().remove(disconnect.getServer().getName());
Main.log("'" + disconnect.getServer().getName() + "' has disconnected from network.");
}
}
} catch (IOException e){
if (!(e instanceof EOFException)){
e.printStackTrace();
}
} finally {
if (in != null){
try {
in.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
}
}
try {
if (s != null) s.close();
if (in != null) in.close();
} catch (IOException e){
e.printStackTrace();
}
}
This is what I use to write data (to the client. This code is still part of the server):
public void run(){
while (Main.running){
if (!QUEUED.isEmpty()){
PacketOut packet = (PacketOut) QUEUED.keySet().toArray()[0];
Socket server = QUEUED.get(packet);
DataOutputStream out = null;
try {
out = new DataOutputStream(server.getOutputStream());
packet.send(out);
} catch (IOException e){
e.printStackTrace();
} finally {
if (out != null){
try {
out.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
QUEUED.remove(packet);
}
}
}

Android 2.1 appears to not flush output stream

We are getting some very weird behavior in Android. Our network stack (that talks to a REST server) works fine in almost all situations, except when we do a GET shortly after doing a larger POST. What appears to be happening is that the Output stream is not flushing, and ends up sending the last line that was in there when the new socket is opened. Please note, each connection is a new object created, so this is unexpected behavior. First, the error code that seems to point me to the output stream, these are from the server logs.
10.1.8.195 - - [07/Nov/2012:13:36:28 -0700] "POST /iou/lender HTTP/1.1" 200 28 "-" "Android"
10.1.8.195 - - [07/Nov/2012:13:36:36 -0700] "------------V2ymHFg03ehbqgZCaKO6jy" 400 173 "-" "-"
That attempt after should be a GET that then pulls the data from the server that includes the new entry added via the POST. However, all we get is again what appears to be the last line from the output stream from the POST. Here is our core code for the network stack, if more of the surrounding code is needed, let me know.
public Object serverConnect(String url, String method,
Hashtable<String, Object> params) {
HttpConnection c = null;
InputStream is = null;
OutputStream out = null;
ByteArrayOutputStream postDataByteArrayImage = new ByteArrayOutputStream();
byte[] data;
String boundry = "----------V2ymHFg03ehbqgZCaKO6jy";
try {
if (!url.startsWith("/")) {
url = "/" + url;
}
String uri = Control.URL_Secure + Control.dtserver + ":"
+ Control.port + url;
ByteArrayOutputStream postDataByteArray = new ByteArrayOutputStream();
params.put("sessionId", Control.sessionId);
if (method.equals("GET")) {
uri = uri + "?";
Enumeration enumParams = params.keys();
while (enumParams.hasMoreElements()) {
if (!uri.endsWith("?")) {
uri = uri + "&";
}
String key = (String) enumParams.nextElement();
uri = uri
+ key
+ "="
+ java.net.URLEncoder.encode((String) params
.get(key));
}
} else if (method.equals("POST")) {
Enumeration enumParams = params.keys();
postDataByteArray.write(("--").getBytes());
postDataByteArray.write((boundry).getBytes());
postDataByteArray.write(("\r\n").getBytes());
while (enumParams.hasMoreElements()) {
String key = (String) enumParams.nextElement();
if (!key.equals("image")){
postDataByteArray
.write(("Content-Disposition: form-data; name=\"")
.getBytes());
postDataByteArray.write((key).getBytes());
postDataByteArray.write(("\"").getBytes());
postDataByteArray.write(("\r\n\r\n").getBytes());
postDataByteArray.write(((String) params.get(key))
.getBytes());
postDataByteArray.write(("\r\n").getBytes());
postDataByteArray.write(("--").getBytes());
postDataByteArray.write(boundry.getBytes());
postDataByteArray.write(("\r\n").getBytes());
}
}
postDataByteArray.close();
}
Log.i("URL", uri);
URL urltoConenct = new URL(uri);
URLConnection connection = urltoConenct.openConnection();
HttpURLConnection urlConnection = (HttpURLConnection) connection;
URLConnection.setDefaultRequestProperty("Method", method); // default
urlConnection.setRequestProperty("User-Agent", "Android");
if (method.equals("POST")) {
urlConnection.setDoOutput(true);
urlConnection.setFixedLengthStreamingMode(postDataByteArray.toByteArray().length + postDataByteArrayImage.toByteArray().length);
urlConnection.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + boundry);
out = urlConnection.getOutputStream();
out.write(postDataByteArray.toByteArray());
out.write(postDataByteArrayImage.toByteArray());
out.close();
}
int response = 0;
try {
response = urlConnection.getResponseCode();
} catch (IOException e) {
if (e.toString()
.equals("java.io.IOException: Received authentication challenge is null"))
throw new RESTException(401, "Invalid Phone or Pin");
else
throw e;
}
if (response == HttpURLConnection.HTTP_OK) {
is = urlConnection.getInputStream();
if (is == null) {
return new IOException(
"Cannot open HTTP InputStream, aborting");
}
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int ch;
int count = 0;
while ((ch = is.read()) != -1) {
bo.write(ch);
count++;
}
data = bo.toByteArray();
return new String(data);
} else if (response == 500) {
return new RESTException(500, "Internal server error");
} else {
RESTException x = new RESTException();
x.setCode(response);
try {
is = urlConnection.getInputStream();
if (is == null) {
x.setMessage("Unable to retrieve message");
return x;
}
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int ch;
int count = 0;
while ((ch = is.read()) != -1) {
bo.write(ch);
count++;
}
data = bo.toByteArray();
String output = new String(data);
JSONObject obj;
try {
obj = new JSONObject(output);
JSONObject err = obj.getJSONArray("errors")
.getJSONObject(0);
x.setMessage(err.getString("message"));
} catch (JSONException e) {
Log.e("stuff", output);
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// Damn you android! I'm using a REST service here, stop
// trying to interpret my errors!
x.setMessage("Unable to retrieve message");
}
return x;
}
} catch (Exception x) {
x.printStackTrace();
/*
* if (!retried && x.toString().equals(
* "java.io.IOException: Persistent connection dropped after first chunk sent, cannot retry"
* )) { retry = true; } if (!retry) { return x; }
*/
return x;
} finally {
try {
out.close();
} catch (Exception x) {
}
try {
is.close();
} catch (Exception x) {
}
try {
c.close();
} catch (Exception x) {
}
params.clear();
}
// return null;
}
After a very long time of frustration, we discovered that Android tries to keep a connection alive even if you manually call .close() on the connection. This worked fine for our GET methods, but POST methods left the socket in a state that it couldn't then process a GET. Adding the following fixed all our problems:
urlConnection.setRequestProperty("connection", "close");

how to resume an interrupted download

I'm trying to download a large file from my Yahoo! web site server which apparently is setup (not by me) to disconnect downloads if they are not completed within 100 seconds. The file is small enough to usually successfully transfer. On the occasions when the data rate is slow and the download gets disconnected, is there a way to resume the URLConnection at the file offset where the disconnection occurred? Here's the code:
// Setup connection.
URL url = new URL(strUrl[0]);
URLConnection cx = url.openConnection();
cx.connect();
// Setup streams and buffers.
int lengthFile = cx.getContentLength();
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(strUrl[1]);
byte data[] = new byte[1024];
// Download file.
for (total=0; (count=input.read(data, 0, 1024)) != -1; total+=count) {
publishProgress((int)(total*100/lengthFile));
output.write(data, 0, count);
Log.d("AsyncDownloadFile", "bytes: " + total);
}
// Close streams.
output.flush();
output.close();
input.close();
Try using a "Range" request header:
// Open connection to URL.
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Specify what portion of file to download.
connection.setRequestProperty("Range", "bytes=" + downloaded + "-");
// here "downloaded" is the data length already previously downloaded.
// Connect to server.
connection.connect();
Having done that, you can seek at a given point (just before the length of your download data, say X) and start writing the newly downloaded data there. Be sure to use the same value X for the range header.
Details about 14.35.2 Range Retrieval Requests
More details and source code can be found here
Here's an example code that you can use:
import java.io.*;
import java.net.*;
public class HttpUrlDownload {
public static void main(String[] args) {
String strUrl = "http://VRSDLSCEN001:80//DLS//lib//clics.jar";
String DESTINATION_PATH = "clics.jar";
int count = 0;
while (true) {
count++;
if (download(strUrl, DESTINATION_PATH) == true || count > 20) {
break;
}
}
}
public static boolean download(String strUrl, String DESTINATION_PATH) {
BufferedInputStream in = null;
FileOutputStream fos = null;
BufferedOutputStream bout = null;
URLConnection connection = null;
int downloaded = 0;
try {
System.out.println("mark ... download start");
URL url = new URL(strUrl);
connection = url.openConnection();
File file=new File(DESTINATION_PATH);
if(file.exists()){
downloaded = (int) file.length();
}
if (downloaded == 0) {
connection.connect();
}
else {
connection.setRequestProperty("Range", "bytes=" + downloaded + "-");
connection.connect();
}
try {
in = new BufferedInputStream(connection.getInputStream());
} catch (IOException e) {
int responseCode = 0;
try {
responseCode = ((HttpURLConnection)connection).getResponseCode();
} catch (IOException e1) {
e1.printStackTrace();
}
if (responseCode == 416) {
return true;
} else {
e.printStackTrace();
return false;
}
}
fos=(downloaded==0)? new FileOutputStream(DESTINATION_PATH): new FileOutputStream(DESTINATION_PATH,true);
bout = new BufferedOutputStream(fos, 1024);
byte[] data = new byte[1024];
int x = 0;
while ((x = in.read(data, 0, 1024)) >= 0) {
bout.write(data, 0, x);
}
in.close();
bout.flush();
bout.close();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
}
}
if (bout != null) {
try {
bout.close();
} catch (IOException e) {
}
}
if (connection != null) {
((HttpURLConnection)connection).disconnect();
}
}
}
}

Categories

Resources