I'm trying to send a file from a client to a server with Sockets in Java. It works fine when I am testing on the same machine, but when I test across different machines, I lose large chunks of data, resulting in a corrupted file. If I try to send a very small file (<20 bytes), it doesn't even reach the println inside the server's while loop.
Here is my code:
Server.java
package edu.mst.cs.sensorreceiver;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private static final int PORT = 51111;
private static final int CHUNK_SIZE = 1024;
private static final File _downloadDir = new File("downloads/");
public static void main(String[] args) {
if (!_downloadDir.exists()) {
if (!_downloadDir.mkdirs()) {
System.err.println("Error: Could not create download directory");
}
}
Socket socket = null;
try {
ServerSocket server = new ServerSocket(PORT);
while (true) {
System.out.println("Waiting for connection...");
socket = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String name = in.readLine();
File file = new File(_downloadDir, name);
String size = in.readLine();
int fileSize;
try {
fileSize = Integer.parseInt(size);
} catch (NumberFormatException e) {
System.err.println("Error: Malformed file size:" + size);
e.printStackTrace();
return;
}
System.out.println("Saving " + file + " from user... (" + fileSize + " bytes)");
saveFile(file, socket.getInputStream());
System.out.println("Finished downloading " + file + " from user.");
if (file.length() != fileSize) {
System.err.println("Error: file incomplete");
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static void saveFile(File file, InputStream inStream) {
FileOutputStream fileOut = null;
try {
fileOut = new FileOutputStream(file);
byte[] buffer = new byte[CHUNK_SIZE];
int bytesRead;
int pos = 0;
while ((bytesRead = inStream.read(buffer, 0, CHUNK_SIZE)) >= 0) {
pos += bytesRead;
System.out.println(pos + " bytes (" + bytesRead + " bytes read)");
fileOut.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileOut != null) {
try {
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("Finished, filesize = " + file.length());
}
}
Client.java
package edu.mst.cs.sensorreceiver;
import java.io.*;
import java.net.Socket;
public class Client {
private static final String HOSTNAME = "131.151.163.153";
private static final int PORT = 51111;
private static final int CHUNK_SIZE = 1024;
public static void main(String[] args) {
sendFile(args[0]);
}
private static void sendFile(String path) {
if (path == null) {
throw new NullPointerException("Path is null");
}
File file = new File(path);
Socket socket = null;
try {
System.out.println("Connecting to server...");
socket = new Socket(HOSTNAME, PORT);
System.out.println("Connected to server at " + socket.getInetAddress());
PrintStream out = new PrintStream(socket.getOutputStream(), true);
out.println(file.getName());
out.println(file.length());
System.out.println("Sending " + file.getName() + " (" + file.length() + " bytes) to server...");
writeFile(file, socket.getOutputStream());
System.out.println("Finished sending " + file.getName() + " to server");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static void writeFile(File file, OutputStream outStream) {
FileInputStream reader = null;
try {
reader = new FileInputStream(file);
byte[] buffer = new byte[CHUNK_SIZE];
int pos = 0;
int bytesRead;
while ((bytesRead = reader.read(buffer, 0, CHUNK_SIZE)) >= 0) {
outStream.write(buffer, 0, bytesRead);
outStream.flush();
pos += bytesRead;
System.out.println(pos + " bytes (" + bytesRead + " bytes read)");
}
} catch (IndexOutOfBoundsException e) {
System.err.println("Error while reading file");
e.printStackTrace();
} catch (IOException e) {
System.err.println("Error while writing " + file.toString() + " to output stream");
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
I've been working on this for hours and I have made almost no progress. I thought I had a pretty good understanding of how reading/writing from streams works, but clearly I'm missing something here.
Again, everything works perfectly when I am sending and receiving from the same machine. But if I try to send a file between two computers, even if the two are on the same LAN, I lose a lot of the data that was sent.
Can anybody figure out my problem? I've already tried everything I could think of.
You appear to be mixing chunked data and line oriented operation. I suggest you use a DataInputStream on the server, and a DataOutputStream. Starting on the client, something like
private static void sendFile(String path) {
if (path == null) {
throw new NullPointerException("Path is null");
}
File file = new File(path);
Socket socket = null;
try {
System.out.println("Connecting to server...");
socket = new Socket(HOSTNAME, PORT);
System.out.println("Connected to server at "
+ socket.getInetAddress());
try (DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(socket.getOutputStream()));) {
dos.writeUTF(file.getName());
dos.writeLong(file.length());
System.out.println("Sending " + file.getName() + " ("
+ file.length() + " bytes) to server...");
writeFile(file, dos);
System.out.println("Finished sending " + file.getName()
+ " to server");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Then on the server
socket = server.accept();
DataInputStream dis = new DataInputStream(socket.getInputStream());
String name = dis.readUTF();
File file = new File(_downloadDir, name);
long fileSize = dis.readLong();
System.out.println("Saving " + file + " from user... ("
+ fileSize + " bytes)");
In your code you mixes all that should never be mixed: (a) input/output streams, (b) PrintStream, (c) stream reader and (d) buffered reader. this hell leads to described behavior.
you should use the only object (stream) to write all your staff. and the only object (stream) to read all your staff.
I can recommend you to use either
OutputStream out = new BufferedOutputStream(socket.getOutputStream()); // for writing
InputStream in = new BufferedInputStream(socket.getInputStream()); // for reading
or
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
The first is more flexible, the second is simpler to use.
Related
I have to send any size file from a client to a server using UDP. I send the datagrams in byte arrays. I split the file and send the datagrams. I know the server receives the datagrams but my problem is on how to put the datagrams in a File again. This is my code for the Client (I'll just put the code that splits and sends the file, I used JavaFX for the client).
Thank you all in advance.
private void sendFile(ActionEvent event) {
ArrayList<byte[]> listDatagrams;
DatagramSocket socket = null;
try {
socket = new DatagramSocket();
String serverName = "localhost";
InetAddress IPserver;
int serverPort = 6789;
byte[] data;
DatagramPacket request;
IPservidor = InetAddress.getByName(serverName);
data = Files.readAllBytes(file.toPath());
listDatagrams = splitFile(data);
for(byte[] datagrama : listDatagrams){
request= new DatagramPacket(datagrama, datagrama.length, IPserver, serverPort );
socket.send(request);
}
try {
fileOuputStream.write(respuesta.getData());
} finally {
fileOuputStream.close();
}
} catch (SocketException e) {
System.out.println("SocketException: " + e.getMessage());
} catch (IOException e) {
System.out.println("IOException: " + e.getMessage());
} finally {
if (socket != null) {
socket.close();
}
}
}
This is the method I used to split the File:
public ArrayList<byte []> splitFile(byte[] file){
ArrayList<byte[]> data = new ArrayList<>();
double nPartitions;
byte[] partition= new byte[MAX];
if(file.length>MAX){
nPartitions =Math.ceil(file.length/MAX);
for(int i=0; i<=nPartitions; i++)
for(int j=0; j<MAX; j++){
if(i==0){
if(j==file.length-1)
break;
partition[j]=file[j];
}else if(i==1){
if((j+MAX)==file.length-1){
break;
}else{
partition[j]=file[(j+MAX)];
}
}else{
if((j+MAX)>=file.length-1)
break;
partition[j]=file[(i*(MAX+1))+j];
}
}
data.add(partition);
}
}
return data;
}
And the code for the server:
public static void main(String args[]) {
DatagramSocket socket = null;
ArrayList<DatagramPacket> data= new ArrayList<>();
try {
int serverPort= 6789;
socket = new DatagramSocket(serverPort);
byte[] buffer;
buffer = new byte[5000];
while (true) {
DatagramPacket request;
request= new DatagramPacket(buffer, buffer.length);
socket.receive(request);
//I add the datagramas to an array list but I am not sure how to re arrenge them into a File. The server should always be on and be able to receive a second file if I want to
data.add(request);
}
} catch (SocketException e) {
System.out.println("SocketException: " + e.getMessage());
} catch (IOException e) {
System.out.println("IOException: " + e.getMessage());
} finally {
if (socket != null) {
socket.close();
}
}
}
Note: I know TCP is better but this is for school so
I have a TCP server and client, but the client never prints the last system.out and disconnects from server socket.
My client message loop:
for (int i = 1; i <= Integer.parseInt(args[2]); i++) {
long messageTimeStart = System.currentTimeMillis();
outToServer.write(MSG.getBytes());
outToServer.flush();
Thread.sleep((long) messageTimePerSecond);
long messageTimeEnd = System.currentTimeMillis();
long totalMessageTime = messageTimeEnd - messageTimeStart; //Meassure total packet transfer time.
System.out.println("Message " + i + ": '" + MSG + "' sent in: " + totalMessageTime);
elapsedTime += totalMessageTime;
}
while (true) {
try {
int msgLength = serverEcho.read(buf);
if (msgLength == -1) {
break;
}
String echoMessage = new String(buf);
System.out.println("ECHO MESSAGE: " + echoMessage);
} catch (IOException e) {
System.out.println("Hot damn");
}
}
System.out.printf(args[2] + " Messages sent in: " + elapsedTime + " milliseconds.");
outToServer.close();
serverEcho.close();
socket.close();
It never gets to the four last lines for some reason. And I have no Idea why.
If it matters, here is my Server class run method:
public void run() {
try {
while (true) {
try {
inFromClient = new DataInputStream(clientSocket.getInputStream());
outToClient = new DataOutputStream(clientSocket.getOutputStream());
//InputStream in = clientSocket.getInputStream();
//DataInputStream dis = new DataInputStream(in);
int msgLength = 0;
msgLength = inFromClient.read(dataBuffer);
String message = new String(dataBuffer);
System.out.println("Message recieved: " + message);
outToClient.write(message.getBytes(), 0, msgLength);
outToClient.flush();
System.out.println("Echo message sent: " + message);
} catch (SocketException e) {
System.out.println("Connection terminated by client.");
break;
}
}
clientSocket.close();
} catch (IOException e) {
System.out.println("Could not listen on port: " + clientSocket.getLocalPort());
System.out.println("Client thread terminated.");
}
}
You already know the amount of data that the server will return to you since the server is returning the same information that the client is sending to him.
Therefore, you could try this approach:
Server
#Override
public void run() {
ServerSocket serverSocket = null;
Socket clientSocket = null;
DataInputStream inFromClient = null;
DataOutputStream outToClient = null;
try {
serverSocket = new ServerSocket(4321);
} catch (IOException ioe) {
System.out.println("Could not listen on port 4321. Cause: " + ioe);
System.exit(-1);
}
System.out.println("#Server#listening on port 4321!");
try {
clientSocket = serverSocket.accept();
} catch (IOException ioe) {
System.out.println("Accept failed on port: 4321. Cause: " + ioe);
System.exit(-1);
}
System.out.println("#Server#accepting connections on port 4321!");
try {
inFromClient = new DataInputStream(clientSocket.getInputStream());
outToClient = new DataOutputStream(clientSocket.getOutputStream());
} catch (IOException ioe) {
System.out.println("Input and output streams creation failed. Cause: " + ioe);
System.exit(-1);
}
System.out.println("#Server#created input and output streams!");
byte[] dataBuffer = new byte[1024];
try {
while (true) {
try {
int msgLength = 0;
msgLength = inFromClient.read(dataBuffer);
String message = new String(dataBuffer);
System.out.println("Message recieved: " + message);
outToClient.write(message.getBytes(), 0, msgLength);
outToClient.flush();
System.out.println("Echo message sent: " + message);
} catch (SocketException e) {
System.out.println("Connection terminated by client.");
break;
}
}
clientSocket.close();
} catch (IOException e) {
System.out.println("Could not listen on port: " + clientSocket.getLocalPort());
System.out.println("Client thread terminated.");
} finally {
try {
outToClient.close();
inFromClient.close();
clientSocket.close();
serverSocket.close();
} catch (IOException ioe) {
System.out.println("Unable to close streams and sockets. Cause: " + ioe);
System.exit(-1);
}
}
}
Client
#Override
public void run() {
String MSG = "Hello from client, mister server!";
Socket socket = null;
DataOutputStream outToServer = null;
DataInputStream inFromServer = null;
try {
socket = new Socket("localhost", 4321);
} catch (IOException ioe) {
System.out.println("Unable to connect with host: localhost. Cause: " + ioe);
System.exit(1);
}
System.out.println("#Client#connected with server localhost on port 4321!");
try {
outToServer = new DataOutputStream(socket.getOutputStream());
inFromServer = new DataInputStream(socket.getInputStream());
} catch (IOException ioe) {
System.out.println("Input and output streams creation failed. Cause: " + ioe);
System.exit(-1);
}
System.out.println("#Client#created input and output streams!");
long messageTimePerSecond = 3000;
long elapsedTime = 0;
try {
for (int it = 0; it < 5; it++) {
long messageTimeStart = System.currentTimeMillis();
outToServer.write(MSG.getBytes());
outToServer.flush();
Thread.sleep((long) messageTimePerSecond);
long messageTimeEnd = System.currentTimeMillis();
// Measure total packet transfer time.
long totalMessageTime = messageTimeEnd - messageTimeStart;
System.out.println("Message " + it + ": '" + MSG + "' sent in: " + totalMessageTime);
elapsedTime += totalMessageTime;
}
byte[] dataBuffer = new byte[1024];
String echoMessage = "";
int msgLength = 0;
int totalData = MSG.length();
boolean finish = false;
while (!finish) {
try {
msgLength = inFromServer.read(dataBuffer);
echoMessage += new String(dataBuffer, 0, msgLength);
if (echoMessage.length() == totalData) {
finish = true;
}
System.out.println("ECHO MESSAGE: " + echoMessage);
} catch (IOException e) {
System.out.println("Hot damn");
}
}
} catch (IOException | InterruptedException e) {
System.out.println("Something bad happened. Cause: " + e);
System.exit(-1);
} finally {
System.out.printf("5 Messages sent in: " + elapsedTime + " milliseconds.");
try {
inFromServer.close();
outToServer.close();
socket.close();
} catch (IOException ioe) {
System.out.println("Unable to close streams and socket. Cause: " + ioe);
System.exit(-1);
}
}
}
Both Server and Client implement Runnable and your main class can be like this:
public class ClientServerMain {
public static void main(String[] args) {
Thread server = new Thread(new Server());
server.start();
Thread client = new Thread(new Client());
client.start();
}
}
I have to transfer chunks of a file to different clients using one server.
When i run the server file and provide the name of the file it successfully makes chunks. when i run the first client for first time it works but when i run it for the client again(by that i mean when i connect as a second client) it fails to transfer chunks to the second client. Complete code of server and client are shown below.
error is for the second client it starts reading the contents of the file as filename and program terminates.
provide a large text file(1MB) file as input to server
Server Code:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
public class server {
private static final int sPort = 8000; //The server will be listening on this port number
public static String str;
public static int c;
public static void main(String[] args) throws Exception {
System.out.println("The server is running.");
ServerSocket listener = new ServerSocket(sPort);
int clientNum = 1;
System.out.println("Enter the name of the file: ");
Scanner in = new Scanner(System.in);
str = in.nextLine();
String path = System.getProperty("user.dir");
String filepath = path +"/"+ str;
in.close();
try {
c=splitFile(new File(filepath));
} catch (IOException e1) {
e1.printStackTrace();
}
try {
while(true) {
new Handler(listener.accept(),clientNum,c).start();
System.out.println("Client " + clientNum + " is connected!");
clientNum++;
}
} finally {
listener.close();
}
}
/**
* A handler thread class. Handlers are spawned from the listening
* loop and are responsible for dealing with a single client's requests.
*/
private static class Handler extends Thread {
private Socket connection;
private int chunkcount;
private ObjectInputStream in; //stream read from the socket
private ObjectOutputStream out; //stream write to the socket
private int no; //The index number of the client
public Handler(Socket connection, int no,int c) {
this.connection = connection;
this.no = no;
this.chunkcount=c;
}
public void run() {
try{
//initialize Input and Output streams
out = new ObjectOutputStream(connection.getOutputStream());
out.flush();
in = new ObjectInputStream(connection.getInputStream());
try{
String path = System.getProperty("user.dir");
path=path+"/"+"chunks"+ "/";
System.out.println(path);
System.out.println("Total chunks: "+chunkcount);
int i=no;
int j=i;
int k=0;
OutputStream op=connection.getOutputStream();
DataOutputStream d = new DataOutputStream(op);
d.writeInt(no);
d.flush();
System.out.println("value of j or clientnum: "+j);
while(j<chunkcount)
{
k++;
j=j+5;
}
System.out.println(k);
d.writeInt(k);
d.flush();
//d.close();
while(i<chunkcount)
{
String pathname= path+Integer.toString(i)+str;
System.out.println(i+str);
sendFile(connection,pathname);
i=i+5;
}
}
catch(Exception e){
e.printStackTrace();
}
}
catch(IOException ioException){
System.out.println("Disconnect with Client " + no);
}
finally{
//Close connections
try{
in.close();
out.close();
connection.close();
}
catch(IOException ioException){
System.out.println("Disconnect with Client " + no);
}
}
}
}
public static int splitFile(File f) throws IOException {
int partCounter = 1;//I like to name parts from 001, 002, 003, ...
//you can change it to 0 if you want 000, 001, ...
int sizeOfFiles = 102400;// 1MB
byte[] buffer = new byte[sizeOfFiles];
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(f))) {//try-with-resources to ensure closing stream
String name = f.getName();
String path = f.getParent();
long sizefile = f.getTotalSpace();
String newpath = path + "/" + "chunks";
File dir = new File(newpath);
dir.mkdir();
int tmp = 0;
while ((tmp = bis.read(buffer)) > 0) {
//write each chunk of data into separate file with different number in name
File newFile = new File(dir, String.format("%d", partCounter++) + name );
//System.out.println(f.getParent());
try (FileOutputStream out = new FileOutputStream(newFile)) {
out.write(buffer, 0, tmp);//tmp is chunk size
}
}
System.out.println("File details are : "+name+" "+sizefile);
System.out.println("Number of chunks: "+ (partCounter-1));
}
return (partCounter-1);
}
public static void sendFile(Socket conn,String fileName) throws IOException
{
File myFile = new File(fileName);
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
dis.readFully(mybytearray, 0, mybytearray.length);
OutputStream os = conn.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(myFile.getName());
dos.writeLong(mybytearray.length);
dos.write(mybytearray, 0, mybytearray.length);
dos.flush();
dis.close();
}
}
client code:
import java.net.*;
import java.io.*;
public class Client {
Socket requestSocket; //socket connect to the server
ObjectOutputStream out; //stream write to the socket
ObjectInputStream in; //stream read from the socket
public Client() {}
void run()
{
try{
//create a socket to connect to the server
requestSocket = new Socket("localhost", 8000);
System.out.println("Connected to localhost in port 8000");
//initialize inputStream and outputStream
out = new ObjectOutputStream(requestSocket.getOutputStream());
out.flush();
in = new ObjectInputStream(requestSocket.getInputStream());
System.out.println("Ready to receive files ( Enter QUIT to end):");
BufferedInputStream in1 = new BufferedInputStream(requestSocket.getInputStream());
DataInputStream d = new DataInputStream(in1);
int clientnum=d.readInt();
String path = System.getProperty("user.dir");
String oppath = path + "/" + "Client" + clientnum;
File dir = new File(oppath);
dir.mkdir();
int numchunk=d.readInt();
System.out.println(numchunk);
int jakarta=1;
while(jakarta<=numchunk ){
jakarta++;
String newpath=oppath+"/";
File f = new File(newpath);
f.createNewFile();
receiveFile(requestSocket,newpath);
System.out.println("File Received");
}
}
catch (ConnectException e) {
System.err.println("Connection refused. You need to initiate a server first.");
}
catch(UnknownHostException unknownHost){
System.err.println("You are trying to connect to an unknown host!");
}
catch(IOException ioException){
ioException.printStackTrace();
}
finally{
//Close connections
try{
in.close();
out.close();
requestSocket.close();
}
catch(IOException ioException){
ioException.printStackTrace();
}
}
}
//send a message to the output stream
public static void receiveFile(Socket s1,String oppath) throws IOException
{
String fileName;
try {
int bytesRead;
InputStream in = s1.getInputStream();
DataInputStream clientData = new DataInputStream(in);
fileName = clientData.readUTF();
OutputStream output = new FileOutputStream(oppath+fileName);
long size = clientData.readLong();
byte[] buffer = new byte[1024];
while (size > 0
&& (bytesRead = clientData.read(buffer, 0,
(int) Math.min(buffer.length, size))) != -1) {
output.write(buffer, 0, bytesRead);
size -= bytesRead;
}
output.flush();
output.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
//main method
public static void main(String args[])
{
Client client = new Client();
client.run();
}
}
I am a new java programmer and I have a file sharing program which I am trying to make it work continuously in a while(true) loop in a multithread. I have the sever running correctly but I can make the client to run continuously e.g. server establishes connection then I run client but I have to manually run it because after a file is transfer, client stops. Bellow is the code, can you please help me correct the error?
import java.net.*;
import java.io.*;
public class TCPServer
{
private static ServerSocket myServer;
private static Socket myClient = null;
public static void main(String[] args) throws IOException
{
try
{
myServer = new ServerSocket(6789);
System.out.println("Server is now available...");
}
catch(Exception e)
{
System.err.println("This port is unavailable.");
System.exit(1);
}
while(true)
{
try
{
myClient = myServer.accept();
System.out.println("Connection established to : " + myClient);
Thread t = new Thread(new ConnectionThread(myClient));
t.start();
}catch(Exception e)
{
System.err.println("Connection failed...!");
}
}
}
}
import java.net.*;
import java.io.*;
public class TCPClient
{
private static BufferedReader myReader;
private static PrintStream myOut;
private static String fileName;
private static Socket mySocket;
public static void main(String[] args) throws IOException
{
try
{
mySocket = new Socket("localhost", 6789);
myReader = new BufferedReader(new InputStreamReader(System.in));
}
catch(Exception e)
{
System.err.println("Couldn't establish a connection with server.");
System.exit(1);
}
try
{
myOut = new PrintStream(mySocket.getOutputStream());
switch (Integer.parseInt(sendOrReceive()))
{
case 1:
myOut.println("1");
sendFile();
break;
case 2:
myOut.println("2");
System.err.print("Enter file name: ");
fileName = myReader.readLine();
myOut.println(fileName);
receiveFile(fileName);
break;
}
mySocket.close();
}
catch(Exception e)
{
System.err.println("not valid input");
}
}
public static String sendOrReceive() throws IOException
{
System.out.println("1. Send file.");
System.out.println("2. Recieve file.");
System.out.print("\nMake selection: ");
return myReader.readLine();
}
public static void sendFile()
{
try
{
System.err.print("Enter file name: ");
fileName = myReader.readLine();
File myFile = new File("F:/" + fileName);
byte[] myArray = new byte[(int) myFile.length()];
FileInputStream myInFileStream = new FileInputStream(myFile);
BufferedInputStream myBufferStream = new BufferedInputStream(myInFileStream);
DataInputStream myDataIn = new DataInputStream(myBufferStream);
myDataIn.readFully(myArray, 0, myArray.length);
OutputStream myOutStream = mySocket.getOutputStream();
//Sending file name and file size to the server
DataOutputStream myDataOut = new DataOutputStream(myOutStream);
myDataOut.writeUTF(myFile.getName());
myDataOut.writeLong(myArray.length);
myDataOut.write(myArray, 0, myArray.length);
myDataOut.flush();
System.out.println("The file " + fileName + " was sent to the server.");
}
catch (Exception e)
{
System.err.println("The file " + fileName + " was not found!");
}
}
public static void receiveFile(String fileName)
{
try
{
InputStream myIn = mySocket.getInputStream();
DataInputStream myDataOut = new DataInputStream(myIn);
fileName = myDataOut.readUTF();
OutputStream myOut = new FileOutputStream(("F:/" + fileName));
long file = myDataOut.readLong();
byte[] buffer = new byte[1024];
int num = 0;
while (file > 0 && num != -1)
{
num = myDataOut.read(buffer, 0, (int) Math.min(buffer.length, file));
myOut.write(buffer, 0, num);
file -= num;
}
myOut.close();
myIn.close();
myDataOut.close();
System.out.println("The file " + fileName + " was received from the server.");
}
catch(IOException ex)
{
System.err.println("Connection closed.");
}
}
}
public class ConnectionThread implements Runnable
{
private Socket clientSocket;
private BufferedReader myBuffer = null;
public ConnectionThread(Socket aSocket)
{
this.clientSocket = aSocket;
}
#Override
public void run()
{
try
{
myBuffer = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
String choice = "";
while((choice = myBuffer.readLine()) != null)
{
switch (choice)
{
case "1":
receiveFile();
break;
case "2":
String fileName;
while ((fileName = myBuffer.readLine()) != null)
{
sendFile(fileName);
}
break;
default:
System.out.println("Not a valid choice. Choice must be '1' or '2'.");
break;
}
myBuffer.close();
clientSocket.close();
break;
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
public void receiveFile()
{
try
{
DataInputStream myDataOut = new DataInputStream(clientSocket.getInputStream());
String fileName = myDataOut.readUTF();
FileOutputStream myOut = new FileOutputStream(("C:/SHARED/" + fileName));
long file = myDataOut.readLong();
byte[] buffer = new byte[1024];
int num = 0;
while (file > 0 && num != -1)
{
num = myDataOut.read(buffer, 0, (int) Math.min(buffer.length, file));
myOut.write(buffer, 0, num);
file -= num;
}
myOut.close();
myDataOut.close();
System.out.println("The file " + fileName + " was received from the client.");
}catch (IOException e)
{
System.err.println("Connection closed.");
}
}
public void sendFile(String fileName)
{
try
{
//handle file read
File myFile = new File("C:/Users/" + fileName);
byte[] myArray = new byte[(int) myFile.length()];
FileInputStream myInFileStream = new FileInputStream(myFile);
BufferedInputStream myInBufferStream = new BufferedInputStream(myInFileStream);
DataInputStream myDataIn = new DataInputStream(myInBufferStream);
myDataIn.readFully(myArray, 0, myArray.length);
//handle file send over socket
OutputStream myOutStream = clientSocket.getOutputStream();
//Sending file name and file size to the server
DataOutputStream myDataOut = new DataOutputStream(myOutStream);
myDataOut.writeUTF(myFile.getName());
myDataOut.writeLong(myArray.length);
myDataOut.write(myArray, 0, myArray.length);
myDataOut.flush();
System.out.println("The file " + fileName + " was sent to the client.");
}
catch(Exception e)
{
System.err.println("The file " + fileName + " was not found!");
}
}
}
I think you can just add a loop to your client's main, as Saket already said in a comment:
public static void main(String[] args) throws IOException
{
while(true) {
try
{
mySocket = new Socket("localhost", 6789);
myReader = new BufferedReader(new InputStreamReader(System.in));
}
...
...
}
}
You could add an option '3' to end the loop and client program:
case 3:
System.exit(0);
Threads would be needed if you wanted to download more than one file at a time with a single client.
Your code is hard to read but key problem is:
ConnectionThread
#Override
public void run()
{
try
{
...
}
}
you should try add while(true) below try:
#Override
public void run()
{
try
{
while(true) {
myBuffer = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
String choice = "";
while((choice = myBuffer.readLine()) != null)
....
// remove close client connection
}
}
catch(Exception e)
{
System.err.println("The file " + fileName + " was not found!");
}
}
}
#mambo: In TCPClient, do not close connection, using while(true)
public class TCPClient
public static void main(String[] args) throws IOException
try
{
mySocket = new Socket("localhost", 6789);
myReader = new BufferedReader(new InputStreamReader(System.in));
}
catch(Exception e)
{
System.err.println("Couldn't establish a connection with server.");
System.exit(1);
}
while(true) {
.....
}
There are problems at 2 classes:
in TCPClient
myOut = new PrintStream(mySocket.getOutputStream());
switch (Integer.parseInt(sendOrReceive()))
{
case 1:
myOut.println("1");
sendFile();
break;
case 2:
myOut.println("2");
System.err.print("Enter file name: ");
fileName = myReader.readLine();
myOut.println(fileName);
receiveFile(fileName);
break;
}
mySocket.close();
The switch block work for only one choice, and later on mySocket will close.
In ConnectionThread Class
in while loop,
myBuffer.close();
clientSocket.close();
break;
Here clientSocket will close in first attempt only. It should be outside of while.
I am trying to write the server client file transfer program in java.
Role of Server:-
a) Serve a file to a client (one).
b) Server will send file 1 byte at a time.
c) Should be able to send the file more than once.
Role of Client:-
a) Client downloads a file
b) Client should buffer the file before writing to disk( <= 100kb) I.e. buffer 100KB and write to disk then repeat this till 1MB
I wrote the code to transfer the file from Server to Client but there seem to have some issues with the program. Server starts sending the data but its lost in the transaction. Also the content of file to be transferred is erased. As I couldn't see any specific error on console so I couldn't figure out the bug. If anyone guide me whether this approach is correct or if not, please suggest proper changes.
*Server*
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream inputStream = null;
FileOutputStream fileOutputStream = null;
BufferedOutputStream bufferedOutputStream = null;
int sizeBuffer = 0;
try{
try {
serverSocket = new ServerSocket(55555);
} catch (IOException ex) {
System.out.println("Error: Unable to Connect to Server ");
}
System.out.println("Created Socket");
try {
socket = serverSocket.accept();
} catch (IOException ex) {
System.out.println("Error: Unable to connect to client ");
}
System.out.println("Accepted Client Connection ");
try {
inputStream = socket.getInputStream();
sizeBuffer = socket.getReceiveBufferSize();
System.out.println("Size of Buffer " + sizeBuffer);
} catch (IOException ex) {
System.out.println("Error: unable to ger socket input stream ");
}
try {
fileOutputStream = new FileOutputStream("D:/ServerFile.txt");
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
} catch (FileNotFoundException ex) {
System.out.println("File not found. ");
}
byte[] bytes = new byte[sizeBuffer];
int count;
while ((count = inputStream.read(bytes)) > 0) {
bufferedOutputStream.write(bytes, 0, count);
}
System.out.println("Done");
}// end of first try
finally{
bufferedOutputStream.flush();
bufferedOutputStream.close();
inputStream.close();
socket.close();
serverSocket.close();
}
}
}
And here is client side code !
*Client*
public class Client {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = null;
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOuptputStream = null;
Socket socket = null;
int count;
try{
try {
socket = new Socket("127.0.0.1", 55555);
} catch (IOException ex) {
System.out.println("Error: Unable to create Socket ");
}
File file = new File("D:/ClientFile.txt");
long fileLength = file.length();
System.out.println(fileLength);
if ( Integer.MAX_VALUE < fileLength ) {
System.out.println("Error: Exceeded the size of transfer");
}
byte[] bytes = new byte[(int) fileLength];
try{
fileInputStream = new FileInputStream(file);
}catch (IOException ex){
System.out.println("Error: Unable to open fileInputStream");
}
bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedOuptputStream = new BufferedOutputStream(socket.getOutputStream());
while ((count = bufferedInputStream.read(bytes)) > 0) {
bufferedOuptputStream.write(bytes, 0, count);
}
}
finally{
bufferedOuptputStream.flush();
bufferedOuptputStream.close();
fileInputStream.close();
bufferedInputStream.close();
socket.close();
}
}
}