UDP multi-clients - java
At the moment I have a Java UDP server working on Android, the server has a datagramSocket on port which it first just listens for a client to connect, a client will create a new datagramSocket on the same port, and send a packet over asking to connect, once the server receives this, it takes the IP uses to send the message, and then just sends a message pack with a position of a block, while the client also sends back it's own position of a block,
Information, the application allows multiple users to connect to one host, this host will take in all the positions from the clients and then broadcast them out, there are other ways to do it, but I want to do it this way for research.
But anyways down to the question, My application will hopefully handle 8 users, as this application works for wifihotspot. how would i go about allowing multiple clients to connect, send data and receive data? I have the code already to allow one client to connect, and the host will send out data to that client, but if I try to connect another client i get an error, Here is my code for the server and the client
P.S. there maybe some debugging code in there as I need to clear that out.
Server code
package com.example.gelorph_v1;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
import org.apache.http.conn.util.InetAddressUtils;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
public class gameServer extends Thread {
/**
* Sets up a server for Android applciation
*/
private static final String TAG = "GameServer";
private DatagramSocket socket;
private int port = 50000;
private int players = 0;
private ArrayList<gameObject> assets = new ArrayList();
private ArrayList<InetAddress> address = new ArrayList();
private boolean wait = false;
private Context contextHolder = null;
//Make an array, this array will hold all the positions
//the clients sent to it,
//using the ID number, it will store it in a array block
//and the "host" can just return it and use that
public gameServer( Context context ) throws IOException
{
contextHolder = context;
socket = new DatagramSocket( port );
Log.d(TAG, "Server was setup");
}
public DatagramSocket rtnSocket(){ return socket; }
private String getLocalIPAddress()
{
try
{
for (Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces(); nis.hasMoreElements();)
{
NetworkInterface ni = nis.nextElement();
Log.v(TAG, "NetworkInterface = " + ni.getDisplayName());
for (Enumeration<InetAddress> ips = ni.getInetAddresses(); ips.hasMoreElements();)
{
InetAddress ip = ips.nextElement();
String s = ip.getHostAddress();
Log.v(TAG, "InetAddress = " + s);
if (!ip.isLoopbackAddress())
{
if(InetAddressUtils.isIPv4Address(s)) return s;
}
}
}
}
catch (SocketException e)
{
Log.e(TAG,"getLocalIPAddress()", e);
}
return null;
}
public void passClient( gameObject clientTemp )
{
assets.add( clientTemp );
}
protected void doInBackground()
{
}
#Override
public void run() {
InetAddress client = null;
boolean run = true;
String data = "";
DatagramPacket packet = null;
while( run )
{
if( data.equalsIgnoreCase( "" ) )
{
/*Log.d(TAG, "waiting for clients");
String msg = "waiting";
int msgLength = msg.length();
byte[] message = msg.getBytes();
DatagramPacket p = new DatagramPacket( message, msgLength, client, port );
try
{
socket.send( p );
}
catch (IOException e2)
{
Log.d(TAG, "Error with sending");
e2.printStackTrace();
}*/
}
//Send some data
if( data.equalsIgnoreCase( "connect" ) && wait == true )
{
Log.d(TAG, "ID send :" + packet.getAddress());
address.add( packet.getAddress() );
players += 1;
String msg = String.valueOf( players );
int msgLength = msg.length();
byte[] message = msg.getBytes();
DatagramPacket p = new DatagramPacket( message, msgLength, packet.getAddress(), port );
try
{
socket.send( p );
wait = false;
}
catch (IOException e2)
{
Log.d(TAG, "Error with sending");
e2.printStackTrace();
data = "";
}
}
//if( /*data.equalsIgnoreCase( "position" )*/ address.size() > 0 )
//{
//Create for loop to create the string
String msg = "";
msg = players + "#";
for(int i = 0; i < players; i++)
{
msg += + i + ":" + assets.get(i).returnPosX() + ":" + assets.get(i).returnPosY() + ":";
}
//msg = String.valueOf(
// players + ":" +
// "1:" + assets.get(0).returnPosX() + ":" + assets.get(0).returnPosY() );
int msgLength = msg.length();
byte[] message = msg.getBytes();
for(int i = 0; i < address.size() ; i++)
{
DatagramPacket p = new DatagramPacket( message, msgLength, address.get(i), port );
try
{
socket.send( p );
}
catch (IOException e2)
{
Log.d(TAG, "Error with sending");
e2.printStackTrace();
}
}
//Log.d(TAG, "Data sent is:" + msg);
//}
data = " ";
//Receive some data
if( wait == false )
{
byte[] buf = new byte[256];
packet = new DatagramPacket( buf, buf.length );
try
{
socket.receive( packet );
wait = true;
}
catch (IOException e)
{
Log.d(TAG, "Error with receiving data");
e.printStackTrace();
}
data = new String( buf, 0, packet.getLength() );
Log.d(TAG, "Data received from :" + packet.getAddress() + ", holds this value: " + data);
//Upset each asset with the data sent
}
//Log.d(TAG, "Data received was :" + data);
try
{
this.sleep( 25 );
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
Log.d(TAG, "Error with trying to sleep");
e.printStackTrace();
}
}
Log.d(TAG, "Error with while run value");
}
public int returnPlayers(){ return players; }
}
Client code
package com.example.gelorph_v1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.net.DhcpInfo;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.util.Log;
public class gameClient extends Thread {
private static final String TAG = "gameClient";
private gameServer server;
private boolean rdyForPlay = false;
private gameObject[] assets = new gameObject[8];
private int ID = 0;
private int port = 50000;
private InetAddress address;
private maths cal = new maths();
private Context contextHolder;
private boolean host = false;
private DatagramSocket socket = null;
private int totalPlayers = 0;
public gameClient( boolean serverTag, Context context )
{
if( serverTag == true)
{
host = true;
try
{
contextHolder = context;
server = new gameServer( contextHolder );
this.start();
}
catch (IOException e)
{
Log.d(TAG, "Could not start server");
e.printStackTrace();
}
}
else
{
contextHolder = context;
connectToServer();
this.start();
}
}
public void connectToServer()
{
//Send a connect message to the server
try {
socket = new DatagramSocket( port );
byte[] bufer = new byte[256];
String msg = "connect";
int msgLength = msg.length();
bufer = msg.getBytes();
InetAddress address;
address = InetAddress.getByName("192.168.1.59");
DatagramPacket p = new DatagramPacket( bufer, bufer.length , address, port );
socket.send( p );
} catch (UnknownHostException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Receive the message back
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket( buf, buf.length );
try
{
socket.receive( packet );
}
catch (IOException e)
{
Log.d(TAG, "Error with receiving data");
e.printStackTrace();
}
String data = new String( buf, 0, packet.getLength() );
ID = Integer.parseInt( data );
setUpClient();
Log.d(TAG, "Data received was :" + ID);
}
public void setUpClient()
{
gameObject temp = new gameObject(BitmapFactory.decodeResource(contextHolder.getResources(), R.drawable.player), 250, 300);
assets[ID] = temp;
if( host == true )
{
server.passClient( temp );
}
}
public void sendTouchEvent(float xSet, float ySet)
{
assets[ID].setPosition( xSet, ySet );
}
#Override
public void run()
{
if( host == true ) { setUpClient(); server.start(); }
rdyForPlay = true;
boolean run = true;
boolean setupPlayer = false;
while( run )
{
//Tell the server to give position of players
//if( setupPlayer == true )
//{
// setUpClient();
// setupPlayer = false;
//}
if( host == false )
{
try {
if(socket == null)
{
socket = new DatagramSocket( port );
}
byte[] bufer = new byte[256];
//String msg = "position";
String msg = ID +":"+ assets[ID].returnPosX() +":"+ assets[ID].returnPosY();
int msgLength = msg.length();
bufer = msg.getBytes();
InetAddress address;
address = InetAddress.getByName("192.168.1.59");
DatagramPacket p = new DatagramPacket( bufer, bufer.length , address, port );
socket.send( p );
} catch (UnknownHostException e2) {
// TODO Auto-generated catch block
Log.d(TAG, "Error with unknown host");
e2.printStackTrace();
} catch (SocketException e) {
// TODO Auto-generated catch block
Log.d(TAG, "Error with socket");
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
Log.d(TAG, "Error with sending/receiving data");
e.printStackTrace();
}
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket( buf, buf.length );
try
{
socket.receive( packet );
}
catch (IOException e)
{
Log.d(TAG, "Error with receiving data");
e.printStackTrace();
}
String data = new String( buf, 0, packet.getLength() );
//Split the string up
String[] dataArray = data.split("#");
int newTotalPlayers = Integer.parseInt( dataArray[0] );
if( newTotalPlayers != totalPlayers )
{
Log.d(TAG," what is total amount of players:" + newTotalPlayers);
if( newTotalPlayers == 1 )
{
newPlayer( 0 );
totalPlayers = newTotalPlayers;
}
else
{
newPlayer( newTotalPlayers );
totalPlayers = newTotalPlayers;
}
//if( ID == 0 && host == false)
//{
// ID = newTotalPlayers;
// setupPlayer = true;
//}
}
//Do a for loop to go through dataArray
for( int i = 0; i < totalPlayers; i++)
{
String[] pos = dataArray[(i + 1)].split(":");
if( Integer.parseInt( pos[(i*3)] ) == ID )
{
Log.d(TAG, "Do nothing please");
}
else
{
assets[i].setPosition( Integer.parseInt( pos[(i*3) + 1] ), Integer.parseInt( pos[(i*3) + 2] ) );
}
}
}
//host
if( host == true )
{
/*if( server.returnPlayers() != totalPlayers )
{
Log.d(TAG," what is total amount of players:" + server.returnPlayers());
newPlayer( server.returnPlayers() );
totalPlayers = server.returnPlayers();
//if( ID == 0 && host == false)
//{
// ID = newTotalPlayers;
// setupPlayer = true;
//}
}*/
}
}
Log.d(TAG, "Error with run value");
}
private void newPlayer( int idOfNewPlayer )
{
gameObject temp = new gameObject(BitmapFactory.decodeResource(contextHolder.getResources(), R.drawable.new_player), 250, 300);
assets[ idOfNewPlayer ] = temp;
}
private void updateAssets()
{
}
public gameObject[] rtnAssets(){ return assets; }
public int rtnID(){ return ID; }
public boolean rtnRdy(){ return rdyForPlay; }
public gameServer rtnServer(){ return server; }
public boolean rtnHost(){ return host; }
public void stopServers()
{
socket.close();
server.rtnSocket().close();
}
}
Don't worry to much about a new block being created when a client joins and what not, I'm just trying to work out what is the best way to allow multiple users? and most importantly how? If anyone could point me in the right direction, or give some simple example code that would be great.
Related
Application becomes irresponsive on InputStream.read();
When the code reaches the InputStream.read(), the application becomes iresponsive. I think maybe that is the case because the client code runs before the server code and it waits for the input. Here is the server code When login button is clicked then the case is "Send login details"(It sends the login details to the client) and if the id and password is correct then the case becomes**"Login successful". It is sending correct value in **output.readUTF(); public void doWork(String line) { Connection conn = Main.getConnection(); switch (line) { case "Send login details": Main main = new Main(); String details = main.giveLoginDetails(); String id = " "; String password = " "; int i = 0; while (details.charAt(i) != ' ') { id = id + details.charAt(i); i++; } try { id = id.trim(); password = details.substring(i + 1); System.out.println(id + " " + password); output.writeUTF(id + " " + password); } catch (IOException e) { e.printStackTrace(); }break; case "Login successful": String getDet1 = "SELECT * FROM $t;"; if(su == 1) getDet1 = getDet1.replace("$t", "Post1"); else getDet1 = getDet1.replace("$t", "Post"+(su*10+1)); System.out.print(getDet1); rs2 = stmt2.executeQuery(getDet1); String d; int dd; for (int x = 0; x < ch; x++) { rs2.next(); d = rs2.getString(2); output.writeUTF(d); System.out.println(d); dd = rs2.getInt(3); output.writeInt(dd); System.out.println(dd); d = rs2.getString(4); output.writeUTF(d); System.out.println(d); d = rs2.getString(5); // if(d == null) { // output.writeUTF("null"); // System.out.println("null"); // } // else output.writeUTF(d); // System.out.println(d+"not null ");} } } catch (SQLException | IOException e) { e.printStackTrace(); } break; } } Client code:- Another scene after the login scene. It is the Initialize method of Initializable interface. Here i am reading the output but it hangs. #Override public void initialize(URL arg0, ResourceBundle arg1) { String posts = ""; int ch = 0; Main m = new Main(); Stage stage = m.getStage(); stage.setResizable(true); int c = 0; try { posts = Networking.input.readUTF(); ch = Networking.input.readInt(); } catch (IOException e) { e.printStackTrace(); } int rs = Integer.valueOf(posts); for(int k = 0; k<rs; k++) { c++; } try { Networking.input.readUTF(); } catch (IOException e) { e.printStackTrace(); } String det = ""; int cl; for (int i = 0; i < ch; i++) { a[i].setDisable(false); a[i].setOpacity(1); try { Networking.output.writeUTF("send voting details"); det = Networking.input.readUTF(); System.out.println(det); cl = Networking.input.readInt(); System.out.println(cl); det = Networking.input.readUTF(); System.out.println(det); det = Networking.input.readUTF(); System.out.println(det); } catch (IOException exx) { exx.printStackTrace(); } } } Add: Here is my Networking class package sample; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class Networking { public static ServerSocket serverSocket= null; public static void connect(int port) { try { serverSocket = new ServerSocket(port); System.out.print("Server is started"); while (true) { Socket socket = null; try { socket = serverSocket.accept(); DataInputStream input = new DataInputStream(socket.getInputStream()); DataOutputStream output = new DataOutputStream(socket.getOutputStream()); Thread thread = new ServerThread(socket, input, output); thread.start(); System.out.print("Client Accepted"); } catch (IOException e) { e.printStackTrace(); } } } catch(IOException exception) { exception.printStackTrace(); } } }
SocketTimeoutException in android when trying video streaming
I am trying to make a video streaming application between pc and android device. so I am getting this error "SocketTimeoutException" private class ChatOperator extends AsyncTask<Void, Void, Void> { DatagramPacket rcvdp; DatagramSocket RTPsocket; int RTP_RCV_PORT = 25000; Timer timer; byte[] buf; final static int INIT = 0; final static int READY = 1; final static int PLAYING = 2; int state; Socket RTSPsocket; BufferedReader RTSPBufferedReader; BufferedWriter RTSPBufferedWriter; String VideoFileName; int RTSPSeqNb = 0; int RTSPid = 0; final static String CRLF = "\r\n"; int MJPEG_TYPE = 26; #Override protected Void doInBackground(Void... params) { buf = new byte[15000]; int RTSP_server_port = 4444; String ServerHost = "10.0.3.2"; try { InetAddress ServerIPAddr = InetAddress.getByName(ServerHost); VideoFileName = "media/movie.Mjpeg"; RTSPsocket = new Socket(ServerIPAddr, 4444); RTSPBufferedReader = new BufferedReader(new InputStreamReader( RTSPsocket.getInputStream())); RTSPBufferedWriter = new BufferedWriter(new OutputStreamWriter( RTSPsocket.getOutputStream())); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println(e.toString()); } try { RTPsocket = new DatagramSocket(RTP_RCV_PORT); RTPsocket.setSoTimeout(5); } catch (SocketException se) { System.out.println("Socket exception: " + se); System.exit(0); } RTSPSeqNb = 1; send_RTSP_request("SETUP"); if (parse_server_response() != 200) System.out.println("Invalid Server Response"); else { state = READY; System.out.println("New RTSP state: READY"); } System.out.println("Play Button pressed !"); RTSPSeqNb++; send_RTSP_request("PLAY"); if (parse_server_response() != 200) System.out.println("Invalid Server Response"); else { state = PLAYING; System.out.println("New RTSP state: PLAYING"); new java.util.Timer().scheduleAtFixedRate(new TimerTask() { #Override public void run() { rcvdp = new DatagramPacket(buf, buf.length); try { RTPsocket.receive(rcvdp); RTPpacket rtp_packet = new RTPpacket(rcvdp.getData(), rcvdp.getLength()); System.out.println("Got RTP packet with SeqNum # " + rtp_packet.getsequencenumber() + " TimeStamp " + rtp_packet.gettimestamp() + " ms, of type " + rtp_packet.getpayloadtype()); rtp_packet.printheader(); int payload_length = rtp_packet.getpayload_length(); byte[] payload = new byte[payload_length]; rtp_packet.getpayload(payload); bmp = BitmapFactory.decodeByteArray(payload,0,payload_length); System.out.print("a packet recieved"); } catch (IOException e) { //e.printStackTrace(); System.out.println("Nothing Recieved"); } } }, 0, 200); } return null; } private int parse_server_response() { int reply_code = 0; try { String StatusLine = RTSPBufferedReader.readLine(); StringTokenizer tokens = new StringTokenizer(StatusLine); tokens.nextToken(); reply_code = Integer.parseInt(tokens.nextToken()); if (reply_code == 200) { String SeqNumLine = RTSPBufferedReader.readLine(); String SessionLine = RTSPBufferedReader.readLine(); tokens = new StringTokenizer(SessionLine); tokens.nextToken(); RTSPid = Integer.parseInt(tokens.nextToken()); } } catch (Exception ex) { } return (reply_code); } private void send_RTSP_request(String request_type) { try { RTSPBufferedWriter.write(request_type + " " + VideoFileName + " " + "RTSP/1.0" + CRLF); RTSPBufferedWriter.write("CSeq: " + RTSPSeqNb + CRLF); if (request_type.equals("SETUP")) { RTSPBufferedWriter.write("Transport: RTP/UDP; client_port= " + RTP_RCV_PORT + CRLF); } else { RTSPBufferedWriter.write("Session: " + RTSPid + CRLF); } RTSPBufferedWriter.flush(); } catch (Exception ex) { } } } the error is made by this line of code in the timer object RTPsocket.receive(rcvdp); I am wondering the same code works well at java SE . but in android it sends request to the server to run and stop but I cannot receive packets like in java SE . Thanks.
is.readUTF() not recieving message
For the chat program in android side I am sending message via DataInput stream as Socket sck = new Socket(); sck.connect(new InetAddress("192.168.1.91",1500),2000); if(sck.isConnected()) { DataOutputStream os = new DataOutputStream(sck.getOutputStream()); os.writeUTf(msg); System.out.println("Message sent"); } and on the Server side My code is ServerSocket serv = new ServerSocket(1500); Socket sock = serv.accept(); DataInputStream is = new DataInputStream(sock.getInputStream); String ans = is.readUTF(); System.out.println("Got"+ans); But on server side it seems it does not received anything and still waiting for the message. But on client side It shows message sent. Here is my full code. package in.prasilabs.eagleeye; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; public class EagleClient extends Thread { public int ret = 0; private String ip; private int port; private Socket sck; private boolean estb = false; private DataInputStream is; private DataOutputStream os; private String rmsg = null; private String msg; private String username; private String password; public String reply; Data dt = new Data(); public EagleClient() { } public EagleClient(String ip, int port, String username, String password) { this.ip = ip; this.port = port; this.username = username; this.password = password; } public void run() { establish(); if(estb == true) { sendInfo(username,password); } } public void establish() { int time_out = 2000; try { System.out.println("trying to connect"); sck = new Socket(); sck.connect(new InetSocketAddress(dt.getIp(),dt.getServerPort()),time_out); estb = true; System.out.println("Established"); } catch (UnknownHostException e) { ret =0; e.printStackTrace(); } catch (IOException e) { ret = 0; // TODO Auto-generated catch block e.printStackTrace(); } if(estb == true) { try { is = new DataInputStream(sck.getInputStream()); os = new DataOutputStream(sck.getOutputStream()); dt.setOS(os); dt.setIS(is); System.out.println("Messages are ready to send"); } catch (IOException e) { ret = 0; // TODO Auto-generated catch block e.printStackTrace(); } } } public void sendInfo(String user,String password) { Data dt = new Data(); is = dt.getIS(); os = dt.getOS(); String drport = Integer.toString(dt.getdrPort()); try { os.writeUTF("logn"); System.out.println("Sending user info"); os.writeUTF(dt.getUsername()); os.writeUTF(dt.getPassword()); os.writeUTF(drport); reply = is.readUTF(); if(reply.equals("success")) dt.setLoginStatus(true); else dt.setLoginStatus(false); System.out.println("ACk recieved"); } catch (IOException e) { ret = 0; // TODO Auto-generated catch block e.printStackTrace(); } } public int sendMessage(String msg) { Data dt = new Data(); os = dt.getOS(); is = dt.getIS(); this.msg = msg; try { os.writeUTF(msg); System.out.println("Client :" +msg); recieveMessage(); } catch (IOException e) { ret = 0; // TODO Auto-generated catch block e.printStackTrace(); } return ret; } public void recieveMessage() { try { System.out.println("Trying to get acknowledgement"); sck.setSoTimeout(2000); rmsg = is.readUTF(); if(rmsg.equals(msg)) { System.out.println("Ack recvd" +rmsg); ret = 1; } else if(!msg.equalsIgnoreCase(rmsg)) { //sendMessage(); Thread.sleep(100); System.out.println("Retrying"); rmsg = is.readUTF(); System.out.println("Ack recvd" +rmsg); ret = 1; } else { System.out.println("Message not recieved"); ret = 0; } } catch (IOException e) { ret = 0; // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e){ e.printStackTrace(); } } }
Try to use something like this: String message = ""; while (!"end".equals(message)) { if (is.available() != 0) { message = dis.readUTF(); System.out.println(message); } } I checked this - working. Server must be up before client will send message.
Partial download nightmare in Java
Here is my complete code that I use to download files from the internet in my Android app. The idea is to resume the download from where it left off when the app restarts / is restored. package com.example.simpledownloader.task; import java.io.BufferedInputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.concurrent.atomic.AtomicLong; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Environment; import android.util.Log; import com.example.simpledownloader.sharable.NetworkOptions; import com.example.simpledownloader.sharable.Sharable; public class Task extends Thread { private String url = null; private String name = null; private AtomicLong contentLength = null; private AtomicLong bytesWritten = null; private boolean isReady = true; private String errCode = new String("OK"); //------------------------------------------------------------------------------ public Task(String name, String url, long contentLength, long bytesWritten){ // Instantiate the variables // The values here depend on whether the Task was created by TaskDAO // or by clicking the download button this.name = name; this.url = url; this.contentLength = new AtomicLong(contentLength); this.bytesWritten = new AtomicLong(bytesWritten); } //------------------------------------------------------------------------------ #Override public void run() { File f = null; RandomAccessFile rFile = null; setReadiness(false); Sharable.setShouldLook(false); try { String[] names = name.split("/"); if(names.length == 0){ // nothing }else{ name = names[names.length-1]; } Log.v("TASKPATH", "/sdcard/" + name); f = new File("/sdcard/",name); rFile = new RandomAccessFile(f, "rw"); writeToFile(rFile); } catch (FileNotFoundException e) { Log.v("TASK", e.getLocalizedMessage()); if(contentLength.get() == 0){ // new download will have content length set to zero try { f.createNewFile(); // make a new file writeToFile(rFile);// start downloading }catch (IOException e1) { errCode = e1.getMessage(); // Unable to create file; Log.v("TASK", "FILE DELETED"); Sharable.setShouldLook(true); return; } }else{ errCode = "Created file has been deleted"; // File was previously created but now is not found. Log.v("TASK", "FILE DELETED"); Sharable.setShouldLook(true); return; } } catch (IOException e) { errCode = e.getLocalizedMessage(); Sharable.setShouldLook(true); Log.v("TASK", e.getLocalizedMessage()); } } //------------------------------------------------------------------------------ private void writeToFile(RandomAccessFile file){ NetworkInfo wifi = Sharable.connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI); NetworkInfo mobile = Sharable.connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); URL u; HttpURLConnection httpCon = null; try { byte[] buffer = new byte[2 * 1024]; // 2 MB buffer long bytesWritten = 0; if(contentLength.get() == 0){ // new file ? u = new URL(url); // make a URL httpCon = (HttpURLConnection) u.openConnection(); // Get ready to make a connection via HTTP httpCon.setDoInput(true); // this connection will download data httpCon.connect(); // make a connection BufferedInputStream buf = new BufferedInputStream(httpCon.getInputStream()); // get a stream contentLength.addAndGet(httpCon.getContentLength()); // set content length while((bytesWritten = buf.read(buffer)) != -1 ){ if(Sharable.networkOption == NetworkOptions.WIFI_ONLY){ if(!wifi.isConnected()){ // check WiFi connectivity setReadiness(false); Sharable.setShouldLook(true); break; } } Log.v("TASK", "Writing at location " + this.bytesWritten.get()); file.write(buffer); this.bytesWritten.addAndGet(bytesWritten); String update = "UPDATE tasks SET byteswritten=" + this.bytesWritten.get() + " ,contentlength=" + this.contentLength.get() + " WHERE url='" + url + "'"; Sharable.db.execSQL(update); // write data to database Sharable.handler.post(new Runnable(){ #Override public void run() { Sharable.adapter.notifyDataSetChanged(); // update the display } }); if(isInterrupted()){ setReadiness(true); Sharable.setShouldLook(true); break; } } }else{ // not a new file file.seek(this.bytesWritten.get()); // seek to proper position u = new URL(url); // make a URL httpCon = (HttpURLConnection) u.openConnection(); // Get ready to make a connection via HTTP httpCon.setDoInput(true); // this connection will download data httpCon.setRequestProperty("Range:", "bytes="+this.bytesWritten.get()+"-"); httpCon.connect(); // make a connection if(httpCon.getResponseCode() != HttpURLConnection.HTTP_PARTIAL){ // check if partial download supported errCode = "206 Not Supported"; setReadiness(false); Sharable.setShouldLook(true); return; } BufferedInputStream buf = new BufferedInputStream(httpCon.getInputStream()); // get a stream while((bytesWritten = buf.read(buffer)) != -1 ){ // start downlading if(Sharable.networkOption == NetworkOptions.WIFI_ONLY){ if(!wifi.isConnected()){ // check WiFi connectivity setReadiness(false); Sharable.setShouldLook(true); if(httpCon != null){ httpCon.disconnect(); } break; } } Log.v("TASK", "Writing at location " + this.bytesWritten.get()); file.write(buffer); this.bytesWritten.addAndGet(bytesWritten); String update = "UPDATE tasks SET byteswritten=" + this.bytesWritten.get() + " ,contentlength=" + this.contentLength.get() + " WHERE url='" + url + "'"; Sharable.db.execSQL(update); // write data to database Sharable.handler.post(new Runnable(){ #Override public void run() { Sharable.adapter.notifyDataSetChanged(); // update the display } }); if(isInterrupted()){ // check for thread interruption setReadiness(true); Sharable.setShouldLook(true); break; } } } } catch (MalformedURLException e) { errCode = e.getMessage(); Log.v("TASK", e.getLocalizedMessage()); } catch (IOException e) { errCode = e.getLocalizedMessage(); Log.v("TASK", e.getLocalizedMessage()); }catch(Exception e){ errCode = e.getLocalizedMessage(); Log.v("TASK", e.getLocalizedMessage()); } } //------------------------------------------------------------------------------ public synchronized float getProgress(){ if(contentLength.get() != -1 && contentLength.get() != 0){ return (bytesWritten.get()*100)/contentLength.get(); }else{ return -1; } } //------------------------------------------------------------------------------ public synchronized boolean getReadiness(){ return isReady; } //------------------------------------------------------------------------------ public synchronized void setReadiness(boolean ready){ isReady = ready; } //------------------------------------------------------------------------------ public synchronized String getStatus(){ return errCode; } //------------------------------------------------------------------------------ public synchronized String getTaskName(){ return name; } //------------------------------------------------------------------------------ #Override public String toString(){ return name; } //------------------------------------------------------------------------------ } The problem, however, is that the partial download never starts... I do not know why. I usually end up with no activity at all or with a 206 Not Supported error. Other class that might interest you is the Sharable which contains singleton instances: Sharable.java and Scheduler.java How do I resume partial downloads ?
Android webserver shows html pages as text
I am developing a android app which turns the android device into a multithreaded web server the code which i use do not have any error but runs fine and it can be seen through web browser but it shows the source of html file as text rather than full gui. this is my code.. Jhtts class: package dolphin.developers.com; import java.io.File; import java.io.IOException; import java.net.InetAddress; import android.app.Activity; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.widget.Toast; import dolphin.devlopers.com.R; public class JHTTS extends Activity { #Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.server); try { String IndexFileName = "index.htm"; File documentRootDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/"); JHTTP j = new JHTTP(documentRootDirectory, 9001, IndexFileName); j.start(); Toast.makeText(getApplicationContext(), "Server Started!!", 5).show(); Log.d("Server Rooot", "" + documentRootDirectory); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } Jhttp class: package dolphin.developers.com; import java.io.File; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; public class JHTTP extends Thread { private File documentRootDirectory; private String indexFileName = "index.htm"; private ServerSocket server; private int numThreads = 50; public JHTTP(File documentRootDirectory, int port, String indexFileName) throws IOException { if (!documentRootDirectory.isDirectory()) { throw new IOException(documentRootDirectory + " does not exist as a directory"); } this.documentRootDirectory = documentRootDirectory; this.indexFileName = indexFileName; this.server = new ServerSocket(port); } public JHTTP(File documentRootDirectory, int port) throws IOException { this(documentRootDirectory, port, "index.htm"); } public JHTTP(File documentRootDirectory) throws IOException { this(documentRootDirectory, 9001, "index.htm"); } public void run() { for (int i = 0; i < numThreads; i++) { Thread t = new Thread(new RequestProcessor(documentRootDirectory, indexFileName)); t.start(); } System.out.println("Accepting connections on port " + server.getLocalPort()); System.out.println("Document Root: " + documentRootDirectory); while (true) { try { Socket request = server.accept(); request.setReuseAddress(true); RequestProcessor.processRequest(request); } catch (SocketException ex) { } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } RequestProcessor: package dolphin.developers.com; import java.net.*; import java.io.*; import java.util.*; public class RequestProcessor implements Runnable { #SuppressWarnings("rawtypes") private static List pool = new LinkedList( ); private File documentRootDirectory; private String indexFileName = "index.html"; public RequestProcessor(File documentRootDirectory, String indexFileName) { if (documentRootDirectory.isFile( )) { throw new IllegalArgumentException( "documentRootDirectory must be a directory, not a file"); } this.documentRootDirectory = documentRootDirectory; try { this.documentRootDirectory = documentRootDirectory.getCanonicalFile( ); } catch (IOException ex) { } if (indexFileName != null) this.indexFileName = indexFileName; } #SuppressWarnings("unchecked") public static void processRequest(Socket request) { synchronized (pool) { pool.add(pool.size( ), request); pool.notifyAll( ); } } public void run( ) { // for security checks String root = documentRootDirectory.getPath( ); while (true) { Socket connection; synchronized (pool) { while (pool.isEmpty( )) { try { pool.wait( ); } catch (InterruptedException ex) { } } connection = (Socket) pool.remove(0); } try { String filename; String contentType; OutputStream raw = new BufferedOutputStream( connection.getOutputStream( ) ); Writer out = new OutputStreamWriter(raw); Reader in = new InputStreamReader( new BufferedInputStream( connection.getInputStream( ) ),"ASCII" ); StringBuffer requestLine = new StringBuffer( ); int c; while (true) { c = in.read( ); if (c == '\r' || c == '\n') break; requestLine.append((char) c); } String get = requestLine.toString( ); // log the request System.out.println(get); StringTokenizer st = new StringTokenizer(get); String method = st.nextToken( ); String version = ""; if (method.equals("GET")) { filename = st.nextToken( ); if (filename.endsWith("/")) filename += indexFileName; contentType = guessContentTypeFromName(filename); if (st.hasMoreTokens( )) { version = st.nextToken( ); } File theFile = new File(documentRootDirectory, filename.substring(1,filename.length( ))); if (theFile.canRead( ) // Don't let clients outside the document root && theFile.getCanonicalPath( ).startsWith(root)) { DataInputStream fis = new DataInputStream( new BufferedInputStream( new FileInputStream(theFile) ) ); byte[] theData = new byte[(int) theFile.length( )]; fis.readFully(theData); fis.close( ); if (version.startsWith("HTTP ")) { // send a MIME header out.write("HTTP/1.0 200 OK\r\n"); Date now = new Date( ); out.write("Date: " + now + "\r\n"); out.write("Server: JHTTP/1.0\r\n"); out.write("Content-length: " + theData.length + "\r\n"); out.write("Content-type: " + contentType + "\r\n\r\n"); out.flush( ); } // end if // send the file; it may be an image or other binary data // so use the underlying output stream // instead of the writer raw.write(theData); raw.flush( ); } // end if else { // can't find the file if (version.startsWith("HTTP ")) { // send a MIME header out.write("HTTP/1.0 404 File Not Found\r\n"); Date now = new Date( ); out.write("Date: " + now + "\r\n"); out.write("Server: JHTTP/1.0\r\n"); out.write("Content-type: text/html\r\n\r\n"); } out.write("<HTML>\r\n"); out.write("<HEAD><TITLE>File Not Found</TITLE>\r\n"); out.write("</HEAD>\r\n"); out.write("<BODY>"); out.write("<H1>HTTP Error 404: File Not Found</H1>\r\n"); out.write("</BODY></HTML>\r\n"); out.flush( ); } } else { // method does not equal "GET" if (version.startsWith("HTTP ")) { // send a MIME header out.write("HTTP/1.0 501 Not Implemented\r\n"); Date now = new Date( ); out.write("Date: " + now + "\r\n"); out.write("Server: JHTTP 1.0\r\n"); out.write("Content-type: text/html\r\n\r\n"); } out.write("<HTML>\r\n"); out.write("<HEAD><TITLE>Not Implemented</TITLE>\r\n"); out.write("</HEAD>\r\n"); out.write("<BODY>"); out.write("<H1>HTTP Error 501: Not Implemented</H1>\r\n"); out.write("</BODY></HTML>\r\n"); out.flush( ); } } catch (IOException ex) { } finally { try { connection.close( ); } catch (IOException ex) {} } } // end while } // end run public static String guessContentTypeFromName(String name) { if (name.endsWith(".html") || name.endsWith(".htm")) { return "text/html"; } else if (name.endsWith(".txt") || name.endsWith(".java")) { return "text/plain"; } else if (name.endsWith(".gif")) { return "image/gif"; } else if (name.endsWith(".class")) { return "application/octet-stream"; } else if (name.endsWith(".jpg") || name.endsWith(".jpeg")) { return "image/jpeg"; } else if (name.endsWith(".png") ) { return "image/png"; } else if (name.endsWith(".js")) { return "text/javascript"; } else if (name.endsWith(".js")) { return "text/javascript"; } else if (name.endsWith(".css")) { return "text/css"; } else return "text/plain"; } } // end RequestProcessor Please Help...