FTP client server model for file transfer in Java - java

Well, I am trying to implement the ftp server and ftp client in Java. I am trying to receive a file from server. Following is line of codes. I am able to achieve Connection between server and client, but unable to send filename to server also. Well can anyone guide me whether this approach is correct or if not, please suggest proper changes.
Server's Implementation:
import java.net.*;
import java.io.*;
class MyServer {
ServerSocket ss;
Socket clientsocket;
BufferedReader fromclient;
InputStreamReader isr;
PrintWriter toclient;
public MyServer() {
String str = new String("hello");
try {
// Create ServerSocket object.
ss = new ServerSocket(1244);
System.out.println("Server Started...");
while(true) {
System.out.println("Waiting for the request...");
// accept the client request.
clientsocket = ss.accept();
System.out.println("Got a client");
System.out.println("Client Address " + clientsocket.getInetAddress().toString());
isr = new InputStreamReader(clientsocket.getInputStream());
fromclient = new BufferedReader(isr);
toclient = new PrintWriter(clientsocket.getOutputStream());
String strfile;
String stringdata;
boolean file_still_present = false;
strfile = fromclient.readLine();
System.out.println(strfile);
//toclient.println("File name received at Server is " + strfile);
File samplefile = new File(strfile);
FileInputStream fileinputstream = new FileInputStream(samplefile);
// now ready to send data from server .....
int notendcharacter;
do {
notendcharacter = fileinputstream.read();
stringdata = String.valueOf(notendcharacter);
toclient.println(stringdata);
if (notendcharacter != -1) {
file_still_present = true;
} else {
file_still_present = false;
}
} while(file_still_present);
fileinputstream.close();
System.out.println("File has been send successfully .. message print from server");
if (str.equals("bye")) {
break;
}
fromclient.close();
toclient.close();
clientsocket.close();
}
} catch(Exception ex) {
System.out.println("Error in the code : " + ex.toString());
}
}
public static void main(String arg[]) {
MyServer serverobj = new MyServer();
}
}
Client's Implementation:
import java.net.*;
import java.io.*;
class MyClient {
Socket soc;
BufferedReader fromkeyboard, fromserver;
PrintWriter toserver;
InputStreamReader isr;
public MyClient() {
String str;
try {
// server is listening on this port.
soc = new Socket("localhost", 1244);
fromkeyboard = new BufferedReader(new InputStreamReader(System.in));
fromserver = new BufferedReader(new InputStreamReader(soc.getInputStream()));
System.out.println("PLEASE ENTER THE MESSAGE TO BE SENT TO THE SERVER");
str = fromkeyboard.readLine();
System.out.println(str);
String ddd;
ddd = str;
toserver = new PrintWriter(soc.getOutputStream());
String strfile;
int notendcharacter;
boolean file_validity = false;
System.out.println("send to server" + str);
System.out.println("Enter the filename to be received from server");
strfile = fromkeyboard.readLine();
toserver.println(strfile);
File samplefile = new File(strfile);
//File OutputStream helps to get write the data from the file ....
FileOutputStream fileOutputStream = new FileOutputStream(samplefile);
// now ready to get the data from server ....
do {
str = fromserver.readLine();
notendcharacter = Integer.parseInt(str);
if (notendcharacter != -1) {
file_validity = true;
} else {
System.out.println("Read and Stored all the Data Bytes from the file ..." +
"Received File Successfully");
}
if (file_validity) {
fileOutputStream.write(notendcharacter);
}
} while(file_validity);
fileOutputStream.close();
toserver.close();
fromserver.close();
soc.close();
} catch(Exception ex) {
System.out.println("Error in the code : " + ex.toString());
}
}
public static void main(String str[]) {
MyClient clientobj = new MyClient();
}
}

The answer to the above question is :
FTP Client :
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class FileClient {
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
// localhost for testing
Socket sock = new Socket("127.0.0.1", 13267);
System.out.println("Connecting...");
InputStream is = sock.getInputStream();
// receive file
new FileClient().receiveFile(is);
OutputStream os = sock.getOutputStream();
//new FileClient().send(os);
long end = System.currentTimeMillis();
System.out.println(end - start);
sock.close();
}
public void send(OutputStream os) throws Exception {
// sendfile
File myFile = new File("/home/nilesh/opt/eclipse/about.html");
byte[] mybytearray = new byte[(int) myFile.length() + 1];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray, 0, mybytearray.length);
System.out.println("Sending...");
os.write(mybytearray, 0, mybytearray.length);
os.flush();
}
public void receiveFile(InputStream is) throws Exception {
int filesize = 6022386;
int bytesRead;
int current = 0;
byte[] mybytearray = new byte[filesize];
FileOutputStream fos = new FileOutputStream("def");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray, 0, mybytearray.length);
current = bytesRead;
do {
bytesRead = is.read(mybytearray, current,
(mybytearray.length - current));
if (bytesRead >= 0)
current += bytesRead;
} while (bytesRead > -1);
bos.write(mybytearray, 0, current);
bos.flush();
bos.close();
}
}
FTP Server :
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class FileServer {
public static void main(String[] args) throws Exception {
// create socket
ServerSocket servsock = new ServerSocket(13267);
while (true) {
System.out.println("Waiting...");
Socket sock = servsock.accept();
System.out.println("Accepted connection : " + sock);
OutputStream os = sock.getOutputStream();
//new FileServer().send(os);
InputStream is = sock.getInputStream();
new FileServer().receiveFile(is);
sock.close();
}
}
public void send(OutputStream os) throws Exception {
// sendfile
File myFile = new File("/home/nilesh/opt/eclipse/about.html");
byte[] mybytearray = new byte[(int) myFile.length() + 1];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray, 0, mybytearray.length);
System.out.println("Sending...");
os.write(mybytearray, 0, mybytearray.length);
os.flush();
}
public void receiveFile(InputStream is) throws Exception {
int filesize = 6022386;
int bytesRead;
int current = 0;
byte[] mybytearray = new byte[filesize];
FileOutputStream fos = new FileOutputStream("def");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray, 0, mybytearray.length);
current = bytesRead;
do {
bytesRead = is.read(mybytearray, current,
(mybytearray.length - current));
if (bytesRead >= 0)
current += bytesRead;
} while (bytesRead > -1);
bos.write(mybytearray, 0, current);
bos.flush();
bos.close();
}
}

>
Server side
import java.io.*;
import java.net.*;
class serversvi
{
public static void main(String svi[])throws IOException
{
try
{
ServerSocket servsock=new ServerSocket(105);
DataInputStream dis=new DataInputStream(System.in);
System.out.println("enter the file name");
String fil=dis.readLine();
System.out.println(fil+" :is file transfer");
File myfile=new File(fil);
while(true)
{
Socket sock=servsock.accept();
byte[] mybytearray=new byte[(int)myfile.length()];
BufferedInputStream bis=new BufferedInputStream(new FileInputStream(myfile));
bis.read(mybytearray,0,mybytearray.length);
OutputStream os=sock.getOutputStream();
os.write(mybytearray,0,mybytearray.length);
os.flush();
sock.close();
}
}
catch(Exception saranvi)
{
System.out.print(saranvi);
}
}
}
>
Client side:
import java.io.*;
import java.net.*;
class clientsvi
{
public static void main(String svi[])throws IOException
{
try
{
Socket sock=new Socket("localhost",105);
byte[] bytearray=new byte[1024];
InputStream is=sock.getInputStream();
DataInputStream dis=new DataInputStream(System.in);
System.out.println("enter the file name");
String fil=dis.readLine();
FileOutputStream fos=new FileOutputStream(fil);
BufferedOutputStream bos=new BufferedOutputStream(fos);
int bytesread=is.read(bytearray,0,bytearray.length);
bos.write(bytearray,0,bytesread);
System.out.println("out.txt file is received");
bos.close();
sock.close();
}
catch(Exception SVI)
{
System.out.print(SVI);
}
}
}

Related

Sending a string and file into InputStream

I'm trying to send a string which is the filename and then the file itself to a server. The string is being received and used to create the file by the server. However, there isn't any data actually written into the file by the server.
I got the file transfer to work before I added the Writer's (with the file names being hard-coded) to the server and client but now I can't get both to work at the same time.
Client:
public class Client {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
while (true) {
String fileName = sc.nextLine();
System.out.println(fileName);
try {
File file = new File(fileName);
Socket socket = new Socket("localhost", 15000);
OutputStream os = socket.getOutputStream();
Writer w = new OutputStreamWriter(os, "UTF-8");
w.write(fileName);
w.close();
os.flush();
byte[] mybytearray = new byte[(int) file.length()];
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
bis.read(mybytearray, 0, mybytearray.length);
os.write(mybytearray, 0, mybytearray.length);
os.flush();
os.close();
socket.close();
} catch (Exception e) { }
}
}
}
Server:
public class Server extends Thread {
public static final int PORT = 15000;
#Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
while (true) {
Socket sock = serverSocket.accept();
readFile(sock);
}
} catch (Exception e) {
}
}
private void readFile(Socket socket) throws Exception {
InputStream ois = socket.getInputStream();
Reader r = new InputStreamReader(ois, "UTF-8");
String filename = "";
int ch = r.read();
while(ch != -1) {
filename += (char) ch;
System.out.println(filename);
ch = r.read();
}
r.close();
System.out.println(filename);
FileOutputStream fos = new FileOutputStream(filename);
byte[] bytearr = new byte[4096];
System.out.println("Reading file...");
BufferedOutputStream bos = new BufferedOutputStream(fos);
while ((ois.read(bytearr)) > 0) {
bos.write(bytearr);
}
bos.close();
System.out.println("Writing file complete...");
}
public static void main(String[] args) {
new Server().start();
}
}
This is my solution, this approach needs some improvements:
Explanation:
In position 0: Length of file name
In position 1 to the length of the file name: filename as bytes.
In position 1 + length of file name til length: The content of the file.
Basically, I'm sending all the information to the server at once (This is one improvement that you will need to figure out).
Another improvement is to send the file by chunks and not all the file at once.
Client class:
public class Client {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
while (true) {
String fileName = sc.nextLine();
System.out.println(fileName);
try {
File file = new File(fileName);
byte[] mybytearray = new byte[1 + fileName.getBytes().length + (int) file.length()];
mybytearray[0] = (byte) fileName.length();
System.arraycopy(fileName.getBytes(), 0, mybytearray, 1, fileName.getBytes().length);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
bis.read(mybytearray, fileName.getBytes().length + 1, (int) file.length());
Socket socket = new Socket("localhost", 15000);
OutputStream os = socket.getOutputStream();
os.write(mybytearray, 0, mybytearray.length);
os.flush();
os.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Server class:
public class Server extends Thread {
public static final int PORT = 15000;
public static void main(String[] args) {
new Server().start();
}
#Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
while (true) {
Socket sock = serverSocket.accept();
readFile(sock);
}
} catch (Exception e) {
}
}
private void readFile(Socket socket) throws Exception {
InputStream ois = socket.getInputStream();
byte[] resultBuff = new byte[0];
byte[] buff = new byte[1024];
int k;
while ((k = ois.read(buff, 0, buff.length)) > -1) {
byte[] tbuff = new byte[resultBuff.length + k];
System.arraycopy(resultBuff, 0, tbuff, 0, resultBuff.length);
System.arraycopy(buff, 0, tbuff, resultBuff.length, k);
resultBuff = tbuff;
}
byte lengthOfFileName = resultBuff[0];
byte fileNameBytes[] = new byte[lengthOfFileName];
System.arraycopy(resultBuff, 1, fileNameBytes, 0, lengthOfFileName);
String filename = new String(fileNameBytes);
FileOutputStream fos = new FileOutputStream(filename + System.currentTimeMillis());
byte[] bytearr = new byte[resultBuff.length - (lengthOfFileName + 1)];
System.out.println("Writing file...");
System.arraycopy(resultBuff, lengthOfFileName + 1, bytearr, 0, bytearr.length);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write(bytearr);
bos.close();
System.out.println("Writing file complete...");
}
}
Hope this helps!
Happy coding time!
You need to close the File Ouptut Stream as well. With
bos.close;
Add
fos.close;

Connection reset by peer: socket write error (Socket Programing)

I am trying to implement a Server Client application using Socket. The client request to the server for a specified file, the server will accept the client request and send the file which client requested. But while i am running my code i got the error "Connection reset by peer: socket write error" at the server side. Why this happening ? My code is below
Server.java
package Client_Server;
import java.net.*;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server extends Thread {
static Server s;
static ServerSocket ss;
static Socket clientSocket;
public static void main(String[] args) throws IOException {
s = new Server();
ss = new ServerSocket(1122);
while(true) {
System.out.println("waiting for a connection....");
clientSocket = ss.accept();
Thread thread = new Thread(s);
thread.start();
}
}
public void run() {
try {
server();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void server() throws IOException {
System.out.println("accepted connection :"+clientSocket);
BufferedReader bfr = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String fileName = bfr.readLine();
System.out.println("server side got the file name : "+fileName);
File myFile = new File(fileName);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile));
OutputStream os = clientSocket.getOutputStream();
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(clientSocket.getOutputStream()));
byte[] buffer = new byte[clientSocket.getSendBufferSize()];
long expect = myFile.length();
long left = expect;
int inlen = 0;
while (left > 0 && (inlen = bis.read(buffer, 0, (int)Math.min(left, buffer.length))) >= 0) {
dos.write(buffer, 0, inlen);
left -= inlen;
}
dos.flush();
if (left > 0) {
throw new IllegalStateException("We expected " + expect + " bytes but came up short by " + left);
}
if (bis.read() >= 0) {
throw new IllegalStateException("We expected only " + expect + " bytes, but additional data has been added to the file");
}
}
}
Client2.java
package Client_Server;
import static Client_Server.MainServer.sock;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class Client2 {
public static void main(String[] args) throws IOException {
File outdir = new File("copiedfiles");
if (!outdir.isDirectory()) {
outdir.mkdirs();
}
String fileName = "som.jpg";
Socket sock = new Socket("localhost", 1122);
System.out.println("connecting.....");
OutputStream os = sock.getOutputStream();
PrintWriter pw = new PrintWriter(os, true);
pw.println(fileName);
DataInputStream clientData = new DataInputStream(new BufferedInputStream(sock.getInputStream()));
OutputStream output = new BufferedOutputStream(new FileOutputStream(new File(outdir, "received_from_client_" + fileName)));
long size = clientData.readLong();
long bytesRemaining = size;
byte[] buffer = new byte[sock.getReceiveBufferSize()];
int bytesRead = 0;
while (bytesRemaining > 0 && (bytesRead = clientData.read(buffer, 0, (int) Math.min(buffer.length, bytesRemaining))) >= 0) {
output.write(buffer, 0, bytesRead);
bytesRemaining -= bytesRead;
}
output.flush();
if (bytesRemaining > 0) {
throw new IllegalStateException("Unable to read entire file, missing " + bytesRemaining + " bytes");
}
if (clientData.read() >= 0) {
throw new IllegalStateException("Unexpected bytes still on the input from the client");
}
}
}
Please help me to solve this.
The Exception is
Exception in thread "main" java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:122)
at java.io.DataOutputStream.write(DataOutputStream.java:107)
at Client_Server.Server.server(Server.java:54)
at Client_Server.Server.main(Server.java:27)
Java Result: 1

Multiple file chunks transfer over socket to multiple clients

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

Send file over socket (with threading on server-side) - not working

I have a Client-Server programm. The Client-programm sends a file to the server and the server receives the file. my problem is, that the file is not really receiving on the server...I't creates a file.txt in the server-directory, but it is empty...(yes i'm sure that ne file.txt in the client-directory is not empty ;) )
I think the problem is the while-loop in Client.java, because it is never embarrassed....
For the future i implements now on the server side one thread per receiving file.
The client-programm:
package controller;
public class Main {
public static void main(String[] args) {
new Controller();
}
}
-
package controller;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Controller {
public Controller() {
try {
sendFileToServer();
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendFileToServer() throws UnknownHostException, IOException {
Socket socket = null;
String host = "localhost";
socket = new Socket(host, 5555);
String filename = "file.txt";
File file = new File(filename);
OutputStream outText = socket.getOutputStream();
PrintStream outTextP = new PrintStream(outText);
outTextP.println(filename);
long filesize = file.length();
byte[] bytes = new byte[(int) filesize];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
int count;
System.out.println("Start sending file...");
while ((count = bis.read(bytes)) > 0) {
System.out.println("count: " + count);
out.write(bytes, 0, count);
}
System.out.println("Finish!");
out.flush();
out.close();
fis.close();
bis.close();
socket.close();
}
}
-
The server-programm:
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
new Server();
}
}
-
public class Server {
private ServerSocket serverSocket;
public Server() {
try {
serverSocket = new ServerSocket(5555);
waitForClient();
} catch (IOException e) {
e.printStackTrace();
}
}
private void waitForClient() {
Socket socket = null;
try {
while(true) {
socket = serverSocket.accept();
Thread thread = new Thread(new Client(socket));
thread.start();
}
} catch (IOException ex) {
System.out.println("serverSocket.accept() failed!");
}
}
}
-
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
public class Client implements Runnable{
private Socket socket;
public Client(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
receiveFile();
}
private void receiveFile() {
try {
InputStream is = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
int bufferSize = 0;
InputStream outText = socket.getInputStream();
// Get filename
InputStreamReader outTextI = new InputStreamReader(outText);
BufferedReader inTextB = new BufferedReader(outTextI);
String dateiname = inTextB.readLine();
System.out.println("Dateiname: " + dateiname);
try {
is = socket.getInputStream();
bufferSize = socket.getReceiveBufferSize();
System.out.println("Buffer size: " + bufferSize);
} catch (IOException ex) {
System.out.println("Can't get socket input stream. ");
}
try {
fos = new FileOutputStream(dateiname);
bos = new BufferedOutputStream(fos);
} catch (FileNotFoundException ex) {
System.out.println("File not found.");
}
byte[] bytes = new byte[bufferSize];
int count;
while ((count = is.read(bytes)) > 0) {
bos.write(bytes, 0, count);
System.out.println("This is never shown!!!"); // In this while-loop the file is normally receiving and written to the directory. But this loop is never embarrassed...
}
bos.flush();
bos.close();
is.close();
socket.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
When you do these kind of transfers you have to keep in mind that there is a difference between a socket's close and shutdown, in your code you close the socket in the client.
So lets see what happens : you fill in the buffers then you tell the socket to close which will discard the operation you just asked for.
When you shutdown you tell the socket "I won't send more data but send what's left to be sent and shut down" so what you need to do is to shut down the socket before you close it so the data will arrive.
So instead of this
out.flush();
out.close();
fis.close();
bis.close();
socket.close();
Try it with this
out.flush();
socket.shutdownInput(); // since you only send you may not need to call this
socket.shutdownOutput(); // with this you ensure that the data you "buffered" is sent
socket.close();
Generally if you want a graceful close, you should do it like this in all cases even for the server, so what you did is usually okay if there is an error and you just close the connection since you cant recover from an error.

Server/Client java.net.SocketException

I'm trying to build a client/server application that sends files but I'm having an issue with larger files. I'm using a BufferedInputStream to read information from a file and OutputStream to write to the socket. I have a loop that reads 1 KB from the file and then sends it, which works fine for the first 25 loops then crashes with a socket write error. Any ideas? Here's the code.
Client
import java.io.*;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class TCPClient
{
public static void main(String[] args)
{
/*Variables*/
int serverPort = 8899;
String ip = "localhost";
File myFile = new File("GeneratedFile.txt"); //fileToBeSent.txt
System.out.println(myFile.length());
try
{
/*Connect to Server*/
Socket sock = new Socket(ip, serverPort);
System.out.println("Connection Made");
/*Create Streams*/
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
OutputStream clientOutput = sock.getOutputStream();
/*This is the old code for transfer*/
/*Create Byte Array
byte[] myByteArray = new byte[(int) myFile.length()]; //was 1024
/*Send File
bis.read(myByteArray, 0, 1024);
clientOutput.write(myByteArray, 0, 1024);
clientOutput.flush();
*/
for(long i = 0; i <= myFile.length(); i += 1024)
{
byte[] myByteArray = new byte[1024];
bis.read(myByteArray, 0, 1024);
clientOutput.write(myByteArray, 0, 1024);
clientOutput.flush();
System.out.println("i is: " + i);
}
System.out.println("File Written");
sock.close();
} catch (IOException ex)
{
Logger.getLogger(TCPClient.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("You can't do that!");
}
System.out.println("Finished");
}
}
Server
import java.io.*;
import java.net.*;
public class RequestHandler
{
public void handleRequest()
{
try
{
ServerSocket welcomeSocket = new ServerSocket(8899);
while(true)
{
Socket socket = welcomeSocket.accept();
System.out.println("Socket Open");
/* Create byte array */
byte[] mybytearray = new byte[1024 * 512];
/* Create streams */
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream("newFile.txt",true);
BufferedOutputStream bos = new BufferedOutputStream(fos);
/*Write to file*/
int bytesRead = is.read(mybytearray, 0, mybytearray.length);
bos.write(mybytearray, 0, bytesRead);
/*Close Stream and Socket*/
bos.close();
socket.close();
}
} catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String args[])
{
RequestHandler rq = new RequestHandler();
rq.handleRequest();
System.out.println("Here");
}
}
Your copying technique is incorrect. This is how to copy streams in Java:
byte[] buffer = new byte[8192]; // or whatever you like, but declare it outside the loop
int count;
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
out.flush();
// then in a finally block ...
out.close();
in.close();
You need this at both ends. You cannot assume that any given read will fill the buffer, so you must loop until EOS. Note that you don't flush inside the loop.

Categories