I'm transferring Byte arrays of different kinds of files(.png, .txt, etc..) My socket starts sending the data and client starts receiving it. For some reason .pngs doesen't look same as they do on the server side. (Sometimes it says image is unreadable, sometimes only some parts of image are shown.. etc)? I'm wondering how could I make it so that the sent data would actually be the same as the sent data? Any suggestions what I'm doing wrong? (Note! If .png file has alpha channel, image seems always to be completely unreadable.)
Client side of the data transfer:
try
{
sInput = new ObjectInputStream(socket.getInputStream());
Input = socket.getInputStream();
}
catch (IOException eIO) {
System.out.println("Exception creating new Input/output Streams: " + eIO);
return false;
}
.
.
.
LoadCache[] filedata = (LoadCache[]) sInput.readObject(); //This contains the path and size of file
while(number < filedata.length){
byte[] mybytearray = new byte[(int) LoadCache.getSize(filedata[number])];
String result = Reader.UpdateCache(LoadCache.getPath(filedata[number]));
number++;
if(result != "skip" && result != "Stop"){
BufferedOutputStream Bos = new BufferedOutputStream(new FileOutputStream(result));
int BytesRead = Input.read(mybytearray, 0, mybytearray.length);
Bos.write(mybytearray, 0, BytesRead);
Bos.close();
}
}
Server side of the data transfer:
Socket socket;
ObjectInputStream sInput;
ObjectOutputStream sOutput;
OutputStream Output;
BufferedInputStream buffIn;
.
.
.
try{
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
Output = socket.getOutputStream();
} catch (Exception e){
System.out.println("Couldn't create Input/Output streams");
}
.
.
.
File[] Data = Reader.getFiles(Action.getString(Incomingdata.getAction(datain)));
LoadCache LoadedCache[] = new LoadCache[Data.length];
for(int i = 0; i<Data.length; i++){
Path filePath = Paths.get(Data[i].getPath());
Path relativePath = base.relativize(filePath); //= filePath - base (so to say)
LoadedCache[i] = new LoadCache(relativePath.toString(), Data[i].length());
}
System.out.println(LoadedCache.length);
try {
sOutput.writeObject(LoadedCache);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for(File file : Data){
try {
if(file.isFile()){
byte[] bytearray = new byte[(int) file.length()];
buffIn = new BufferedInputStream(new FileInputStream(file));
buffIn.read(bytearray, 0, bytearray.length);
Output.write(bytearray, 0, bytearray.length);
Output.flush();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
buffIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Also! Now (I'm not quite sure anymore if I got this earlier) Client gives me java.util.zip.ZipException: incorrect header check -Exception (And none of the files is zipped)
Something Runnable:
Public class Client {
private ObjectInputStream sInput; // to read from the socket
private static ObjectOutputStream sOutput; // to write on the socket
private static Socket socket;
public static Client client;
public static Player player;
public static boolean loadingFiles;
String server;
int port;
boolean connected;
Client(String server, int port) {
this.server = server;
this.port = port;
this.connected = true;
}
public static boolean isConnected(Client client){
return client.connected;
}
private void disconnect() {
try {
if(sInput != null) sInput.close();
}
catch(Exception e) {} // not much else I can do
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {} // not much else I can do
try{
if(socket != null) socket.close();
}
catch(Exception e) {} // not much else I can do
}
public boolean start() {
// try to connect to the server
try {
socket = new Socket(server, port);
}
// if it failed we catch the exception
catch(Exception ec) {
System.out.println("Error connecting to server: " + ec);
return false;
}
System.out.println("Connection accepted " + socket.getInetAddress() + ":" + socket.getPort());
/* Creating Data Streams */
try
{
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
}
catch (IOException eIO) {
System.out.println("Exception creating streams: " + eIO);
return false;
}
// creates the Thread to listen from the server
new ListenFromServer().start();
String Cache;
if(Reader.ReadCache(Frame.drive +"//FM_Cache/version") == "WeHadToMakeNewFile"){ //If we don't have that file. We create it, but now it's empty.
Cache = "New";
}
else{ //If we do have cache and it has "version" we send our version to server.
Cache = Reader.ReadCache(Frame.drive +"FM_Cache/version");
}
send(new Incomingdata("", "", new Action(0, Cache, 0, 0)));
// success we inform the caller that it worked
return true;
}
public static void Connect() {
// default values
int portNumber = 16304;
String serverAddress = "0.0.0.0"; //I'm using my own ip here..
// create the Client object
client = new Client(serverAddress, portNumber);
// test if we can start the connection to the Server
if(client.start()){
client.connected = true;
}
}
public static void Disconnect(Client client) {
client.connected = false;
client.disconnect();
}
class ListenFromServer extends Thread {
public void run() {
loadingFiles = true;
while(true) {
try {
int number = 0;
LoadCache[] filedata = (LoadCache[]) sInput.readObject();
while(number < filedata.length){
byte[] mybytearray = new byte[(int) LoadCache.getSize(filedata[number])];
String result = Reader.UpdateCache(LoadCache.getPath(filedata[number]));
number++;
if(result != "skip" && result != "Stop"){
BufferedOutputStream Bos = new BufferedOutputStream(new FileOutputStream(result));
int BytesRead = sInput.read(mybytearray, 0, mybytearray.length);
Bos.write(mybytearray, 0, BytesRead);
Bos.close();
}
}
System.out.println("Cache has been patched succesfully!");
Client.loadingFiles = false;
}catch(EOFException e){
System.out.println("Problem reading the data streams! " +e);
break;
}
catch(IOException e) {
System.out.println(e);
break;
}
catch(ClassNotFoundException e2) {
}
}
}
}
public static void send(Incomingdata incomingdata) {
try {
sOutput.writeObject(incomingdata);
}
catch(IOException e) {
System.out.println("Exception writing to server: " + e);
}
}
}
Incomingdata:
package com.connection;
import com.connection.Action;
public class Incomingdata implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = -1309997274550304156L;
private String Username, Password;
private Action action;
public Incomingdata(String Username, String Password, Action action){
this.Username = Username;
this.action = action;
this.Password = Password;
}
public static String getUsername(Incomingdata Incomingdata){
return Incomingdata.Username;
}
public static String getPassword(Incomingdata Incomingdata){
return Incomingdata.Password;
}
public static Action getAction(Incomingdata Incomingdata){
return Incomingdata.action;
}
}
LoadingCache:
package com.connection;
import java.io.Serializable;
public class LoadCache implements Serializable{
/**
*
*/
private static final long serialVersionUID = 7267682639705707967L;
String path;
long size;
public LoadCache(String path, long size){
this.path = path;
this.size = size;
}
public static long getSize(LoadCache cache) {
return cache.size;
}
public static String getPath(LoadCache filedata) {
return filedata.path;
}
}
Action.java:
package com.connection;
import com.connection.Action;
public class Action implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 4389420849399916526L;
int type, x, y;
String string;
public Action(int type, String string, int x, int y){
this.type = type;
this.string = string;
this.x = x;
this.y = y;
}
public static int getType(Action action) {
return action.type;
}
public static String getString(Action action) {
return action.string;
}
public static int getX(Action action) {
return action.x;
}
public static int getY(Action action) {
return action.y;
}
}
And Reader for Client. This should be the last class you need to run the client.
package com.game.loader;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import com.connection.Client;
import com.game.Frame;
import com.game.menu.GameMenu;
public class Reader {
public static String ReadCache(String string) {
int CurrentLine = 0;
String returnement = "";
try {
BufferedReader Reader = new BufferedReader(new FileReader(new File(string)));
for(String line = Reader.readLine(); line != null; line = Reader.readLine()){
if(CurrentLine == 0){
returnement = line;
}
CurrentLine++;
}
} catch (FileNotFoundException e) {
new File(Frame.drive +"//FM_Cache").mkdirs();
return "WeHadToMakeNewFile";
} catch (IOException e) {
e.printStackTrace();
}
return returnement;
}
public static String UpdateCache(String path) {
String[] pieces = path.split("/");
String returnement = "skip";
System.out.println(Frame.drive + "//FM_Cache/" + path);
if(new File(Frame.drive +"//FM_Cache/" +path).exists()){
returnement = (Frame.drive +"//FM_Cache/" +path);
}
else{ //If file doesen't exit we make one and parent folders.
File file = new File(Frame.drive +"//FM_Cache/" +path);
file.getParentFile().mkdirs();
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
returnement = (Frame.drive +"//FM_Cache/" +path);
}
return returnement;
}
}
Runnable server:
package com.server;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.ServerSocket;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import org.apache.commons.io.IOUtils;
import com.connection.Action;
import com.connection.Incomingdata;
import com.connection.LoadCache;
import com.game.loader.Reader;
import com.game.player.Player;
public class Server {
//Every connection got their own unique id
private static int uniqueId;
//List all the clients
private static ArrayList<ClientThread> al;
private static boolean running = false;
#SuppressWarnings("unused")
private SimpleDateFormat sdf;
final Path base = Paths.get("Data", "Cache");
public Server(int port) {
sdf = new SimpleDateFormat("HH:mm:ss");
al = new ArrayList<ClientThread>();
}
public void start() {
running = true;
try {
//Server socket
ServerSocket serverSocket = new ServerSocket(Screen.portnumber);
System.out.println("Server is running and waiting for Clients to connect.");
while(running){
Socket socket = serverSocket.accept();
if(!running){ //this will make server running stop.
System.out.println("Closing the server..");
break;
}
ClientThread t = new ClientThread(socket);
al.add(t); //saving new client to our arraylist.
t.run();
}
try{
serverSocket.close();
for(int i = 0; i< al.size(); i++){//We forget about all the clients.
//Maybe also save all the data here?
ClientThread tc = al.get(i);
try{
tc.sInput.close();
tc.sOutput.close();
tc.socket.close();
}
catch(IOException ioE){}
}
} catch(Exception e){e.printStackTrace();}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void close() {
running = false;
try {
new Socket("localhost", Screen.portnumber);
} catch (Exception e) { System.out.println("Can't disconnect.."); }
}
synchronized void remove(int id) {
// scan the array list until we find the Id
for(int i = 0; i < al.size(); ++i) {
ClientThread ct = al.get(i);
// found it
if(ct.id == id) {
al.remove(i);
return;
}
}
}
public static boolean isRunning(){
return running;
}
class ClientThread extends Thread {
//The socket where to listen/talk
Socket socket;
ObjectInputStream sInput;
ObjectOutputStream sOutput;
BufferedInputStream buffIn;
//my unique id (easier for deconnection)
int id;
//Objects that we will be receiving
Incomingdata datain;
//the date we connect
String date;
Player player;
boolean Connected = false;
//Constructor
ClientThread(Socket socket){
id = uniqueId++;
this.socket = socket;
try{
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
} catch (Exception e){
System.out.println("Couldn't create Input/Output streams");
}
date = new Date().toString();
}
// what will run forever
public void run() {
// to loop until LOGOUT
Connected = true;
while(Connected) {
try {
datain = (Incomingdata) sInput.readObject();
}
catch (IOException e) {
System.out.println("Exception reading Streams: " + e);
break;
}
catch(ClassNotFoundException e2) {
break;
}
if(!Incomingdata.getUsername(datain).isEmpty()){
switch(Action.getType(Incomingdata.getAction(datain))) { //CHANGE!!
case 0://Log in/off
System.out.println(Incomingdata.getUsername(datain) +", " +Incomingdata.getPassword(datain) + " trying to connect.");
if(Player.getPassword(Reader.ReadPlayerData("Data/Players/" +Incomingdata.getUsername(datain) +".txt")) == Incomingdata.getPassword(datain)){
player = Reader.ReadPlayerData("Data/Players/" +Incomingdata.getUsername(datain) +".txt");
System.out.println(Player.getUsername(player) +"Just connected!");
Player.isOnline(player);
}
break;
case 1://Talk
System.out.println(Incomingdata.getUsername(datain) + ": " +Action.getString(Incomingdata.getAction(datain)));
break;
case 2://Move
break;
}
}
else if(Action.getString(Incomingdata.getAction(datain)) != null){
File[] Data = Reader.getFiles(Action.getString(Incomingdata.getAction(datain)));
LoadCache LoadedCache[] = new LoadCache[Data.length];
for(int i = 0; i<Data.length; i++){
Path filePath = Paths.get(Data[i].getPath());
Path relativePath = base.relativize(filePath); //= filePath - base (so to say)
LoadedCache[i] = new LoadCache(relativePath.toString(), Data[i].length());
}
System.out.println(LoadedCache.length);
try {
sOutput.writeObject(LoadedCache);
sOutput.flush();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for(File file : Data){
try {
if(file.isFile()){
byte[] bytearray = new byte[(int) file.length()];
buffIn = new BufferedInputStream(new FileInputStream(file));
buffIn.read(bytearray, 0, bytearray.length);
sOutput.write(bytearray, 0, bytearray.length);
sOutput.flush();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
buffIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Cache updated!");
}
}
// remove myself from the arrayList containing the list of the
System.out.println(Player.getUsername(player) +", " +Player.getPassword(player) +" disconnected.");
remove(id);
close();
}
// try to close everything
private void close() {
// try to close the connection
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {}
try {
if(sInput != null) sInput.close();
}
catch(Exception e) {};
try {
if(socket != null) socket.close();
}
catch (Exception e) {}
}
}
}
Reader.java for server:
package com.game.loader;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import org.apache.commons.io.filefilter.FileFileFilter;
import com.game.player.CharacterClass;
import com.game.player.Equipment;
import com.game.player.Friends;
import com.game.player.Inventory;
import com.game.player.Orbs;
import com.game.player.Player;
import com.game.player.Quest;
import com.game.world.Tile;
public class Reader {
public static Player temporary;
static int stage = 0;
private static int count = 0;
private static int totalfolders = 0;
private static File[] files = new File[NumberOfFiles("Data/Cache/")];
public static Player ReadPlayerData(String string) {
Player player = null;
int CurrentLine = 0;
String[] All = new String[100]; //This may need to be extended.
try {
BufferedReader Reader = new BufferedReader(new FileReader(new File(string)));
for(String line = Reader.readLine(); line != null; line = Reader.readLine()){
All[CurrentLine] = line;
CurrentLine++;
}
} catch (FileNotFoundException e) {
System.out.println("Someone is trying to log in using wrong username.");
} catch (IOException e) {
e.printStackTrace();
}
player = new Player(string, All[0], new Tile(Integer.parseInt(All[1].split(", ")[0]), Integer.parseInt(All[1].split(", ")[1]), Integer.parseInt(All[1].split(", ")[2])),
Integer.parseInt(All[2]), Integer.parseInt(All[3]), Integer.parseInt(All[4]), new CharacterClass(All[5]), new Orbs(All[6].split(", ")), null, new Inventory(All[8].split(", ")),
null, new Equipment(All[10].split(", ")), new Friends(All[11].split(", ")), /* All[12] = guild,*/ Integer.parseInt(All[13]), true, false, null, null, Integer.parseInt(All[18]), /*All[19] = StartDate,*/ All[20]);
temporary = player;
return player;
}
public static boolean CacheReader(String string) {
File[] all = new File(string).listFiles(); //We list all the files from path
int folders = 0;
for(int i = 0; i < all.length; i++){
if(!all[i].isDirectory()) { //folders are not added to this list. :)
System.out.println("((i = " +i +") - (folders = " +folders +")) + (stage = " +stage +") = " +(i-folders+stage));
files[i-folders+stage] = all[i];
}
else{
folders++;
totalfolders++;
}
}
stage += all.length-folders; //We add number of files from every directory to stage.
for(int i = 0; i < all.length; i++){ //Then we seek for all the sub-directories
if(all[i].isDirectory()){
CacheReader(all[i].getPath()); //and add all the files from sub-directories to out file list
}
}
return true;
}
public static File[] getFiles(String string) {
if(string == "New"){
}
return files;
}
public static int NumberOfFiles(String string) {
File[] filenames;
filenames = new File(string).listFiles();
count += filenames.length; //We add all the files from the File(string) Note!: Also folders
for(int i = 0; i < filenames.length; i++){
if(filenames[i].isDirectory()){
NumberOfFiles(filenames[i].getPath());
count--;
}
}
return count;
}
}
Umm.. I think you can remove everything related to player, since it's not part of cache update system.. also there are some unused imports in those, I didn't remove all of them. Most of TextArea.Addline();s I changed to System.out.println(); if you find one, you can aswell replace it with System.out.println(); or if you don't need it you can remove it. What ever.. I just would like to find an answer..
try to write the byte array to the ObjectOutputStream as an object:
final byte[] bytearray = new byte[(int) file.length()];
buffIn = new BufferedInputStream(new FileInputStream(file));
buffIn.read(bytearray, 0, bytearray.length);
sOutput.writeObject(bytearray);
And to read it as an Object:
final BufferedOutputStream Bos =
new BufferedOutputStream(new FileOutputStream(result));
byte[] mybytearray = (byte[])sInput.readObject();
Bos.write(mybytearray, 0, BytesRead);
I hope it helps.
Don't use multiple streams to read from the same socket, or write to it either. Use the object streams for everything.
Your copy loops are incorrect, because they aren't loops. You can't assume that read() fills the buffer. The canonical stream copy loop in Java is like so:
int count;
byte[] buffer = new byte[8192]; // or more, code works with any size >= 1
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
Related
The need:
I want to write data into compressed and normal format as well. When I'll have to write data into compressed format "useCompression" will be sent as "true" and "useCompression" will be false when data needs to be stored in normal(as it is given to the Writer class) format.
The problem here is, how will I identify whether the data is compressed or not later when Reader class is trying to read the data?
So, to solve the problem, I am writing "1" into file if is "useCompression" is true and "0" if "useCompression" is false.
writing is fine, but when we try to skip the first element using "fIn.skip(1)" cause it is the identifier and not actual data, it is leaving behind some garbage value.
For, example, I am trying to write "2019-07-31" into a file and "useCompression" is false, so my file will hold "02019-07-31" and post "fIn.skip(1)" call it should hold "2019-07-31" but it is holding "^#2019-07-31".
Please help me figure out what I am doing wrong here
I've tried to update Reader class's constructor as:
public Reader(String key)
{
mKey = key;
try {
FileInputStream fIn = new FileInputStream(streamFileForKey(key));
byte[] firstByte = new byte[1];
int read = fIn.read(firstByte);
boolean shouldUseDecompression = (1 == firstByte[0]);
if (shouldUseDecompression) {
mFin = new GZIPInputStream(fIn);
}
else {
mFin = fIn;
}
}
catch (Exception e) {
System.out.println("Failed to open (r) key " + key + " exception : " + e);
}
}
But it does not solve the problem.
The actual code is:
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.DataOutputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.GZIPInputStream;
public class forStackOverflow {
public static void main(String []args) {
// Write to normal file
mReader1 = new Reader(mInputFileName);
mWriter1 = new Writer(mOutputFilename1, false);
int availableBytes = mReader1.availableBytes();
int readBytes = 1000;
while (availableBytes > 0)
{
if (availableBytes >= 1000) {
availableBytes = availableBytes - readBytes;
}
else {
readBytes = availableBytes;
availableBytes = availableBytes - readBytes;
}
mWriter1.write(mReader1.read(readBytes), 0, readBytes);
}
mReader1.close();
mWriter1.close();
}
private static File streamFileForKey(String key)
{
return new File(key);
}
static String mInputFileName = "~/Downloads/inputStream.txt";
static String mOutputFilename1 = "~/Downloads/outputStream.txt";
static Reader mReader1;
static Writer mWriter1;
private static class Writer
{
public Writer(String key, boolean useCompression) {
mKey = key;
try {
FileOutputStream fileOutput = new FileOutputStream(streamFileForKey(key));
if (useCompression) {
fileOutput.write(1);
gOutputStream = new GZIPOutputStream(fileOutput);
}
else {
fileOutput.write(0);
gOutputStream = new DataOutputStream(fileOutput);
}
}
catch (Exception e) {
System.out.println("Got error while opening stream for " + mKey + ". Ex: " + e);
}
}
public boolean write(byte[] bytes, int pos, int len)
{
boolean retVal = true;
if (gOutputStream == null) {
return false;
}
try {
gOutputStream.write(bytes, pos, len);
retVal = true;
}
catch (Exception e) {
System.out.println("Failed to write " + len + " bytes to key " +
mKey + e);
retVal = false;
}
return retVal;
}
public void close()
{
if (gOutputStream != null) {
try {
gOutputStream.close();
}
catch (Exception e) {
System.out.println("Failed to close key " + mKey + e);
}
gOutputStream = null;
}
}
private String mKey;
private OutputStream gOutputStream;
}
private static class Reader
{
public Reader(String key)
{
mKey = key;
try {
FileInputStream fIn = new FileInputStream(streamFileForKey(key));
if (shouldUseDecompression()) {
long skipped = fIn.skip(1);
mFin = new GZIPInputStream(fIn);
}
else {
long skipped = fIn.skip(1);
mFin = fIn;
}
}
catch (Exception e) {
System.out.println("Failed to open (r) key " + key + " exception : " + e);
}
}
public byte[] read(int len)
{
if (mFin == null) {
return null;
}
byte[] b = null;
try {
b = new byte[len];
int read;
read = mFin.read(b, 0, len);
if (read <= 0) {
return null;
}
}
catch (Exception e) {
System.out.println("Failed to read " + len + " bytes from key " +
mKey + " exception : " + e);
}
return b;
}
public void close()
{
if (mFin != null) {
try {
mFin.close();
}
catch (Exception e) {
System.out.println("Failed to close key " + mKey + " exception : " + e);
}
mFin = null;
}
}
private boolean shouldUseDecompression()
{
boolean retVal = false;
try {
FileInputStream fIn = new FileInputStream(streamFileForKey(mKey));
byte[] firstByte = new byte[1];
int read = fIn.read(firstByte);
// If first byte is `1` the we need to use decompression on it.
retVal = (1 == firstByte[0]);
fIn.close();
}
catch(Exception e) {
System.out.println("Exception in shouldUseDecompression() : " + e);
retVal = false;
}
return retVal;
}
public int availableBytes()
{
int available = 0;
try {
if (mFin != null) {
available = mFin.available();
}
}
catch (IOException e) {
System.out.println("Failed to read available bytes for " + mKey + ". Exception : " + e);
}
return available;
}
private String mKey;
private InputStream mFin;
}
}
The expected result should be, post "fIn.skip(1)" call file should hold "2019-07-31" and not "^#2019-07-31".
After a lot of struggle, I found out that it was the expected result.
^# was nothing but the binary 0 I was writing from Writer class's constructor incase useCompression was false.
From line fileOutput.write(0);.
This class is part of the multi user application and it's used to view documents, however this does not work when the file size is over 20 MB.
The issue is here:
raf = new RandomAccessFile(this._file, "rw");
byte[] b = new byte[128000];
I have also tried to change it to byte[] b = new byte[(int)raf]; but it did not work.
import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
class PersistentByteServerV2$Runner extends Thread {
private ReaderWriterLock _rwl;
private File _file;
private InputStream _is;
private long _bytesRead;
private boolean _locksAcquired = true;
public PersistentByteServerV2$Runner(ReaderWriterLock rwl, File file,
InputStream is) {
this._rwl = rwl;
try {
this._rwl.startWrite();
this._rwl.startRead();
} catch (InterruptedException var5) {
this._locksAcquired = false;
}
this._file = file;
this._is = is;
this._bytesRead = 0 L;
}
public void run() {
RandomAccessFile raf = null;
if (this._locksAcquired) {
try {
raf = new RandomAccessFile(this._file, "rw");
byte[] b = new byte[128000]; // the value is set to this, as changing it to raf length does not work.
long len = 0 L;
do {
len = (long) this._is.read(b); //InputStream
if (len <= 0 L) {
break;
}
raf.write(b, 0, (int) len); //write to the random access file
if (this._bytesRead == 0 L) {
this._rwl.endRead();
}
this._bytesRead += len;
} while (len > -1 L);
} catch (Throwable var18) {;
} finally {
try {
raf.close();
} catch (Throwable var17) {;
}
try {
this._is.close();
} catch (Throwable var16) {;
}
if (this._rwl.isWriterDown()) {
this._rwl.endWrite();
}
if (this._rwl.isReaderDown()) {
this._rwl.endRead();
}
}
}
}
public long getBytesRead() {
try {
this._rwl.startRead();
this._rwl.endRead();
} catch (InterruptedException var2) {
return -1 L;
}
return this._bytesRead;
}
}
I have written a java code to transfer files from one server to another using the concept of socket programming. I got the codes from another java forum that meet my requirements. The program is said to transfer large sized files (like .mkv , .mprg movies) from one machine to another and can be used to transfer files of all formats. But after running the codes I found that the program is not able to transfer large sized files such as movies and even pdf of sizes 80mb or 111mb. The program has used bytebuffer but still error occurs. The codes are as follows (I got them from this site http://www.coderpanda.com/java-socket-programming-transferring-large-sized-files-through-socket/)
ClientMain.java
import java.io.IOException;
import java.net.Socket;
public class ClientMain
{
private DirectoryTxr transmitter = null;
Socket clientSocket = null;
private boolean connectedStatus = false;
private String ipAddress;
String srcPath = null;
String dstPath = "";
public ClientMain()
{
}
public void setIpAddress(String ip)
{
this.ipAddress = ip;
}
public void setSrcPath(String path)
{
this.srcPath = path;
}
public void setDstPath(String path)
{
this.dstPath = path;
}
private void createConnection()
{
Runnable connectRunnable = new Runnable()
{
public void run()
{
while (!connectedStatus)
{
try
{
clientSocket = new Socket(ipAddress, 22);
connectedStatus = true;
transmitter = new DirectoryTxr(clientSocket, srcPath, dstPath);
}
catch (IOException io)
{
io.printStackTrace();
}
}
}
};
Thread connectionThread = new Thread(connectRunnable);
connectionThread.start();
}
public static void main(String[] args)
{
ClientMain main = new ClientMain();
main.setIpAddress("localHost");
main.setSrcPath("C:/Transfer/");
main.setDstPath("C:/Receive");
main.createConnection();
}
}
DirectoryTxr.java
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class DirectoryTxr
{
Socket clientSocket = null;
String srcDir = null;
String dstDir = null;
byte[] readBuffer = new byte[1024];
private InputStream inStream = null;
private OutputStream outStream = null;
int state = 0;
final int permissionReqState = 1;
final int initialState = 0;
final int dirHeaderSendState = 2;
final int fileHeaderSendState = 3;
final int fileSendState = 4;
final int fileFinishedState = 5;
private boolean isLive = false;
private int numFiles = 0;
private int filePointer = 0;
String request = "May I send?";
String respServer = "Yes,You can";
String dirResponse = "Directory created...Please send files";
String fileHeaderRecvd = "File header received ...Send File";
String fileReceived = "File Received";
String dirFailedResponse = "Failed";
File[] opFileList = null;
public DirectoryTxr(Socket clientSocket, String srcDir, String dstDir)
{
try
{
this.clientSocket = clientSocket;
inStream = clientSocket.getInputStream();
outStream = clientSocket.getOutputStream();
isLive = true;
this.srcDir = srcDir;
this.dstDir = dstDir;
state = initialState;
readResponse();
sendMessage(request);
state = permissionReqState;
}
catch (IOException io)
{
io.printStackTrace();
}
}
private void sendMessage(String message)
{
try
{
sendBytes(request.getBytes("UTF-8"));
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
private void readResponse()
{
Runnable readRunnable = new Runnable()
{
public void run()
{
while (isLive)
{
try
{
int num = inStream.read(readBuffer);
if (num > 0)
{
byte[] tempArray = new byte[num];
System.arraycopy(readBuffer, 0, tempArray, 0, num);
processBytes(tempArray);
}
}
catch (SocketException se)
{
System.exit(0);
}
catch (IOException io)
{
io.printStackTrace();
isLive = false;
}
}
}
};
Thread readThread = new Thread(readRunnable);
readThread.start();
}
private void sendDirectoryHeader()
{
File file = new File(srcDir);
if (file.isDirectory())
{
try
{
String[] childFiles = file.list();
numFiles = childFiles.length;
String dirHeader = "$" + dstDir + "#" + numFiles + "&";
sendBytes(dirHeader.getBytes("UTF-8"));
}
catch (UnsupportedEncodingException en)
{
en.printStackTrace();
}
}
else
{
System.out.println(srcDir + " is not a valid directory");
}
}
private void sendFile(String dirName)
{
File file = new File(dirName);
if (!file.isDirectory())
{
try
{
int len = (int) file.length();
int buffSize = len / 8;
RandomAccessFile raf = new RandomAccessFile(file, "rw");
FileChannel channel = raf.getChannel();
int numRead = 0;
while (numRead >= 0)
{
ByteBuffer buf = ByteBuffer.allocate(1024 * 100000);
numRead = channel.read(buf);
if (numRead > 0)
{
byte[] array = new byte[numRead];
System.arraycopy(buf.array(), 0, array, 0, numRead);
sendBytes(array);
}
}
System.out.println("Finished");
}
catch (IOException io)
{
io.printStackTrace();
}
}
}
private void sendHeader(String fileName)
{
try
{
File file = new File(fileName);
if (file.isDirectory())
return;
String header = "&" + fileName + "#" + file.length() + "*";
sendHeader(header);
sendBytes(header.getBytes("UTF-8"));
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
private void sendBytes(byte[] dataBytes)
{
synchronized (clientSocket)
{
if (outStream != null)
{
try
{
outStream.write(dataBytes);
outStream.flush();
}
catch (IOException io)
{
io.printStackTrace();
}
}
}
}
private void processBytes(byte[] data)
{
try
{
String parsedMessage = new String(data, "UTF-8");
System.out.println(parsedMessage);
setResponse(parsedMessage);
}
catch (UnsupportedEncodingException u)
{
u.printStackTrace();
}
}
private void setResponse(String message)
{
if (message.trim().equalsIgnoreCase(respServer) && state == permissionReqState)
{
state = dirHeaderSendState;
sendDirectoryHeader();
}
else if (message.trim().equalsIgnoreCase(dirResponse) && state == dirHeaderSendState)
{
state = fileHeaderSendState;
if (LocateDirectory())
{
createAndSendHeader();
}
else
{
System.out.println("Vacant or invalid directory");
}
}
else if (message.trim().equalsIgnoreCase(fileHeaderRecvd) && state == fileHeaderSendState)
{
state = fileSendState;
sendFile(opFileList[filePointer].toString());
state = fileFinishedState;
filePointer++;
}
else if (message.trim().equalsIgnoreCase(fileReceived) && state == fileFinishedState)
{
if (filePointer < numFiles)
{
createAndSendHeader();
}
System.out.println("Successfully sent");
}
else if (message.trim().equalsIgnoreCase(dirFailedResponse))
{
System.out.println("Going to exit....Error ");
}
else if (message.trim().equalsIgnoreCase("Thanks"))
{
System.out.println("All files were copied");
}
}
private void closeSocket()
{
try
{
clientSocket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
private boolean LocateDirectory()
{
boolean status = false;
File file = new File(srcDir);
if (file.isDirectory())
{
opFileList = file.listFiles();
numFiles = opFileList.length;
if (numFiles <= 0)
{
System.out.println("No files found");
}
else
{
status = true;
}
}
return status;
}
private void createAndSendHeader()
{
File opFile = opFileList[filePointer];
String header = "&" + opFile.getName() + "#" + opFile.length() + "*";
try
{
state = fileHeaderSendState;
sendBytes(header.getBytes("UTF-8"));
}
catch (UnsupportedEncodingException e)
{
}
}
private void sendListFiles()
{
createAndSendHeader();
}
}
ServerMain.java
public class ServerMain {
public ServerMain() {
}
public static void main(String[] args) {
DirectoryRcr dirRcr = new DirectoryRcr();
}
}
DirectoryRcr.java
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
public class DirectoryRcr
{
String request = "May I send?";
String respServer = "Yes,You can";
String dirResponse = "Directory created...Please send files";
String dirFailedResponse = "Failed";
String fileHeaderRecvd = "File header received ...Send File";
String fileReceived = "File Received";
Socket socket = null;
OutputStream ioStream = null;
InputStream inStream = null;
boolean isLive = false;
int state = 0;
final int initialState = 0;
final int dirHeaderWait = 1;
final int dirWaitState = 2;
final int fileHeaderWaitState = 3;
final int fileContentWaitState = 4;
final int fileReceiveState = 5;
final int fileReceivedState = 6;
final int finalState = 7;
byte[] readBuffer = new byte[1024 * 100000];
long fileSize = 0;
String dir = "";
FileOutputStream foStream = null;
int fileCount = 0;
File dstFile = null;
public DirectoryRcr()
{
acceptConnection();
}
private void acceptConnection()
{
try
{
ServerSocket server = new ServerSocket(22);
socket = server.accept();
isLive = true;
ioStream = socket.getOutputStream();
inStream = socket.getInputStream();
state = initialState;
startReadThread();
}
catch (IOException io)
{
io.printStackTrace();
}
}
private void startReadThread()
{
Thread readRunnable = new Thread()
{
public void run()
{
while (isLive)
{
try
{
int num = inStream.read(readBuffer);
if (num > 0)
{
byte[] tempArray = new byte[num];
System.arraycopy(readBuffer, 0, tempArray, 0, num);
processBytes(tempArray);
}
sleep(100);
} catch (SocketException s)
{
}
catch (IOException e)
{
e.printStackTrace();
}
catch (InterruptedException i)
{
i.printStackTrace();
}
}
}
};
Thread readThread = new Thread(readRunnable);
readThread.start();
}
private void processBytes(byte[] buff) throws InterruptedException
{
if (state == fileReceiveState || state == fileContentWaitState)
{
if (state == fileContentWaitState)
state = fileReceiveState;
fileSize = fileSize - buff.length;
writeToFile(buff);
if (fileSize == 0)
{
state = fileReceivedState;
try
{
foStream.close();
}
catch (IOException io)
{
io.printStackTrace();
}
System.out.println("Received " + dstFile.getName());
sendResponse(fileReceived);
fileCount--;
if (fileCount != 0)
{
state = fileHeaderWaitState;
}
else
{
System.out.println("Finished");
state = finalState;
sendResponse("Thanks");
Thread.sleep(2000);
System.exit(0);
}
System.out.println("Received");
}
}
else
{
parseToUTF(buff);
}
}
private void parseToUTF(byte[] data)
{
try
{
String parsedMessage = new String(data, "UTF-8");
System.out.println(parsedMessage);
setResponse(parsedMessage);
}
catch (UnsupportedEncodingException u) {
u.printStackTrace();
}
}
private void setResponse(String message)
{
if (message.trim().equalsIgnoreCase(request) && state == initialState)
{
sendResponse(respServer);
state = dirHeaderWait;
}
else if (state == dirHeaderWait)
{
if (createDirectory(message))
{
sendResponse(dirResponse);
state = fileHeaderWaitState;
}
else
{
sendResponse(dirFailedResponse);
System.out.println("Error occurred...Going to exit");
System.exit(0);
}
} else if (state == fileHeaderWaitState)
{
createFile(message);
state = fileContentWaitState;
sendResponse(fileHeaderRecvd);
}
else if (message.trim().equalsIgnoreCase(dirFailedResponse))
{
System.out.println("Error occurred ....");
System.exit(0);
}
}
private void sendResponse(String resp)
{
try
{
sendBytes(resp.getBytes("UTF-8"));
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
}
private boolean createDirectory(String dirName)
{
boolean status = false;
dir = dirName.substring(dirName.indexOf("$") + 1, dirName.indexOf("#"));
fileCount = Integer.parseInt(dirName.substring(dirName.indexOf("#") + 1, dirName.indexOf("&")));
if (new File(dir).mkdir())
{
status = true;
System.out.println("Successfully created directory " + dirName);
}
else if (new File(dir).mkdirs())
{
status = true;
System.out.println("Directories were created " + dirName);
}
else if (new File(dir).exists())
{
status = true;
System.out.println("Directory exists" + dirName);
}
else
{
System.out.println("Could not create directory " + dirName);
status = false;
}
return status;
}
private void createFile(String fileName)
{
String file = fileName.substring(fileName.indexOf("&") + 1, fileName.indexOf("#"));
String lengthFile = fileName.substring(fileName.indexOf("#") + 1, fileName.indexOf("*"));
fileSize = Integer.parseInt(lengthFile);
dstFile = new File(dir + "/" + file);
try
{
foStream = new FileOutputStream(dstFile);
System.out.println("Starting to receive " + dstFile.getName());
}
catch (FileNotFoundException fn)
{
fn.printStackTrace();
}
}
private void writeToFile(byte[] buff)
{
try
{
foStream.write(buff);
}
catch (IOException io)
{
io.printStackTrace();
}
}
private void sendBytes(byte[] dataBytes)
{
synchronized (socket)
{
if (ioStream != null)
{
try
{
ioStream.write(dataBytes);
}
catch (IOException io)
{
io.printStackTrace();
}
}
}
}
}
Note that:-
ClientMain.java and DirectoryTxr.java are the two classes under client application.
ServerMain.java and DirectoryRcr.java are the two classes under Server application.
run the ClientMain.java and ServerMain.java simultaneously
Also specify the source directory, destination directory and host address of the machine in which server is running in the ClientMain.java(as per your computer). Here we are not specifying source file ,instead a source directory or folder is specifying.So the entire files of source directory will be transferred.
I would really appreciate if someone can help me with the problem.
You can check this code. This code can send files till 2GB of file size. Checked and working. Basically what I do here is first I send the file size and file name in an object then I start sending the file. First of all let me show you the class whose object will carry the File's details and send it to Receiver.
FileTransfer Class:
public class FileDetails implements Serializable {
String name;
long size;
public void setDetails(String name, long size) {
this.name = name;
this.size = size;
}
public String getName() {
return name;
}
public long getSize() {
return size;
}
}
Sender:
ServerSocket sendServer = null;
Socket sendSocket;
FileDetails details;
byte data[];
try {
File file = new File("File Url");
// Getting file name and size
if (file.length() > Integer.MAX_VALUE) {
System.out.println("File size exceeds 2 GB");
} else {
sendServer = new ServerSocket(5050);
System.out.println("Waiting for Client...");
sendSocket = sendServer.accept();
// File Object for accesing file Details
System.out.println("Connected to Client...");
data = new byte[2048]; // Here you can increase the size also which will send it faster
details = new FileDetails();
details.setDetails(file.getName(), file.length());
// Sending file details to the client
System.out.println("Sending file details...");
ObjectOutputStream sendDetails = new ObjectOutputStream(sendSocket.getOutputStream());
sendDetails.writeObject(details);
sendDetails.flush();
// Sending File Data
System.out.println("Sending file data...");
FileInputStream fileStream = new FileInputStream(file);
BufferedInputStream fileBuffer = new BufferedInputStream(fileStream);
OutputStream out = sendSocket.getOutputStream();
int count;
while ((count = fileBuffer.read(data)) > 0) {
System.out.println("Data Sent : " + count);
out.write(data, 0, count);
out.flush();
}
out.close();
fileBuffer.close();
fileStream.close();
}
} catch (Exception e) {
System.out.println("Error : " + e.toString());
}
Receiver's code :
int port = 5050;
try {
System.out.println("Connecting to Server...");
Socket receiveSocket = new Socket("IP of Server", port);
System.out.println("Connected to Server...");
// Getting file details
System.out.println("Getting details from Server...");
ObjectInputStream getDetails = new ObjectInputStream(receiveSocket.getInputStream());
FileDetails details = (FileDetails) getDetails.readObject();
System.out.println("Now receiving file...");
// Storing file name and sizes
String fileName = details.getName();
System.out.println("File Name : " + fileName);
byte data[] = new byte[2048]; // Here you can increase the size also which will receive it faster
FileOutputStream fileOut = new FileOutputStream("D:\\" + fileName);
InputStream fileIn = receiveSocket.getInputStream();
BufferedOutputStream fileBuffer = new BufferedOutputStream(fileOut);
int count;
int sum = 0;
while ((count = fileIn.read(data)) > 0) {
sum += count;
fileBuffer.write(data, 0, count);
System.out.println("Data received : " + sum);
fileBuffer.flush();
}
System.out.println("File Received...");
fileBuffer.close();
fileIn.close();
} catch (Exception e) {
System.out.println("Error : " + e.toString());
}
Hope this helps you.
You don't need all this. The canonical way to copy a stream in Java is as follows. It works for any buffer size greater than zero. I generally use 8192. There is certainly no necessity to read entire files into memory. It just wastes time and space.
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
If you know the size in advance and need to keep the socket open for another transfer:
while (total < length && (count = in.read(buffer, 0, length-total > buffer.length ? buffer.length : (int)(length-total))) > 0)
{
out.write(buffer, 0, count);
total += count;
}
where total is a long initialized to zero before this loop, and length is the length you know in advance.
Hello I have created a multi-threaded HTTP Server in Java and cannot get content when using a web browser.
When I use a telnet client to read from the webserver it works fine, however with a browser such as chrome nothing shows up.
I have posted 3 pictures below showing that connection via telnet works fine and an additional picture that shows wireshark capture when calling webserver via chrome browswer using:
http://localhost:4568
Here is the code I have written posted below.
I changed the code to single threaded for easier debugging, the section in MainWebServer which is called "Debugging Section" is what the threading class contains.
MainWebServer:
package my.simple.webserver;
import java.io.*;
import java.net.*;
import java.util.*;
#SuppressWarnings("unused")
public class mainWebServer {
private static ServerSocket ser = null;
private static Socket cli = null;
private static String host = null;
private static int port;
/**
* #param args
*/
public static void main(String[] args) {
// Get parameters
if(args.length < 2)
{
setHost("localhost");
port = 4568;
}
else
{
setHost(args[0]);
port = Integer.parseInt(args[1]);
}
// initialize server
try {
// change to take in host
ser = new ServerSocket(port);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while(true)
{
try {
setCli(ser.accept());
//(new Thread(new HttpThread(cli))).start();
// Debugging section
DataInputStream sockIn = new DataInputStream(cli.getInputStream());
HttpRequest req = new HttpRequest(cli);
int cnt = 0;
byte[] buffer = new byte[1024];
while((cnt = sockIn.read(buffer)) >= 0)
{
System.out.println("We are here");
req.checkMethod(new String(buffer));
resetBuffer(buffer, 256);
}
// end debugging section
// run thread for client socket
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static String getHost() {
return host;
}
public static void setHost(String host) {
mainWebServer.host = host;
}
public static Socket getCli() {
return cli;
}
public static void setCli(Socket cli) {
mainWebServer.cli = cli;
}
// remove after debugging
public static void resetBuffer(byte[] buffer2, int i) {
// TODO Auto-generated method stub
for(int x=0; x < i; x++)
{
buffer2[x] = 0;
}
}
}
HttpRequest class:
package my.simple.webserver;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
public class HttpRequest {
private String method = null;
private String path = null;
private FileInputStream fis = null;
private OutputStream os = null;
private Socket mycli;
private static final String HTTP_OK_RESPONSE = "HTTP/1.1 200 OK\r\n";
private static final String HTTP_FNF_RESPONSE = "HTTP/1.1 404 NOT FOUND\r\n";
private static final String HTTP_DATE_RESPONSE = "Date: Mon, 04-Jan-99 13:14:15 GMT\r\n";
private static final String HTTP_SERVER_RESPONSE = "Server: Challenger\r\n";
private static final String HTTP_CONTENT_TYPE = "Content-Type: text/html\r\n";
private String HTTP_Content_Length = "Content-length: ";
public HttpRequest(Socket myCli) {
// TODO Auto-generated constructor stub
mycli = myCli;
}
void checkMethod(String buffer)
{
// get data and parse for method, location and protocol
// use switch statement based on method given
System.out.println("buffer = " + buffer);
StringTokenizer tok = new StringTokenizer(buffer);
try
{
method = tok.nextToken();
path = tok.nextToken();
}
catch(NoSuchElementException nse)
{
System.out.println(nse.getMessage());
method = "";
}
//System.out.println("method=" + method + " path=" + path);
switch(method)
{
case "GET":
//System.out.println("Get method called");
getMethod();
break;
case "HEAD":
System.out.println("Head method called");
break;
case "POST":
System.out.println("Post method called");
break;
case "PUT":
System.out.println("Put method called");
break;
case "DELETE":
System.out.println("Delete method called");
break;
case "TRACE":
System.out.println("Trace method called");
break;
case "OPTIONS":
System.out.println("Options method called");
break;
case "CONNECT":
System.out.println("Connect method called");
break;
default:
break;
}
}
private void getMethod()
{
String file;
File f = null;
// check if file exists
if(path.equalsIgnoreCase("/"))
{
//file = checkForIndex();
file = "index.html";
}
else
file = path;
System.out.println("file = " + file);
// open file
try {
file = "badfile.html";
f = new File(file);
os = mycli.getOutputStream();
//check if file exists
if(f.exists())
{
byte[] buffer = null;
buffer = HTTP_OK_RESPONSE.getBytes();
os.write(buffer);
buffer = HTTP_DATE_RESPONSE.getBytes();
os.write(buffer);
buffer = HTTP_SERVER_RESPONSE.getBytes();
os.write(buffer);
buffer = HTTP_CONTENT_TYPE.getBytes();
os.write(buffer);
long fileLen = f.length();
HTTP_Content_Length = HTTP_Content_Length.concat(String.valueOf(fileLen));
HTTP_Content_Length = HTTP_Content_Length.concat("\r\n");
buffer = HTTP_Content_Length.getBytes();
os.write(buffer);
fis = new FileInputStream(file);
int nread, result;
// read file
while((nread = fis.available()) > 0)
{
buffer = new byte[nread];
result = fis.read(buffer);
if(result == -1) break;
os.write(buffer);
}
System.out.println("Left the loop!");
mycli.close();
}
else
{
// deal with 404
byte[] buffer = null;
buffer = HTTP_FNF_RESPONSE.getBytes();
os.write(buffer);
buffer = HTTP_DATE_RESPONSE.getBytes();
os.write(buffer);
buffer = HTTP_SERVER_RESPONSE.getBytes();
os.write(buffer);
buffer = HTTP_CONTENT_TYPE.getBytes();
os.write(buffer);
f = new File("fnf.html");
long fileLen = f.length();
HTTP_Content_Length = HTTP_Content_Length.concat(String.valueOf(fileLen));
HTTP_Content_Length = HTTP_Content_Length.concat("\r\n");
buffer = HTTP_Content_Length.getBytes();
os.write(buffer);
fis = new FileInputStream(f);
int nread, result;
// read file
while((nread = fis.available()) > 0)
{
buffer = new byte[nread];
result = fis.read(buffer);
if(result == -1) break;
os.write(buffer);
}
System.out.println("Left the loop!");
mycli.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// end thread
}
}
I am on a time crunch, I appreciate any help.
Thank you!
Because in HTTP protocol after sending the header, you need to send an empty line(\r\n) that indicates the end of header section in both request and response, for example
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 21
\r\n(EMPTY LINE) <- you forgot this one
<b>Hello World :D</b>
Add "\r\n" after you complete header.
Like:
HTTP_Content_Length = HTTP_Content_Length.concat("\r\n\r\n");
I have created a webserver in Android which binds to port 2090 and serves the sdcard of Android devices it works fine if I type the ip:port/index.htm in Internet Explorer then it works just great but when I open it in other browsers than it opens the HTML file as text please help me.
This is my code.
The server starter 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.facebook);
try{
File documentRootDirectory = new File (Environment.getExternalStorageDirectory().getAbsolutePath()+"/");
JHTTP j = new JHTTP(documentRootDirectory,2090);
j.start();
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( );
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.htm";
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 return "text/plain";
}
} // end RequestProcessor
Logcat:
Not posting because there is no error.
the problem is solved i replace the line
else return "text/plain";
to
else return "text/html";
Actually the problem was in MIME type thank you all for helping me...