Upolading a file from server to client with servlet - java

I'm trying to write a servlet, that can upload a file from client to server and download a file from server to client from specific location to specific location. But two problems stopped me:
1. When uploading a file from client to server, how to tell to the server where to store the file?
2. (and more important) How to do the downloading from server to client part?
Here is the code so far:
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server extends Thread {
public static final int PORT = 3333;
public static final int BUFFER_SIZE = 100;
#Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
while (true) {
Socket s = serverSocket.accept();
saveFile(s);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void saveFile(Socket socket) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
FileOutputStream fos = null;
byte [] buffer = new byte[BUFFER_SIZE];
Object o = ois.readObject();
if (o instanceof String) {
fos = new FileOutputStream(o.toString());
} else {
throwException(null);
}
Integer bytesRead = 0;
do {
o = ois.readObject();
if (!(o instanceof Integer)) {
throwException(null);
}
bytesRead = (Integer)o;
o = ois.readObject();
if (!(o instanceof byte[])) {
throwException(null);
}
buffer = (byte[]) o;
fos.write(buffer, 0, bytesRead);
} while (bytesRead == BUFFER_SIZE);
fos.close();
ois.close();
oos.close();
}
public static void throwException(String message) throws Exception {
throw new Exception(message);
}
public static void main(String[] args) {
new Server().start();
}
}
package com.filetransfer.web;
import java.io.*;
import java.net.Socket;
import java.util.Arrays;
import javax.servlet.*;
import javax.servlet.http.*;
public class FileTransfer extends HttpServlet {
private static final long serialVersionUID = 1L;
public static final int PORT = 3333;
public static final int BUFFER_SIZE = 100;
public static final String HOST = "localhost";
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("option");
System.out.println(action);
if ("upload".equals(action)) {
uploadFile(request);
} else if ("download".equals(action)) {
downloadFile(request, response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
public void reportError(HttpServletResponse response, String message) throws IOException {
response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
}
public void uploadFile(HttpServletRequest request) {
String fileLocation = request.getParameter("localfile");
File file = new File(fileLocation);
Socket socket;
try {
socket = new Socket(HOST, PORT);
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(file.getName());
FileInputStream fis = new FileInputStream(file);
byte [] buffer = new byte[BUFFER_SIZE];
Integer bytesRead = 0;
while ((bytesRead = fis.read(buffer)) > 0) {
oos.writeObject(bytesRead);
oos.writeObject(Arrays.copyOf(buffer, buffer.length));
}
oos.close();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void downloadFile(HttpServletRequest request, HttpServletResponse response) {
File file = new File(request.getParameter("remotefile"));
Socket socket;
InputStream inputStream = null;
OutputStream outputStream = null;
try {
socket = new Socket(HOST, PORT);
response.setContentLength((int)file.length());
outputStream = response.getOutputStream();
inputStream = new BufferedInputStream(new FileInputStream(file));
int nextByte;
while ((nextByte = inputStream.read()) != -1) {
outputStream.write(nextByte);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

Since you're using a HTTP servlet, I strongly suggest to use a HTTP client. Don't pass around proprietary and self-invented request/response formats around, but just construct requests and responses according the HTTP protocol. When you adhere a certain transport standard, then there is no doubt that there are several API's and tools available which may ease the job.
In the client side, you can use java.net.URLConnection or Apache HttpClient for this. Sending files over HTTP from client to server (uploading) usually require a multipart/form-data request encoding. Sending files over HTTP from server to client (downloading) usually require just a correct Content-Type header and the entire file as response body.
At the bottom of this answer you can find an example how to upload files by URLConnection (and in this answer an example with Apache HttpClient 4). In this answer you can find an example how to process the uploaded file in servlet. Saving the uploaded file is easy: just write the obtained InputStream to some FileOutputStream. In this article you can find an example how to send the file for download. Saving the downloaded file is also easy, just write URLConnection#getInputStream() to some FileOutputStream.

Related

How to discover why a FileNotFoundException is thrown if the file is in the directory?

This is server side code:
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server extends Thread {
public static final int PORT = portno;
public static final int BUFFER_SIZE = 100;
ServerSocket serverSocket;
#Override
public void run() {
try {
serverSocket = new ServerSocket(PORT);
while (true) {
Socket s = serverSocket.accept();
saveFile(s);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
private void saveFile(Socket socket) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
FileOutputStream fos = null;
byte[] buffer = new byte[BUFFER_SIZE];
// 1. Read file name.
Object o = ois.readObject();
System.out.println("file name is:"+o.toString());
if (o instanceof String) {
fos = new FileOutputStream("D://anmolrishte_files//"+o.toString());
}
else {
throwException("Something is wrong");
}
// 2. Read file to the end.
Integer bytesRead = 0;
do {
o = ois.readObject();
if (!(o instanceof Integer)) {
throwException("Something is wrong");
}
bytesRead = (Integer)o;
o = ois.readObject();
if (!(o instanceof byte[])) {
throwException("Something is wrong");
}
buffer = (byte[])o;
// 3. Write data to output file.
fos.write(buffer, 0, bytesRead);
} while (bytesRead == BUFFER_SIZE);
System.out.println("File transfer success");
fos.close();
ois.close();
oos.close();
}
public static void throwException(String message) throws Exception {
throw new Exception(message);
}
public static void main(String[] args) {
new Server().start();
}*/
public static final int PORT = portno;
public static final int BUFFER_SIZE = 100;
ServerSocket serverSocket;
#Override
public void run() {
try {
serverSocket = new ServerSocket(PORT);
while (true) {
Socket s = serverSocket.accept();
saveFile(s);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
private void saveFile(Socket socket) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
FileOutputStream fos = null;
byte [] buffer = new byte[BUFFER_SIZE];
// 1. Read file name.
Object o = ois.readObject();
System.out.println("file name is:"+o.toString());
if (o instanceof String) {
System.out.println("hello");
fos = new FileOutputStream("D://anmolrishte_files//"+o.toString());
// fos.write(b);
}
else {
throwException("Something is wrong");
}
// 2. Read file to the end.
Integer bytesRead = 0;
do {
o = ois.readObject();
if (!(o instanceof Integer)) {
throwException("Something is wrong");
}
bytesRead = (Integer)o;
System.out.println("hello1");
o = ois.readObject();
if (!(o instanceof byte[])) {
throwException("Something is wrong");
}
buffer = (byte[])o;
// 3. Write data to output file.
fos.write(buffer, 0, bytesRead);
} while (bytesRead == BUFFER_SIZE);
System.out.println("File transfer success");
fos.close();
ois.close();
oos.close();
}
public static void throwException(String message) throws Exception {
throw new Exception(message);
}
public static void main(String[] args) {
new Server().start();
}
}
This is client side code
public class MessageSender extends AsyncTask<Void,Void,Void> {
File file;
private static final String ipAddress = "address";
private static final int port = portno;
private Socket socket;
#Override
protected Void doInBackground(Void... voids) {
file = new File(Environment.getExternalStorageDirectory(), "/123.jpg");
System.out.print(file);
try {
socket = new Socket(ipAddress, port);
ObjectInputStream ois = null;
ois = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream oos = null;
oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(file.getName());
FileInputStream fis = null;
fis = new FileInputStream(file);
byte[] buffer = new byte[100];
Integer bytesRead = 0;
while ((bytesRead = fis.read(buffer)) > 0) {
}
oos.writeObject(bytesRead);
oos.writeObject(Arrays.copyOf(buffer, buffer.length));
oos.close();
ois.close();
}
catch (IOException e) {
e.printStackTrace();
}
System.exit(0);
return null;
}
}
This code is onButtonClick, when we click on button image send to server so I push this code for it.
btn2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
MessageSender messageSender = new MessageSender();
messageSender.execute();
}
Manifest permissions are necessary so I written that
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
FileNotFoundException occurs, but I don't know why. This error is showing in Android Studio:
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/123.jpg (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:146)
at MainActivity$MessageSender.doInBackground(MainActivity.java:167)
at MainActivity$MessageSender.doInBackground(MainActivity.java:148)
at android.os.AsyncTask$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
04-09 11:06:01.166 4148-4204/W/System.err: at java.lang.Thread.run(Thread.java:760)
You are reading your file from a bad path
and the error tells you
no such file or directory
at this path
/storage/emulated/0/123.jpg
so just change your reading path to the correct path.

How to send multiple images using socket programing in java and write on specific path on server side?

I want to send multiple images from client side to server side on different systems in wifi and in server side write this files on specific location.
Thanks in advance.
In Client.java file
public class Client {
public void send(String file_name){
try {
Socket socket = new Socket("IBM-PC", 3332);
File file = new File(file_name);
System.out.println(file_name);
ObjectInputStream ois = new ObjectInputStream(
socket.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(
socket.getOutputStream());
oos.writeObject(file.getName());
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[Server.BUFFER_SIZE];
Integer bytesRead = 0;
while ((bytesRead = fis.read(buffer)) > 0) {
oos.writeObject(bytesRead);
oos.writeObject(Arrays.copyOf(buffer, buffer.length));
}
ois = null;
oos = null;
} catch (Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) throws Exception {
Client c = new Client();
c.send("D://1.jpg"); // first image path
c.send("D://0.jpg"); // second image path
}
}
In Server.Java File
public class Server extends Thread {
public static final int PORT = 3332;
public static final int BUFFER_SIZE = 500102;
#Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
while (true) {
Socket s = serverSocket.accept();
saveFile(s);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void saveFile(Socket socket) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(
socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
FileOutputStream fos = null;
byte[] buffer = new byte[BUFFER_SIZE];
// 1. Read file name.
Object o = ois.readObject();
if (o instanceof String) {
fos = new FileOutputStream("D:\\temp\\"+o.toString()); // Edit it for specific path
System.out.println("D:\\temp\\"+o.toString());
} else {
throwException("Something is wrong");
}
// 2. Read file to the end.
Integer bytesRead = 0;
do {
o = ois.readObject();
if (!(o instanceof Integer)) {
throwException("Something is wrong");
}
bytesRead = (Integer) o;
o = ois.readObject();
if (!(o instanceof byte[])) {
throwException("Something is wrong");
}
buffer = (byte[]) o;
// 3. Write data to output file.
fos.write(buffer, 0, bytesRead);
} while (bytesRead == BUFFER_SIZE);
System.out.println("File transfer success");
fos.close();
ois.close();
oos.close();
}
public static void throwException(String message) throws Exception {
throw new Exception(message);
}
public static void main(String[] args) {
new Server().start();
}
}
First run server.java file and then run client.java file
I hope it'll help you...

Can't accept connection to http server socket

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

how to keep a "Hello World" type server running

How do I keep the server "open" so that it can send and receive objects on a continuing basis without crashing? Basically, I would like to put an infinite loop around the readRecord method, so that it runs indefinitely.
server:
package net.bounceme.dur.driver;
import java.net.*;
import java.io.*;
import java.util.Properties;
import java.util.logging.Logger;
public class Server {
private static final Logger log = Logger.getLogger(Server.class.getName());
private final RecordQueue recordsQueue = new RecordQueue();
public static void main(String[] args) throws IOException {
Properties props = PropertiesReader.getProps();
int portNumber = Integer.parseInt(props.getProperty("port"));
new Server().readRecord(portNumber);
}
public void readRecord(int portNumber) throws IOException {
ServerSocket serverSocket = new ServerSocket(portNumber);
Socket socket = serverSocket.accept();
ObjectOutputStream objectOutputStream = null;
MyRecord recordFromClient = null;
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
while (true) {
try {
recordFromClient = (MyRecord) objectInputStream.readObject();
} catch (ClassNotFoundException e) {
System.out.println(e);
}
objectOutputStream.writeObject(recordFromClient);
}
}
}
client:
package net.bounceme.dur.driver;
import java.net.*;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class Client {
private List<MyRecord> iterate() {
MyRecord myRecord = null;
List<MyRecord> records = new ArrayList<>();
for (int i = 0; i < 9; i++) {
myRecord = new MyRecord(i, "foo");
records.add(myRecord);
}
return records;
}
public void simple(String server, int portNumber) throws IOException, ClassNotFoundException {
Socket s = new Socket(server, portNumber);
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
List<MyRecord> records = iterate();
for (MyRecord record : records) {
oos.writeObject(record);
}
oos.flush();
Object received = ois.readObject();
System.out.println(received);
oos.close();
ois.close();
}
public static void main(String args[]) throws IOException, ClassNotFoundException {
Properties props = PropertiesReader.getProps();
int portNumber = Integer.parseInt(props.getProperty("port"));
String server = (props.getProperty("server"));
new Client().simple(server, portNumber);
}
}
server output:
thufir#dur:~$
thufir#dur:~$ java -jar NetBeansProjects/Server/dist/Server.jar
Exception in thread "main" java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1876)
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1785)
at java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1285)
at java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1230)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1426)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.writeFatalException(ObjectOutputStream.java:1576)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:350)
at net.bounceme.dur.driver.Server.readRecord(Server.java:32)
at net.bounceme.dur.driver.Server.main(Server.java:16)
thufir#dur:~$
client output:
thufir#dur:~$
thufir#dur:~$ java -jar NetBeansProjects/Client/dist/Client.jar
value=0, id='foo
thufir#dur:~$
Okay what your problem is, your server was made to only read and handle one object at a time. So When you client tries to send all of those MyRecord objects, the server reads one, and then tries to send it back to you, the problem is, you are still trying to send the other MyRecord objects while the server is trying to send you the FIRST MyRecord object. Client/Server connections are like a game of tennis. One person must serve the ball to the other player, and the other must then hit the ball back. You cannot both hit a ball with neither of you recieving.
So in,
for (MyRecord record : records) {
oos.writeObject(record);
}
oos.flush();
Object received = ois.readObject();
System.out.println(received);
you should put the
oos.flush();
Object received = ois.readObject();
System.out.println(received);
inside of the for() loop, that way each MyRecord object is sent to the server, read by the server, sent back to the client by the server, and read by the client.
Final result:
for (MyRecord record : records) {
oos.writeObject(record);
oos.flush();
Object received = ois.readObject();
System.out.println(received);
}
See the changes(i edited some code to run on my machine, so make your changes appropriately)
import java.net.*;
import java.io.*;
import java.util.Properties;
import java.util.logging.Logger;
import java.util.ArrayList;
import java.util.List;
class MyRecord implements java.io.Serializable
{
int x;
String y;
MyRecord(int a,String b)
{
x=a;
y=b;
}
}
class Server {
private static final Logger log = Logger.getLogger(Server.class.getName());
//private final RecordQueue recordsQueue = new RecordQueue();
public static void main(String[] args) throws IOException {
//Properties props = PropertiesReader.getProps();
//int portNumber = Integer.parseInt(props.getProperty("port"));
new Server().readRecord(2*1000);
}
public void readRecord(int portNumber) throws IOException {
ServerSocket serverSocket = new ServerSocket(portNumber);
Socket socket = serverSocket.accept();
ObjectOutputStream objectOutputStream = null;
MyRecord recordFromClient = null;
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
while (true) {
try {
recordFromClient = (MyRecord) objectInputStream.readObject();
if(recordFromClient.x==-1) {break;}
} catch (ClassNotFoundException e) {
System.out.println(e);
}
objectOutputStream.writeObject(recordFromClient);
objectOutputStream.flush();
}
}
}
class Client {
private List<MyRecord> iterate() {
MyRecord myRecord = null;
List<MyRecord> records = new ArrayList<>();
for (int i = 0; i < 9; i++) {
myRecord = new MyRecord(i, "foo");
records.add(myRecord);
}
return records;
}
public void simple(String server, int portNumber) throws IOException, ClassNotFoundException {
Socket s = new Socket(server, portNumber);
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
List<MyRecord> records = iterate();
for (MyRecord record : records) {
oos.writeObject(record);
oos.flush();
Object received = ois.readObject();
System.out.println(received);
}
MyRecord record= new MyRecord(-1,"end");
oos.writeObject(record);
oos.flush();
oos.close();
ois.close();
}
public static void main(String args[]) throws IOException, ClassNotFoundException {
//Properties props = PropertiesReader.getProps();
//int portNumber = Integer.parseInt(props.getProperty("port"));
String server = "localhost";
new Client().simple(server, 2000);
}
}
This works to a degree:
package net.bounceme.dur.driver;
//import stuff
public class Server {
private static final Logger log = Logger.getLogger(Server.class.getName());
private final RecordQueue recordsQueue = new RecordQueue();
public static void main(String[] args) {
Properties props = PropertiesReader.getProps();
int portNumber = Integer.parseInt(props.getProperty("port"));
while (true) {
try {
new Server().inOut(portNumber);
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(Server.class.getName()).log(Level.FINE, null, ex);
}
}
}
private List<MyRecord> dummyRecords() {
MyRecord record = null;
List<MyRecord> records = new ArrayList<>();
for (int i = 0; i < 9; i++) {
record = new MyRecord(i, "foo");
records.add(record);
log.info(record.toString());
}
return records;
}
public void inOut(int portNumber) throws IOException, ClassNotFoundException {
ServerSocket serverSocket = new ServerSocket(portNumber);
Socket socket = serverSocket.accept();
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
log.info("...connected...waiting for data...");
MyRecord recordFromClient = (MyRecord) objectInputStream.readObject();
objectOutputStream.writeObject(recordFromClient);
objectOutputStream.flush();
objectInputStream.close();
objectOutputStream.close();
log.info(recordFromClient.toString());//never logs
System.out.println("never gets here");
}
}
except that it never logs the recordFromClient, which is kind of important. On the plus side, it doesn't crash.

Writing a proxy using sockets

I'm writing a HTTP proxy server using sockets, now the program is receiving the request successfully but I'm not able to get it back again to the browser...
import java.io.*;
import java.net.*;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
public class Server {
public void startServer() {
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);
Runnable serverTask = new Runnable() {
#Override
public void run() {
try {
#SuppressWarnings("resource")
ServerSocket serverSocket = new ServerSocket(80);
while (true) {
Socket clientSocket = serverSocket.accept();
clientProcessingPool.submit(new ClientTask(clientSocket));
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
}
private class ClientTask implements Runnable {
private Socket clientSocket;
private ClientTask(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
try {
// Read request
InputStream incommingIS = clientSocket.getInputStream();
byte[] b = new byte[8196];
int len = incommingIS.read(b);
if (len > 0) {
System.out.println("REQUEST"
+ System.getProperty("line.separator") + "-------");
System.out.println(new String(b, 0, len));
// Write request
Socket socket = new Socket("localhost", 80);
OutputStream outgoingOS = socket.getOutputStream();
outgoingOS.write(b, 0, len);
// Copy response
OutputStream incommingOS = clientSocket.getOutputStream();
InputStream outgoingIS = socket.getInputStream();
for (int length; (length = outgoingIS.read(b)) != -1;) {
incommingOS.write(b, 0, length);
}
incommingOS.close();
outgoingIS.close();
outgoingOS.close();
incommingIS.close();
socket.close();
} else {
incommingIS.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
What I'm doing wrong? Anyone could help me on this?
Thanks!
You're assuming you got the entire request in a single read, instead of using a loop like your response loop.
You're also assuming that it is terminated by an end of stream, which means the client must have done a shutdownOutput(), which doesn't happen in most protocols.
In general this isn't the correct technique for writing a proxy. You need to start two threads per client, to copy data in both directions simultaneously, and defer closing the socket until you've read EOS from both directions.

Categories

Resources