Java Peer-to-Peer networking application - homework - java

I'm creating a p2p application in Java for file sharing. Each peer node will be running on my machine on a different port and listen for a request. but the problem I'm running into is when an instance of PeerNode is created my code runs into an infinite loop. Following is my code for PeerNode. Is this how I should create each node and have them listen for incoming requests?
Following code represents one peer node:
public class PeerNode
{
private int port;
private ArrayList<PeerNode> contacts;
PeerNode preNode;
PeerNode postNode;
private String directoryLocation = "";
PeerNode(int port)
{
this.port = port;
this.setDirectoryLocation( port+"");
startClientServer( port );
}
private void sendRequest(String fileName, String host, int port) throws UnknownHostException, IOException
{
Socket socket = new Socket(host, port);//machine name, port number
PrintWriter out = new PrintWriter( socket.getOutputStream(), true );
out.println(fileName);
out.close();
socket.close();
}
private void startClientServer( int portNum )
{
try
{
// Establish the listen socket.
ServerSocket server = new ServerSocket( 0 );
System.out.println("listening on port " + server.getLocalPort());
while( true )
{
// Listen for a TCP connection request.
Socket connection = server.accept();
// Construct an object to process the HTTP request message.
HttpRequestHandler request = new HttpRequestHandler( connection );
// Create a new thread to process the request.
Thread thread = new Thread(request);
// Start the thread.
thread.start();
System.out.println("Thread started for "+ portNum);
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
And following class creates all the nodes and connects them:
public class MasterClientServer
{
public static void main( String [] args )
{
int count = 10;
ArrayList<PeerNode> arrayOfNodes = createNodes( count );
}
public static ArrayList<PeerNode> createNodes( int count)
{
System.out.println("Creating a network of "+ count + " nodes...");
ArrayList< PeerNode > arrayOfNodes = new ArrayList<PeerNode>();
for( int i =1 ; i<=count; i++)
{
arrayOfNodes.add( new PeerNode( 0 ) ); //providing 0, will take any free node
}
return arrayOfNodes;
}
}
public class HttpRequestHandler implements Runnable
{
final static String CRLF = "\r\n";
Socket socket;
public HttpRequestHandler(Socket socket) throws Exception
{
this.socket = socket;
}
#Override
public void run()
{
try
{
processRequest();
}
catch (Exception e)
{
System.out.println(e);
}
}
/*
* Gets a request from another node.
* Sends the file to the node if available.
*/
private void processRequest() throws Exception
{
/*DataOutputStream os = new DataOutputStream(socket.getOutputStream());
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
// Get the request line of the HTTP request message.
String requestLine = br.readLine();
// Extract the filename from the request line.
// In Get request, the second token is the fie name
String[] tokens = requestLine.split(" ");
String fileName = tokens[1];
// Prepend a "." so that file request is within the current directory.
fileName = "." + fileName;
// Open the requested file.
FileInputStream fis = null;
boolean fileExists = true;
try
{
fis = new FileInputStream(fileName);
}
catch (FileNotFoundException e)
{
fileExists = false;
}
// construct the response Message
// Construct the response message.
String statusLine = null;
String contentTypeLine = null;
String entityBody = null;
if (fileExists)
{
statusLine = "HTTP/1.1 200 OK" + CRLF;
contentTypeLine = "Content-Type: " + contentType(fileName) + CRLF;
}
else
{
statusLine = "HTTP/1.1 404 Not Found" + CRLF;
contentTypeLine = "Content-Type: text/html" + CRLF;
entityBody = "<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD><BODY>Error 404: Page Not Found</BODY></HTML>";
}
// Send the status line.
os.writeBytes(statusLine);
// Send the content type line.
os.writeBytes(contentTypeLine);
// Send a blank line to indicate the end of the header lines.
os.writeBytes(CRLF);
// Send the entity body.
if (fileExists) {
sendBytes(fis, os);
fis.close();
} else {
os.writeBytes(entityBody);
}
// Close streams and socket.
os.close();
br.close();
socket.close();
}
private static void sendBytes(FileInputStream fis, OutputStream os)
throws Exception
{
// Construct a 1K buffer to hold bytes on their way to the socket.
byte[] buffer = new byte[1024];
int bytes = 0;
// Copy requested file into the socket's output stream.
while ((bytes = fis.read(buffer)) != -1) {
os.write(buffer, 0, bytes);
}*/
}
private static String contentType(String fileName)
{
if (fileName.endsWith(".htm") || fileName.endsWith(".html"))
{
return "text/html";
}
if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg"))
{
return "image/jpeg";
}
if (fileName.endsWith(".gif")) {
return "image/gif";
}
if (fileName.endsWith(".ram") || fileName.endsWith(".ra"))
{
return "audio/x-pn-realaudio";
}
return "application/octet-stream";
}
}

Your PeerNode constructor never returns since it is busy accepting new connections. Hence your loop in createNodes only creates the first PeerNode instance. You can solve this by calling startClientServer in a new thread:
new Thread(new Runnable() {
public void run() {
startClientServer( port );
}
}.start();

Related

What is run() function doing in ProxyThread class if is not called anywhere?

This is the class containing the main() method:
public class MultithreadedProxyServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
boolean listening = true;
int port = 10000; //default
try {
port = Integer.parseInt(args[0]);
} catch (Exception e) {
//ignore me
System.out.println("gnore");
}
try {
serverSocket = new ServerSocket(port);
System.out.println("Started on: " + port);
} catch (IOException e) {
System.err.println("Could not listen on port: " + args[0]);
System.exit(-1);
}
while (listening) {
new ProxyThread(serverSocket.accept()).start();
}
serverSocket.close();
}
}
And this is the ProxyThread class:
public class ProxyThread extends Thread {
private Socket socket = null;
private static final int BUFFER_SIZE = 32768;
public ProxyThread(Socket socket) {
super("ProxyThread");
this.socket = socket; //initialzed my parent before you initalize me
}
public void run() {
//get input from user
//send request to server
//get response from server
//send response to user
System.out.println("run");
try {
DataOutputStream out =
new DataOutputStream(socket.getOutputStream());
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String inputLine, outputLine;
int cnt = 0;
String urlToCall = "";
///////////////////////////////////
//begin get request from client
while ((inputLine = in.readLine()) != null) {
try {
StringTokenizer tok = new StringTokenizer(inputLine);
tok.nextToken();
} catch (Exception e) {
System.out.println("break");
break;
}
//parse the first line of the request to find the url
if (cnt == 0) {
String[] tokens = inputLine.split(" ");
urlToCall = tokens[1];
//can redirect this to output log
System.out.println("Request for : " + urlToCall);
}
cnt++;
}
//end get request from client
///////////////////////////////////
BufferedReader rd = null;
try {
//System.out.println("sending request
//to real server for url: "
// + urlToCall);
///////////////////////////////////
//begin send request to server, get response from server
URL url = new URL(urlToCall);
URLConnection conn = url.openConnection();
conn.setDoInput(true);
//not doing HTTP posts
conn.setDoOutput(false);
//System.out.println("Type is: "
//+ conn.getContentType());
//System.out.println("content length: "
//+ conn.getContentLength());
//System.out.println("allowed user interaction: "
//+ conn.getAllowUserInteraction());
//System.out.println("content encoding: "
//+ conn.getContentEncoding());
//System.out.println("content type: "
//+ conn.getContentType());
// Get the response
InputStream is = null;
HttpURLConnection huc = (HttpURLConnection)conn;
if (conn.getContentLength() > 0) {
is = conn.getInputStream();
rd = new BufferedReader(new InputStreamReader(is));
}
//end send request to server, get response from server
///////////////////////////////////
///////////////////////////////////
//begin send response to client
byte by[] = new byte[ BUFFER_SIZE ];
int index = is.read( by, 0, BUFFER_SIZE );
while ( index != -1 )
{
out.write( by, 0, index );
index = is.read( by, 0, BUFFER_SIZE );
}
out.flush();
//end send response to client
///////////////////////////////////
} catch (Exception e) {
//can redirect this to error log
System.err.println("Encountered exception: " + e);
//encountered error - just send nothing back, so
//processing can continue
out.writeBytes("");
}
//close out all resources
if (rd != null) {
rd.close();
}
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I have copy-pasted the above code from the internet, however I am having difficulties running it.
To answer the question from the post title, the run() method from ProxyThread class is called by JVM, after the thread has been started new ProxyThread(serverSocket.accept()).start(); and it usually contains the actual work that a thread should performed (in this case, it handles whatever the server socket receives and it accepts a connection from a client).
The moment when JVM calls run() method cannot be controlled by the programmer, but is after the thread has been started.
run() method is never called explicitly by the programmer.

Java Socket : java.net.SocketTimeoutException: Read timed out

Hi I hope you guys are doing great.
I'm currently trying to test a service class that creates a socket connection to a print server.
Here's the service class :
public class PrintServiceImpl implements PrintService {
private static final Logger LOGGER = LoggerFactory.getLogger(PrintServiceImpl.class);
static final int TIMEOUT_MILLISECOND = 20000;
#Override
public boolean sendLabelToPrintServer(String hostname, int port, String labelData) {
Socket clientSocket = null;
DataOutputStream outToServer = null;
Boolean successful;
try {
// open the connection to the printing server
clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress(hostname, port), TIMEOUT_MILLISECOND);
clientSocket.setSoTimeout(TIMEOUT_MILLISECOND);
outToServer = new DataOutputStream(clientSocket.getOutputStream());
// send data to print
outToServer.writeBytes(labelData);
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(),
StandardCharsets.UTF_8));
// Read HTTP Request CHARACTER BY CHARACTER instead of line by line
while ((char) input.read() != 0 && (char) input.read() != '\r') {
LOGGER.debug("Getting print server answer.");
}
successful = true;
LOGGER.debug("Label printed.");
} catch (Exception e) {
LOGGER.error("Printing failed.", e);
successful = false;
} finally {
try {
// close connection
if (outToServer != null) {
outToServer.close();
}
if (clientSocket != null) {
clientSocket.close();
}
} catch (IOException e) {
LOGGER.error("Exception while closing DataOutputStream/ClientSocket.", e);
}
}
return successful;
}
And here's my test class. As you can see the #Before method instantiates a SocketServer on a new Thread.
public class PrintServiceImplTest {
private static final Logger LOGGER = LoggerFactory.getLogger(PrintServiceImplTest.class);
PrintServiceImpl whfPrintService = new PrintServiceImpl();
private static final String LOCALHOST = "localhost";
private static final int SERVER_PORT = 3000;
private static final String LABEL_TEXT = "This dummy text is sent to the print server";
private static final String RESPONSE = "Test Label printed correctly";
private ServerSocket server;
private Socket incommingSocket = null;
#Before
public void before() {
Thread myThread = new Thread() {
#Override
public void run() {
try {
server = new ServerSocket(SERVER_PORT);
incommingSocket = server.accept();
} catch (IOException e) {
e.printStackTrace();
}
}
};
myThread.start();
}
#After
public void after() {
try {
incommingSocket.close();
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
#Test
public void returnsTrueIfConnectionSuccessful() {
BufferedReader reader = null;
PrintWriter out = null;
BufferedReader in = null;
String line;
whfPrintService.sendLabelToPrintServer(LOCALHOST, SERVER_PORT, LABEL_TEXT);
try {
in = new BufferedReader(new InputStreamReader(incommingSocket.getInputStream()));
out = new PrintWriter(incommingSocket.getOutputStream());
reader = new BufferedReader(new InputStreamReader(incommingSocket.getInputStream()));
while ((line = reader.readLine()) != null) {
System.out.println("line : " + line);
}
out.write(RESPONSE);
out.flush();
out.close();
in.close();
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
When I run the test, I get a SocketTimoutException. It occurs when the client is reading the response from the server. This line :
while ((char) input.read() != 0 && (char) input.read() != '\r') {
So this means that the client does not receive a response. My guess is that the server does not send a correct response.
What am I missing ? thank you in advance.
Improper server->client response
You response doesn't end with a \0 or a \r.
private static final String RESPONSE = "Test Label printed correctly";
By making your response end with either of those characters, the client will escape from the loop.
private static final String RESPONSE = "Test Label printed correctly\0";
Client reads response incorrectly
The client reads the response using the following code:
while ((char) input.read() != 0 && (char) input.read() != '\r') {
Every call to input.read() returns a new byte from the network. You should call input.read() one time every while loop, and compare after it.
char c;
while (c = (char) input.read()) != -1) {
if(c == 0 || c == '\r') {
break;
}
}
Client to server message has no proper ending
Messages send from the client to server have no ending, the server reads until the socket input is closed, but the client never closes the socket.
// send data to print
outToServer.writeBytes(labelData);
After you wrote those bytes, call socket.shutdownOutput() to signal end of file to the other party.
// send data to print
outToServer.writeBytes(labelData);
clientSocket.shutdownOutput();

java web server program

The goal is to develop a web server that when accessed via a web browser will return the HTTP request message that it receives.
I run the program from a virtual machine environment and access the server from my local machine. The code I have is below. When I type in my IP address while the server is running, I just get a Null Pointer Exception. Any guidance would be greatly appreciated.
import java.io.*;
import java.net.*;
import java.util.*;
public final class proj1 {
public static void main(String[] args) throws Exception{
int port = 9000;
ServerSocket socket = new ServerSocket(port);
while(true) {
Socket connection = socket.accept();
HttpRequest request = new HttpRequest(connection);
Thread thread = new Thread(request);
thread.start();
}
}
}
final class HttpRequest implements Runnable {
//Declare Variables
final static String CRLF = "\r\n";
Socket socket;
//Constructor
public HttpRequest(Socket socket) throws Exception {
this.socket = socket;
}
//Unimplemented Runnable Method
#Override
public void run() {
try {
processRequest();
} catch (Exception e) {
System.out.println(e);
}
}
private void processRequest() throws Exception {
//Reference Socket Input and Output Streams
InputStream is = socket.getInputStream();
DataOutputStream os = null;
//Input Stream Filters
BufferedReader br = new BufferedReader(null);
//Request Line of HTTP Request Message
String requestLine = br.readLine();
//Extract FileName From Request Line
StringTokenizer tokens = new StringTokenizer(requestLine);
tokens.nextToken();
String fileName = tokens.nextToken();
fileName = "." + fileName;
//Open Requested File
FileInputStream fis = null;
boolean fileExists = true;
try {
fis = new FileInputStream(fileName);
} catch (FileNotFoundException e) {
fileExists = false;
}
//Debug
System.out.println(requestLine);
String headerLine = null;
while ((headerLine = br.readLine()).length() != 0) {
System.out.println(headerLine);
}
//Construct Response Message
String statusLine = null;
String contentTypeLine = null;
String entityBody = null;
if (fileExists) {
statusLine = "statusLine";
contentTypeLine = "Content-Type: " + contentType(fileName) + CRLF;
} else {
statusLine = "HTTP/1.0 404 Not Found" + CRLF;
contentTypeLine = "Content-Type: text/html" + CRLF;
entityBody = "<HTML>" + "<HEAD><TITLE>Not Found</TITLE></HEAD>" + "<BODY>Not Found</BODY></HTML>";
}
//Send Lines
os.writeBytes(statusLine);
os.writeBytes(contentTypeLine);
os.writeBytes(CRLF);
//Send Entity Body
if (fileExists) {
sendBytes(fis, os);
fis.close();
} else {
os.writeBytes(entityBody);
}
//Close Streams and Sockets
os.close();
br.close();
socket.close();
}
private static void sendBytes(FileInputStream fis, OutputStream os) throws Exception {
byte[] buffer = new byte[1024];
int bytes = 0;
while ((bytes = fis.read(buffer)) != -1) {
os.write(buffer, 0, bytes);
}
}
private static String contentType(String fileName) {
if (fileName.endsWith(".htm") || fileName.endsWith(".html")) {
return "text/html";
}
return "application/octet-stream";
}
}
Exception in thread "main" java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(Unknown Source)
at java.net.AbstractPlainSocketImpl.bind(Unknown Source)
at java.net.PlainSocketImpl.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at proj1.main(proj1.java:10)
That is the error code when I try to run the program in eclipse... When I run the code in my virtual machine, it runs fine but whenever I access the IP address of the server on my machine, I get no response message and a Null Pointer Exception on the virtual machine.
new BufferedReader(null) will always throw NullPointerException. What did you except?
By the way, this is always a bad idea:
try {
processRequest();
} catch (Exception e) {
System.out.println(e);
}
If you don't know what to do with the exception, at least re-throw it to retain the stack trace:
try {
processRequest();
} catch (Exception e) {
throw new RuntimeException(e);
}
This would have lead you to the line throwing the exception.

How to access a file on a Client from a Server without transferring the file from the Client to the Server in Java

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);
}
}
}

Server socket always return null to the client , Java

I, doing some computer network homework and I have to develop some sort of distributed DBMS which are connected to each other with peer to peer network, so I have a TCP client and a TCP server in one .java file which running next to each other by threads. the TCP Server of the class always listen to the other TCP client from others and give them service, the problem is when I System.out the String which I have to send back to the client on the Server side it's in the way which it's supposed to be but after sending , the client gets nothing and prints null. I wrote my code based on tutorials I found on the net and I when I test them they worked well but it's not working in my own code. could you see where my problem is? thanks
class CommandComp
{
int PORT = 1210;
int PORT2 = 1211;
String IPLocal = "";
String IPdest = "";
InetAddress IPAD;
InetAddress IPAD2;
int numOfNodes;
int numOfNodesnonchanged;
String[] Nodes;
Random rand = new Random();
int max = 2000;
int min = 1000;
String command;
Socket clientSocket;
CommandComp(String[] IPdest, String IPLocal, int numOfNodes, String command)
{
try
{
this.numOfNodes = numOfNodes;
numOfNodesnonchanged = numOfNodes;
this.IPLocal = IPLocal;
this.Nodes = IPdest;
this.command = command;
// this.IPAD = InetAddress.getByName(this.IPdest);
this.IPAD2 = InetAddress.getByName(this.IPLocal);
// clientSocket = new Socket(this.IPAD , PORT ,this.IPAD2 , PORT2 );
}
catch (Exception e)
{
// //e.printStackTrace();
}
}
public String call()
{
int i = 0;
while (numOfNodes > 0)
{
String response = "";
try
{
Thread.sleep(rand.nextInt(max - min + 1) + min);
i = numOfNodes - 1;
int max2 = 50;
int min2 = 10;
this.IPAD = InetAddress.getByName(Nodes[i]);
clientSocket = new Socket(this.IPAD, PORT, this.IPAD2, PORT2 + rand.nextInt(max2 - min2 + 1) + min2);
PrintWriter outToServer = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
outToServer.println(command);
System.out.println(inFromServer.readLine());
response = inFromServer.readLine();
outToServer.close();
inFromServer.close();
clientSocket.close();
numOfNodes--;
System.out.println(Nodes[i] + " Remote DBMS");
System.out.println(response);
}
catch (Exception e)
{
e.printStackTrace();
try
{
clientSocket.close();
}
catch (Exception e2)
{
// TODO: handle exception
}
}
}
return command;
}
}
class TCPListnerService
implements Callable<Object>
{
String from;
String to;
ServerSocket Server;
String IP = "";
int numOfNodes;
int numofNodesUnchanged;
static clientThread t[];
TCPListnerService(String IP, int numOfNodes)
{
try
{
this.IP = IP;
this.numOfNodes = numOfNodes;
numofNodesUnchanged = numOfNodes * 2;
this.t = new clientThread[numofNodesUnchanged];
InetAddress IPAD = InetAddress.getByName(IP);
Server = new ServerSocket(1210, 20, IPAD);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public String call()
throws Exception
{
String gotten = "";
while (numOfNodes > 0)
{
Socket connected = Server.accept();
for (int i = 0; i < numofNodesUnchanged; i++)
{
if (t[i] == null)
{
(t[i] = new clientThread(connected)).start();
break;
}
}
}
return gotten;
}
}
class clientThread
extends Thread
{
Socket clientSocket = null;
sqlite DB = new sqlite();
String response = "";
String fromclient;
String delims = "[ =)(',\n\t\r]+";
String[] tokens;
public clientThread(Socket clientSocket)
{
this.clientSocket = clientSocket;
}
public void run()
{
try
{
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter outToClient = new PrintWriter(clientSocket.getOutputStream(), true);
fromclient = inFromClient.readLine();
tokens = fromclient.split(delims);
if (tokens[0].equalsIgnoreCase("create")
|| tokens[0].equalsIgnoreCase("drop")
|| tokens[0].equalsIgnoreCase("delete")
|| tokens[0].equalsIgnoreCase("insert")
|| tokens[0].equalsIgnoreCase("update")
|| tokens[0].equalsIgnoreCase("select"))
{
response = DB.RunQuery(fromclient);
System.out.println(response);
outToClient.print(response);
clientS.close();
}
else if (tokens[0].equalsIgnoreCase("shut"))
{
System.exit(0);
}
inFromClient.close();
outToClient.close();
clientSocket.close();
}
catch (Exception e)
{
}
;
}
}
The problem is here:
inFromClient.close();
outToClient.close();
clientSocket.close();
You are closing (1) the input stream, which closes the socket, (2) the PrintWriter, which flushes it and closes the socket, and (3) the socket. Obviously (2) cannot succeed if the socket is already closed. The data you sent to the client is still buffered, never got flushed, so it never got sent.
Just close the PrintWriter, and close the socket in a finally block in case (2) fails somehow. No need to close the input at all.

Categories

Resources