I wrote a Java server application that returns a file when it is requested by a browser. The browser makes a GET request to my socket and the socket returns the file. But the browser (firefox in my case) treats the html file as a regular text file and does not render the actual page. So the browser shows the whole html source code. How can I fix that?
Here the Code:
package ml.mindlabor.networking;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
static final int PORT = 9806;
static final int MAX_BYTES_PER_STREAM = 10_000; // 10 kB
static final String FILE_SYSTEM_PATH = "C:\\Users\\SBrau\\eclipse-workspace\\Networking\\src\\ml\\mindlabor\\networking\\Files\\public_html";
static boolean running = true;
ServerSocket ss = null;
Socket soc = null;
public static void main(String[] args) {
Server server = new Server();
// When the connection could not be established
System.out.println("Waiting for connection ...");
if (!server.connect()) return;
server.listenForResponse();
}
public Server() {
try {
ss = new ServerSocket(PORT);
} catch (IOException e) {
System.err.println("Could not create ServerSocket on Port " + PORT);
shutdown();
}
}
boolean respond(String response) {
try {
PrintWriter out = new PrintWriter(soc.getOutputStream(), true);
out.println(response);
return true;
} catch (IOException e) {
System.err.println("Could not send to Port " + PORT);
}
return false;
}
boolean respond(byte[] response) {
try {
soc.getOutputStream().write(response);
return true;
} catch (IOException e) {
System.err.println("Could not send to Port " + PORT);
}
return false;
}
boolean respondFile(String relPath) {
String path = Server.FILE_SYSTEM_PATH + relPath;
File file = new File(path);
try {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
byte[] buffer = new byte[(int)file.length()]; // or 4096, or more
in.read(buffer, 0, buffer.length);
soc.getOutputStream().write(buffer, 0, buffer.length);
System.out.println("Loaded :D");
in.close();
soc.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
String rawDataToString(byte[] rawData) {
return new String(rawData);
}
void listenForResponse() {
new Thread(() -> {
while (true) {
try {
DataInputStream in = new DataInputStream(soc.getInputStream());
byte[] packetData = new byte[MAX_BYTES_PER_STREAM];
in.read(packetData);
receivedPackage(packetData);
} catch (IOException e) {
System.err.println("Could not get data from port " + PORT);
shutdown();
}
}
}).start();
}
void shutdown() {
Server.running = false;
}
void receivedPackage(byte[] pkg) {
String request = new String(pkg).trim();
// GET Request for file
if (request.contains("GET ")) {
String[] arr = request.split(" ");
respondFile(arr[1].trim());
}
}
boolean connect() {
try {
soc = ss.accept();
//soc.setKeepAlive(true);
System.out.println("Connected!");
return true;
} catch (IOException e) {
System.err.println("Could not wait for connection on port " + PORT);
shutdown();
}
return false;
}
}
Ok. Got it. I solved it by rewriting the following method:
boolean respondFile(String relPath) {
String path = Server.FILE_SYSTEM_PATH + relPath;
File file = new File(path);
try {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
PrintWriter out = new PrintWriter(soc.getOutputStream());
BufferedOutputStream dataOut = new BufferedOutputStream(soc.getOutputStream());
byte[] fileData = readFileData(file, (int)file.length());
out.println("HTTP/1.1 501 Not Implemented");
out.println("Content-type: text/html");
out.println(); // blank line between headers and content, very important !
out.flush();
dataOut.write(fileData, 0, fileData.length);
dataOut.flush();
System.out.println("Loaded :D");
in.close();
soc.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
private byte[] readFileData(File file, int fileLength) throws IOException {
FileInputStream fileIn = null;
byte[] fileData = new byte[fileLength];
try {
fileIn = new FileInputStream(file);
fileIn.read(fileData);
} finally {
if (fileIn != null)
fileIn.close();
}
return fileData;
}
I am trying to implement a server and client based on the web socket technologie but when I run the TCPDataServer class I am getting the following error:
java.io.IOException: connection reset
at java.io.DataInputStream.read(Unknown Source)
at org.server.ClientWorker.run(TCPDataServer.java:67)
at java.lang.Thread.run(Unknown Source)
I excepted to get the following output Hello, I am Alex!
TCPDataClient
package org.client;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class TCPDataClient {
public static void main(String[] args) {
try {
TCPDataClient obj = new TCPDataClient();
Socket obj_client = new Socket(InetAddress.getByName("127.0.1"), 1000);
DataInputStream din = new DataInputStream(obj_client.getInputStream());
DataOutputStream dout = new DataOutputStream(obj_client.getOutputStream());
byte[] buffer = obj.createDataPacket("Hello, I am Alex!".getBytes("UTF8"));
dout.write(buffer);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private byte[] createDataPacket(byte[] data) {
byte[] packet = null;
try {
byte[] initialize = new byte[1];
initialize[0] = 2;
byte[] separator = new byte[1];
separator[0] = 4;
byte[] data_length = String.valueOf(data.length).getBytes("UIF8");
packet = new byte[initialize.length + separator.length + data_length.length + data.length];
System.arraycopy(initialize, 0, packet, 0, initialize.length);
System.arraycopy(data_length, 0, packet, initialize.length, data_length.length);
System.arraycopy(separator, 0, packet, initialize.length + data_length.length, separator.length);
System.arraycopy(data, 0, packet, initialize.length + data_length.length + separator.length, data.length);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return packet;
}
}
TCPDataServer
package org.server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import java.util.logging.Level;
import com.sun.istack.internal.logging.Logger;
public class TCPDataServer {
public static void main(String[] args) {
try {
ServerSocket server_socket = new ServerSocket(1000);
while (true) {
new Thread(new ClientWorker(server_socket.accept())).start();
}
} catch (IOException e) {
System.err.println("Error");
System.err.println(e);
System.err.println("\n2");
System.err.println(e.getMessage());
System.err.println("\n3");
System.err.println(e.getLocalizedMessage());
System.err.println("\n4");
System.err.println(e.getCause());
System.err.println("\n5");
System.err.println(Arrays.toString(e.getStackTrace()));
System.err.println("\n6");
e.printStackTrace();
}
}
}
class ClientWorker implements Runnable {
private Socket target_socket;
private DataInputStream din;
private DataOutputStream dout;
public ClientWorker(Socket recv_scket) {
try {
target_socket = recv_scket;
din = new DataInputStream(target_socket.getInputStream());
dout = new DataOutputStream(target_socket.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void run() {
while (true) {
byte[] initilize = new byte[1];
try {
din.read(initilize, 0, initilize.length);
if (initilize[0] == 2) {
//This is line 67.
System.out.println(new String(readStream()));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private byte[] readStream() {
byte[] data_buff = null;
try {
int b = 0;
String buff_length = "";
while ((b = din.read()) != 4) {
buff_length += (char) b;
}
int data_length = Integer.parseInt(buff_length);
data_buff = new byte[Integer.parseInt(buff_length)];
int byte_read = 0;
int byte_offset = 0;
while (byte_offset < data_length) {
byte_read = din.read(data_buff, byte_read, data_length - byte_offset);
byte_offset += byte_read;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return data_buff;
}
}
In your Server program you have used din as your input stream reader which reads from the socket.
In your Client program you have used dout as output stream writer which writes to the underlying socket
In your ClientWorker class you have given multiple read operations using dinfrom the socket, whereas you have given only one write operation to the stream using dout object.
The din object will be blocking/waiting to receive the data from client side, but unfortunately you would have closed (program ends) your socket connection on your client which is reason for the DataInputStream to throw IOException.
And your din object will throw an IO error if your underlying socket/stream has been close and yet you are trying read using it.
Try to maintain the same number of reads and writes on either side (client/server).
You aren't closing the sockets, so your OS is resetting them when the JVM exits.
I am trying to create a simple server, but am having a problem with trying to accept the connection, specifically the line "connectionSocket = serverSocket.accept();". I also have another class SimpleHttpHandler which handles the connection which is referenced in this code.
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class SimpleHttpServer {
private String rootDirectory;
private int port;
private ServerSocket serverSocket;
private Socket connectionSocket;
public SimpleHttpServer(String rootDirectory, int port) {
this.rootDirectory = rootDirectory;
this.port = port;
}
public void start() {
// Establish the listen socket
try {
serverSocket = new ServerSocket(port);
System.out.println("Server started");
} catch (IOException e1) {
e1.printStackTrace();
}
while (true) {
System.out.println("Inside while");
// Listen for a TCP connection request
try {
connectionSocket = serverSocket.accept();
System.out.println("Client connected");
SimpleHttpHandler simpleHandler = new SimpleHttpHandler(rootDirectory);
simpleHandler.handle(connectionSocket);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SimpleHttpServer server = new SimpleHttpServer(args[0], Integer.parseInt(args[1]));
server.start();
}
}
When I accept a new connection, I need to create a handler to handle it.
The Handler class is:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import org.omg.CORBA.Request;
public class SimpleHttpHandler {
private String rootDirectory;
private StringBuffer readFile;
private FileInputStream fileInputStream;
private File file;
private int b;
public SimpleHttpHandler(String rootDirectory) {
this.rootDirectory = rootDirectory;
}
public void handle(Socket remote) {
try {
// Create in and out streams
BufferedReader in = new BufferedReader(new InputStreamReader(remote.getInputStream()));
PrintStream out = new PrintStream(remote.getOutputStream());
// HTTP requests resolved here based on the protocol
// Read a string line from client
String line = in.readLine();
// Send a string to client
out.println("Not yet implemented");
// Send an empty line to client
out.println();
// Send a byte to client
out.write(123);
// Read a byte from file
file = this.requestFile(rootDirectory, line);
fileInputStream = new FileInputStream(file);
b = fileInputStream.read(); // it returns -1 at end of file
// Read the file
BufferedReader fileReader = new BufferedReader(new FileReader(file));
readFile = null;
while(fileReader.readLine() != null) {
readFile.append(fileReader);
}
if(!file.equals(null)) {
responseMessage(readFile.toString());
} else {
errorMessage();
}
// Close the remote socket and r/w objects
in.close();
out.close();
remote.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private void errorMessage() {
System.out.println(readFile);
System.out.println("HTTP/1.0 500 Internal Server Error");
System.out.println();
System.out.println("^_^ Internal Server Error!");
;
}
private void responseMessage(String string) {
System.out.println("HTTP/1.0 200 OK");
System.out.println();
System.out.println("Hello World!");
}
public File requestFile(String rootDirectory, String path) {
// Construct a full path by connecting <rootDirectory> and requested relative path
File file = new File(rootDirectory, path);
// If it is a directory
// Then load the file index.html
if (file.isDirectory()) {
file = new File(file, "index.html");
}
// If the file exists, the file object is returned
// Otherwise null is returned
if (file.exists()) {
return file;
} else {
return null;
}
}
}
I am programming my first Java Socket application that uses a Client/Server paradigm.
I have the following classes:
SocketServer
SocketClient
The objective of the application is to have a user input a file path to a .csv file on the Client Console/File System:
1. Create a Server Program that uses a Socket.
a. The Server receives a CSV path/filename located on the Client from the Client.
b. The Server accesses the Client CSV file and converts it to an XML file.
c. The Server streams the XML file contents, not the XML path/file
name, back to the Client.
Create a Client Program that uses a Socket. Use the same port as the
Server.
a. Prompt the user for the path/filename of a CSV file.
b. Send the path/filename to the Server for processing.
c. Receive the XML file stream from the Server Socket.
d. Save the XML file stream to a file stored on the Client.
e. Store the generated XML file anywhere on the Client.
I have already written the code for connecting the Sockets on both the Server and Client as well as for converting the .csv to .xml, however, I am struggling with:
Step 1b.The Server accesses the Client CSV file and converts it to an
XML file.
Can I access the .csv file located on the Client directly from the Server
OR
Do I have to transfer the file path back from the Server to the Client, then transfer the file to the Server for conversion, then transfer the new XML document back?
Based on the instructions, it sounds like there should be a way to access the file from the Server.
Here is the code that I have already written.
ClientController.java
public class ClientController extends ConsoleController {
// DEBUG
private static final boolean DEBUG = true;
private static final boolean DEBUG_STORE = false;
private static final boolean DEBUG_PROMPT = false;
private static final boolean DEBUG_VALUES = true;
// CONSTANTS
public static final String PROMPT_MESSAGE = "Enter the filepath to a '.csv' file to convert to a '.xml' file: ";
// MEMBERS
private String userFilepath;
private SocketClient mClient;
// CONSTRUCTORS
public ClientController() {
super();
mClient = null;
}
// LIFE-CYCLE METHODS
#Override
public void onCreate() {
// Setup the Connection to the Server
mClient = setupServerConnection();
// Get the path to the CSV file for conversion
requestPathToCSVFile();
// Attempt to Transfer the file
try {
sendPathToServer(userFilepath);
} catch (Exception e) {
System.out.println("Failed to transfer the file!");
System.out.println("Exception: ");
e.printStackTrace();
}
// Attempt to send some message 50 times
mClient.sendSomeMessages(3);
}
// CONVENIENCE METHODS
private SocketClient setupServerConnection() {
String hostname = "localhost";
int port = 54321;
byte[] data = "Hello Server".getBytes();
return new SocketClient(hostname, port, data);
}
private void requestPathToCSVFile() {
// Debug vars
boolean isEmpty = true;
boolean isDefaultMessage = true;
boolean isCSV = false;
while (true){
if (!isEmpty && !isDefaultMessage && isCSV) break;
// Prompt user
userFilepath = promptUser(PROMPT_MESSAGE);
System.out.println(userFilepath);
// Debugging
isEmpty = userFilepath.isEmpty();
isDefaultMessage = userFilepath.equals(DEFAULT_MESSAGE);
isCSV = isCSVPath(userFilepath);
// Output Debugging
if (DEBUG && DEBUG_VALUES) {
if (userFilepath != null) {
System.out.println("DEBUG userFilepath: " + userFilepath);
} else {
System.out.println("DEBUG userFilepath: isNull");
}
System.out.println("isEmpty: " + (isEmpty? "true":"false"));
System.out.println("DEBUG userFilepath:" + (isDefaultMessage? "true":"false"));
System.out.println("isCSVPath: " + (isCSVPath(userFilepath)? "true":"false"));
}
}
}
private void sendPathToServer(String path) {
// Send the filepath to the Server
mClient.sendMessage(path);
}
private boolean isCSVPath(String path) {
return Regex.hasExtension(path, "csv");
}
}
SocketServer.java
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
// An example of a very simple socket server.
public class SocketServer
{
// CONSTANTS
private static final boolean DEBUG = true;
private static final boolean DEBUG_NODES = true;
// FLAGS
private static final int FLAG_MESSAGE = 0;
private static final int FLAG_CONVERT_CSV_TO_XML = 1;
// CONSTANTS
private static final String TEMPORARY_FOLDER_PATH = "/tmp";
private static final String TEMP_CSV_FILENAME = "csvToConvertToXml.csv";
private static final String TEMP_XML_FILENAME = "xmlOfCsv.xml";
// MEMBERS
private int serverPort;
private ServerSocket mServerSocket = null;
private Socket mSocket;
private InputStream mSocketInput;
private OutputStream mSocketOutput;
private int mSocketFlag;
private String mPathToCsv;
public SocketServer(int serverPort)
{
this.serverPort = serverPort;
try
{
mServerSocket = new ServerSocket(serverPort);
}
catch (IOException e)
{
e.printStackTrace(System.err);
}
}
public void waitForConnections()
{
mSocket = null;
mSocketInput = null;
mSocketOutput = null;
while (true)
{
// Open a Socket on the Server and Wait for a Connection
openSocket();
// TODO CODE THE FLAGGING
mSocketFlag = 1;
switch (mSocketFlag) {
case FLAG_MESSAGE:
handleConnection();
break;
case FLAG_CONVERT_CSV_TO_XML:
handleFileConversionConnection();
break;
}
// Now close the socket.
closeSocket();
}
}
// All this method does is wait for some bytes from the
// connection, read them, then write them back again, until the
// socket is closed from the other side.
public void handleFileConversionConnection()
{
while(true)
{
byte[] buffer = new byte[1024];
int bytes_read = 0;
try
{
// This call to read() will wait forever, until the
// program on the other side either sends some data,
// or closes the socket.
bytes_read = mSocketInput.read(buffer, 0, buffer.length);
// If the socket is closed, sockInput.read() will return -1.
if(bytes_read < 0)
{
System.err.println("Tried to read from socket, read() returned < 0, Closing socket.");
return;
}
// Set the mPathToCsv
mPathToCsv = new String(buffer, 0, bytes_read);
// Log the RECIEVED DATA
System.out.println("Server Received "+ bytes_read +" bytes, data=" + mPathToCsv);
System.out.println("mPathToCsv: " + mPathToCsv);
// Get the a the path supplied by the Client and save it in the /temp folder on the server
String pathToTempCsv = getFileFromClient(mPathToCsv,TEMPORARY_FOLDER_PATH, TEMP_CSV_FILENAME);
// Convert the Csv to XML
String pathToXmlForClient = convertCsvToXml(pathToTempCsv, TEMPORARY_FOLDER_PATH, TEMP_XML_FILENAME);
// Transfer the new XML Document to the Client
//transfer(pathToXmlForClient);
//
mSocketOutput.write(buffer, 0, bytes_read);
// This call to flush() is optional - we're saying go
// ahead and send the data now instead of buffering it.
mSocketOutput.flush();
}
catch (Exception e)
{
System.err.println("Exception reading from/writing to socket, e="+e);
e.printStackTrace(System.err);
return;
}
}
}
// All this method does is wait for some bytes from the
// connection, read them, then write them back again, until the
// socket is closed from the other side.
public void handleConnection()
{
while(true)
{
byte[] buffer = new byte[1024];
int bytes_read = 0;
try
{
// This call to read() will wait forever, until the
// program on the other side either sends some data,
// or closes the socket.
bytes_read = mSocketInput.read(buffer, 0, buffer.length);
// If the socket is closed, sockInput.read() will return -1.
if(bytes_read < 0)
{
System.err.println("Tried to read from socket, read() returned < 0, Closing socket.");
return;
}
System.out.println("Server Received "+ bytes_read +" bytes, data=" + (new String(buffer, 0, bytes_read)));
mSocketOutput.write(buffer, 0, bytes_read);
// This call to flush() is optional - we're saying go
// ahead and send the data now instead of buffering it.
mSocketOutput.flush();
}
catch (Exception e)
{
System.err.println("Exception reading from/writing to socket, e="+e);
e.printStackTrace(System.err);
return;
}
}
}
public void openSocket() {
try
{
// This method call, accept(), blocks and waits
// (forever if necessary) until some other program
// opens a socket connection to our server. When some
// other program opens a connection to our server,
// accept() creates a new socket to represent that
// connection and returns.
mSocket = mServerSocket.accept();
System.err.println("Have accepted new socket.");
// From this point on, no new socket connections can
// be made to our server until accept() is called again.
mSocketInput = mSocket.getInputStream();
mSocketOutput = mSocket.getOutputStream();
}
catch (IOException e)
{
e.printStackTrace(System.err);
}
}
public void closeSocket() {
try
{
System.err.println("Closing socket.");
mSocket.close();
}
catch (Exception e)
{
System.err.println("Exception while closing socket.");
e.printStackTrace(System.err);
}
System.err.println("Finished with socket, waiting for next connection.");
}
// CONVENIENCE METHODS
public void transfer(String sfile) throws IOException {
if (DEBUG && DEBUG_NODES) System.out.println("Enter transfer(String sfile)");
// Create a new File object
File myFile = new File(sfile);
while (true) {
byte[] mybytearray = new byte[(int) myFile.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));
bis.read(mybytearray, 0, mybytearray.length);
// Get the OutputStream for the Socket
mSocketOutput.write(mybytearray, 0, mybytearray.length);
mSocketOutput.flush();
// Close the socket
bis.close();
}
}
public String getFileFromClient(String pathToFile, String destinationDirectory, String newFilename) {
if (DEBUG && DEBUG_NODES) System.out.println("Enter getFileFromClient(String pathToFile, String destinationDirectory, String newFilename)");
String pathToNewFile = destinationDirectory + "/" + newFilename;
// TODO GET THE FILE FROM THE CLIENT
if (DEBUG && DEBUG_NODES) System.out.println("Exit getFileFromClient(String pathToFile, String destinationDirectory, String newFilename)");
return pathToNewFile;
}
public String convertCsvToXml(String pathToCsv, String pathToDestinationDirectory, String newFilename) {
if (DEBUG && DEBUG_NODES) System.out.println("Enter convertCsvToXml(String pathToCsv, String pathToDestinationDirectory, String newFilename)");
String pathToNewFile = pathToDestinationDirectory + "/" + newFilename;
// TODO CREATE THE NEW FILE AND CONVERT THE CSV TO XML
XMLWriter xmlFile = new XMLWriter(pathToCsv, pathToNewFile);
xmlFile.csvToXml();
if (DEBUG && DEBUG_NODES) System.out.println("Exit convertCsvToXml(String pathToCsv, String pathToDestinationDirectory, String newFilename)");
return pathToNewFile;
}
public static void main(String argv[])
{
int port = 54321;
SocketServer server = new SocketServer(port);
server.waitForConnections();
}
}
SocketClient.java
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class SocketClient
{
// CONSTANTS
public static final int TRANSFER_SIZE_1KB = 1024;
// MEMBERS
private String mServerHostname = null;
private int mServerPort = 0;
private byte[] data = null;
private Socket mSocket = null;
private InputStream mSocketInput = null;
private OutputStream mSocketOutput = null;
public SocketClient(String ServerHostname, int ServerPort)
{
this(ServerHostname, ServerPort, null);
}
public SocketClient(String mServerHostname, int mServerPort, byte[] data)
{
this.mServerHostname = mServerHostname;
this.mServerPort = mServerPort;
this.data = data;
}
public void transfer( String outfile ) throws Exception {
// Open the Socket
openSocket();
// Create a new byte array size of 1KB
byte[] bytearray = new byte[TRANSFER_SIZE_1KB];
// Create a bufferedOutputStream from the outfile path
FileOutputStream fos = new FileOutputStream(outfile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
// TESTING
fos.toString();
// Initialize values to 0
int bytesRead = 0;
int count = 0;
System.out.println("GOT HERE");
// Transfer the 'outfile' 1KB (1024 bytes) increments, each pass is 1KB chunk of files
while ((bytesRead = mSocketInput.read(bytearray, 0, bytearray.length)) != -1)
{
System.out.println("GOT HERE");
// Send the data to the Server
bos.write(bytearray, 0, bytesRead);
// If less than 1KB, finish the transfer using flush()
bos.flush();
System.out.println(++count);
}
// Log to console
System.out.println("Finished transferring " + outfile);
// Close the bufferedOutputStream
bos.close();
// Close the socket
closeSocket();
}
public void sendSomeMessages(int iterations)
{
// Open the Socket
openSocket();
byte[] buf = new byte[data.length];
int bytes_read = 0;
for(int x=1; x<=iterations; x++)
{
try
{
mSocketOutput.write(data, 0, data.length);
bytes_read = mSocketInput.read(buf, 0, buf.length);
}
catch (IOException e)
{
e.printStackTrace(System.err);
}
if( bytes_read != data.length )
{
System.out.println("run: Sent "+ data.length +" bytes, server should have sent them back, read "+bytes_read+" bytes, not the same number of bytes.");
}
else
{
System.out.println("Client Sent "+bytes_read+" bytes to server and received them back again, msg = "+(new String(data)));
}
// Sleep for a bit so the action doesn't happen to fast -
// this is purely for reasons of demonstration, and not required technically.
try { Thread.sleep(50);}
catch (Exception e) {};
}
System.err.println("Done reading/writing to/from socket, closing socket.");
// Close the Socket
closeSocket();
}
public void sendMessage(String str) {
// Open the Socket
openSocket();
// Convert the String to a Byte Array
byte[] data = str.getBytes();
// Create a buffer object the size of the data byte array
byte[] buf = new byte[data.length];
int bytes_read = 0;
// Attempt to send the data over the network
try
{
mSocketOutput.write(data, 0, data.length);
bytes_read = mSocketInput.read(buf, 0, buf.length);
}
catch (IOException e)
{
e.printStackTrace(System.err);
}
if( bytes_read != data.length )
{
System.out.println("run: Sent "+ data.length +" bytes, server should have sent them back, read "+bytes_read+" bytes, not the same number of bytes.");
}
else
{
System.out.println("Client Sent "+bytes_read+" bytes to server and received them back again, msg = "+(new String(data)));
}
// Sleep for a bit so the action doesn't happen to fast -
// this is purely for reasons of demonstration, and not required technically.
try { Thread.sleep(50);}
catch (Exception e) {};
System.err.println("Done reading/writing to/from socket, closing socket.");
// Close the Socket
closeSocket();
}
public void openSocket() {
// Open the Socket
System.err.println("Opening connection to "+mServerHostname+" port "+mServerPort);
try
{
mSocket = new Socket(mServerHostname, mServerPort);
mSocketInput = mSocket.getInputStream();
mSocketOutput = mSocket.getOutputStream();
}
catch (IOException e)
{
e.printStackTrace(System.err);
return;
}
System.err.println("About to start reading/writing to/from socket.");
}
public void closeSocket() {
// Close the Socket
try
{
mSocket.close();
}
catch (IOException e)
{
System.err.println("Exception closing socket.");
e.printStackTrace(System.err);
}
System.err.println("Exiting.");
}
// GETTERS & SETTERS
public String getServerHostname() {
return mServerHostname;
}
public void setServerHostname(String serverHostname) {
this.mServerHostname = mServerHostname;
}
public int getServerPort() {
return mServerPort;
}
public void setServerPort(int serverPort) {
this.mServerPort = mServerPort;
}
public Socket getSocket() {
return mSocket;
}
public void setSocket(Socket socket) {
this.mSocket = mSocket;
}
public InputStream getSocketInput() {
return mSocketInput;
}
public void setSocketInput(InputStream socketInput) {
this.mSocketInput = mSocketInput;
}
public OutputStream getSocketOutput() {
return mSocketOutput;
}
public void setSocketOutput(OutputStream socketOutput) {
this.mSocketOutput = mSocketOutput;
}
}
SUPPORTING CLASSES
ConsoleController.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Comparator;
#SuppressWarnings("unused")
public abstract class ConsoleController {
// DEBUG
private static final boolean DEBUG = false;
private static final boolean DEBUG_STORE = false;
private static final boolean DEBUG_PROMPT = false;
private static final boolean DEBUG_VALUES = false;
// CONSTANTS
protected static final String DEFAULT_MESSAGE = "No input recieved";
// MEMBERS
private String mRecentInput;
// CONSTRUCTORS
public ConsoleController() {
mRecentInput = DEFAULT_MESSAGE;
}
// LIFE-CYCLE METHODS
abstract public void onCreate();
public String promptUser(String userPrompt) {
System.out.println(userPrompt);
try{
// Create BufferedReader to read from the Console
BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
// Read the line from the console
mRecentInput = bufferRead.readLine();
if (mRecentInput.equalsIgnoreCase("Exit")) exit();
}
catch(IOException e)
{
e.printStackTrace();
}
return mRecentInput;
}
public String getInput() {
return mRecentInput;
}
public void exit() {
//System.out.println("Quiting");
System.exit(0);
}
}
Regex.java
import java.util.regex.Matcher;
import java.util.regex.Pattern;
#SuppressWarnings("unused")
public class Regex {
public static final boolean DEBUG = false;
public static final boolean DEBUG_HAS_EXT = true;
public static boolean hasExtension(String path, String extension) {
// Match Numberic and Hexadecimal Values
Pattern extTest = Pattern.compile("\\.(" + extension.trim() + ")$");
Matcher values = extTest.matcher(path);
if (DEBUG && DEBUG_HAS_EXT) {
System.out.println("Regex - Extension Matches");
System.out.println("Search String: " + path);
System.out.println("Pattern: " + extTest.pattern());
System.out.print("Match: ");
}
// Returns true if there is anotherMatch remaining, returns false if no matches remain
boolean anotherMatch = values.find();
if (anotherMatch == true) {
while(anotherMatch) {
// If we get here, there is a match
// Log
if (DEBUG && DEBUG_HAS_EXT) System.out.println(values.group());
// Check to see if there is anotherMatch
anotherMatch = values.find();
}
return true;
} else {
if (DEBUG && DEBUG_HAS_EXT) System.out.println("There was no match");
return false;
}
}
}
XMLWriter.java
import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
public class XMLWriter
{
// Members
private Document mDocumentForOutput;
private String mInFilePath;
private String mOutFilePath;
// CONSTRUCTORS
public XMLWriter(String filePathForConversion, String filePathForOutput) {
mInFilePath = filePathForConversion;
mOutFilePath = filePathForOutput;
try {
mDocumentForOutput = createDocument();
} catch (Exception e) {
System.out.println("Exception: ");
e.printStackTrace();
}
}
public Document createDocument() throws IOException, ParserConfigurationException
{
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = builderFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
return doc;
}
public void processDocument(String delimeter) throws Exception
{
// Get a File object from the InPath
File inFile = new File(mInFilePath);
// Create a BufferedReader from the file
BufferedReader reader = new BufferedReader(new FileReader(inFile));
// Read a line from the file
String sline = reader.readLine();
//
String[] sheaders = sline.split(delimeter);
sline = reader.readLine();
String[] snodes = sline.split(delimeter);
Element aroot;
Element achild;
aroot = mDocumentForOutput.createElement(sheaders[0].trim());
mDocumentForOutput.appendChild(aroot);
while ((sline=reader.readLine()) != null)
{
achild = mDocumentForOutput.createElement(sheaders[1].trim());
String[] sdata = sline.split(delimeter);
for (int x=0; x<snodes.length; ++x)
{
Element c = mDocumentForOutput.createElement(snodes[x].trim());
c.appendChild(mDocumentForOutput.createTextNode(sdata[x].trim()));
achild.appendChild(c);
}
aroot.appendChild(achild);
}
}
public void createXML() throws Exception
{
//TransformerFactory instance is used to create Transformer objects.
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
// create string from xml tree
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(mDocumentForOutput);
transformer.transform(source, result);
String xmlString = sw.toString();
File file = new File(mOutFilePath);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
bw.write(xmlString);
bw.flush();
bw.close();
}
public void createXmlDocument(String delimeter) throws Exception
{
processDocument(delimeter);
createXML();
}
public void csvToXml() {
try {
createXmlDocument(",");
} catch (Exception e) {
System.out.print("Exception: ");
e.printStackTrace();
}
}
public static void testWriter(String csvFile)
{
try
{
try {
XMLWriter xmlWriter = new XMLWriter(csvFile, "Output.xml");
xmlWriter.csvToXml();
} catch (Exception e) {
System.out.println("'" + csvFile + "' does not exist in the given directory! Please check that you have properly entered your filepath");
}
System.out.println("<b>Xml File Created Successfully</b>");
}
catch(Exception e)
{
System.out.println(e);
}
}
}
I'm a beginner at java and also for socket programming.
This program I've written is aimed to allow p2p file synchronisation between client and server.
When a peer establishes a TCP connection with another peer, both of them will compare the lists of files they possess and proceed to exchange files so that they both have exactly the
same files. A TCP connection must remain open until the peer process is manually terminated at either end of the connection.
I've looked at online tutorials and similar programs to write the code for this program. However, after running the server, the following error is shown on the console when I run the client.
IOException: java.net.ConnectException: Connection timed out: connect
Please advice me on how I could solve the error. Thanks so much in advance!
Here is my code for reference.
Server:
package bdn;
import java.net.*;
import java.io.*;
import java.util.*;
public class MultipleSocketServer extends Thread{
// private Socket connection;
private String TimeStamp;
private int ID;
static int port = 6789;
static ArrayList<File> currentfiles = new ArrayList<File>();
static ArrayList<File> missingsourcefiles = new ArrayList<File>();
public static void main(String[] args)
{
File allFiles = new File("src/bdn/files");
if (!allFiles.exists()) {
if (allFiles.mkdir()) {
System.out.println("Directory is created.");
}
}
//Load the list of files in the directory
listOfFiles(allFiles);
try {
new MultipleSocketServer().startServer();
} catch (Exception e) {
System.out.println("I/O failure: " + e.getMessage());
e.printStackTrace();
}
}
public static void listOfFiles(final File folder){
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listOfFiles(fileEntry);
} else {
//System.out.println(fileEntry.getName());
currentfiles.add(fileEntry.getAbsoluteFile());
}
}
}
public void startServer() throws Exception {
ServerSocket serverSocket = null;
boolean listening = true;
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
System.err.println("Could not listen on port: " + port);
System.exit(-1);
}
while (listening) {
handleClientRequest(serverSocket);
}
//serverSocket.close();
}
private void handleClientRequest(ServerSocket serverSocket) {
try {
new ConnectionRequestHandler(serverSocket.accept()).run();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Handles client connection requests.
*/
public class ConnectionRequestHandler implements Runnable{
private Socket _socket = null;
public ConnectionRequestHandler(Socket socket) {
_socket = socket;
}
public void run() {
System.out.println("Client connected to socket: " + _socket.toString());
try {
ObjectOutputStream oos = new ObjectOutputStream (_socket.getOutputStream());
oos.flush();
oos.writeObject(currentfiles); //sending to client side.
oos.flush();
} catch (IOException e) {
e.printStackTrace();
}
syncMissingFiles();
}
#SuppressWarnings("unchecked")
public void syncMissingFiles(){
try {
ObjectInputStream ois = new ObjectInputStream(_socket.getInputStream());
System.out.println("Is the socket connected="+_socket.isConnected());
missingsourcefiles= (ArrayList<File>) ois.readObject();
System.out.println(missingsourcefiles);
//add missing files to current file list.
ListIterator<File> iter = missingsourcefiles.listIterator();
File temp_file;
while (iter.hasNext()) {
// System.out.println(iter.next());
temp_file = iter.next();
currentfiles.add(temp_file);
}
} catch (IOException e) {
e.printStackTrace();
} catch ( ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
Client:
package bdn;
import java.net.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.ListIterator;
/* The java.io package contains the basics needed for IO operations. */
import java.io.*;
public class SocketClient {
/** Define a port */
static int port = 2000;
static Socket peer_socket = null;
static String peerAddress;
static ArrayList<File> currentfiles = new ArrayList<File>();
static ArrayList<File> sourcefiles = new ArrayList<File>();
static ArrayList<File> missingsourcefiles = new ArrayList<File>();
static ArrayList<File> missingcurrentfiles = new ArrayList<File>();
SocketClient(){}
public static void listOfFiles(final File folder) {
for (final File fileEntry : folder.listFiles()) {
if (fileEntry.isDirectory()) {
listOfFiles(fileEntry);
} else {
//System.out.println(fileEntry.getName());
currentfiles.add(fileEntry.getAbsoluteFile());
}
}
}
#SuppressWarnings("unchecked")
public static void getListfromPeer() {
try {
ObjectInputStream inList =new ObjectInputStream(peer_socket.getInputStream());
sourcefiles = (ArrayList<File>) inList.readObject();
} catch (ClassNotFoundException e) {
System.err.println("Error in data type.");
}catch (IOException classNot){
System.err.println("Error in data type.");
}
}
public static void compareList1() {
//Compare the source files and current files. If not in current files, add the files to "missingcurrentfiles".
ListIterator<File> iter = sourcefiles.listIterator();
File temp_file;
while (iter.hasNext()) {
// System.out.println(iter.next());
temp_file = iter.next();
if (!currentfiles.contains(temp_file)) //file cannot be found
{
missingcurrentfiles.add(temp_file);
}
}
}
public static void compareList2() {
//Compare the source files and current files. If not in current files, add the files to "missingsourcefiles".
ListIterator<File> iter = currentfiles.listIterator();
File temp_file;
while (iter.hasNext()) {
// System.out.println(iter.next());
temp_file = iter.next();
if (!sourcefiles.contains(temp_file)) //file cannot be found
{
missingsourcefiles.add(temp_file);
}
}
}
public static void main(String[] args) {
//Make file lists of the directory in here.
File allFiles = new File("src/bdn/files");
if (!allFiles.exists()) {
if (allFiles.mkdir()) {
System.out.println("Directory is created.");
}
}
/*Get the list of files in that directory and store the names in array*/
listOfFiles(allFiles);
/*Connect to peer*/
try {
new SocketClient().transfer();
//new TcpClient().checkForInput();
} catch (Exception e) {
System.out.println("Failed at main" + e.getMessage());
e.printStackTrace();
}
}
public void transfer(){
getPeerAddress();
// StringBuffer instr = new StringBuffer();
// String TimeStamp;
try {
/** Obtain an address object of the server */
// InetAddress address = InetAddress.getByName(host);
// System.out.println("Address of connected host:"+ address);
/** Establish a socket connection */
Socket connection = new Socket(peerAddress, port);
System.out.println("New SocketClient initialized");
getListfromPeer();
compareList1();
compareList2();
System.out.println(missingcurrentfiles);
System.out.println(missingsourcefiles);
/** Instantiate a BufferedOutputStream object */
// BufferedOutputStream bos = new BufferedOutputStream(connection.getOutputStream());
/** Instantiate an ObjectOutputStream*/
ObjectOutputStream oos = new ObjectOutputStream(connection.getOutputStream());
oos.flush();
/*
TimeStamp = new java.util.Date().toString();
String process = "Calling the Socket Server on "+ host + " port " + port +
" at " + TimeStamp + (char) 13;
*//** Write across the socket connection and flush the buffer *//*
oos.writeObject(process);
oos.flush();*/
oos.writeObject(missingsourcefiles);
oos.flush();
System.out.println("Missing files in source sent back.");
}
catch (IOException f) {
System.out.println("IOException: " + f);
}
catch (Exception g) {
System.out.println("Exception: " + g);
}
}
public void syncMissingFiles(){
//add missing files to current file list.
ListIterator<File> iter = missingcurrentfiles.listIterator();
File temp_file;
while (iter.hasNext()) {
// System.out.println(iter.next());
temp_file = iter.next();
currentfiles.add(temp_file);
}
}
public static void getPeerAddress() {
// prompt the user to enter the client's address
System.out.print("Please enter the IP address of the client :");
// open up standard input
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// read the IP address from the command-line
try {
peerAddress = br.readLine();
} catch (IOException ioe) {
System.out.println("IO error trying to read client's IP address!");
System.exit(1);
}
System.out.println("Thanks for the client's IP address, " + peerAddress);
}
}
From what I've noticed, and I'm not an expert, you set your server to listen on port 6789 while your client connect to port 2000.
They should both work on the same port.
Try do the following in your client constructor.
SocketClient(String servername){
//while port is same as server port
peer_socket = new Socket(servername, port);
}
You can set servername in your main to be "localhost" in case you are working locally
Also, I would recommand to verify the port you are working on is not blocked by any firewall existing on your machine.