File transfer (.png , .txt) between Server and Client using UDP - java

I wrote a server and client for client to connect to the server and select a data from the server's directory to transfer the data with UDP protocol but the problem is, it is only working for .txt files it isn't working for .png files and also in the .txt files the output files are not the same with the original one forexample lines between words are not there and all the words printed side by side instead of line by line. How can i fix this problem ?
Server side:
import java.io.*;
import java.net.*;
public class FTPServer {
public static void main(String[] args)
{
DatagramSocket socket = null;
DatagramPacket inPacket = null;
DatagramPacket outPacket = null;
byte[] inBuf, outBuf;
String msg;
final int PORT = 50000;
try
{
socket = new DatagramSocket(PORT);
while(true)
{
System.out.println("\nRunning...\n");
inBuf = new byte[1000];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
int source_port=inPacket.getPort();
InetAddress source_address = inPacket.getAddress();
msg = new String(inPacket.getData(), 0, inPacket.getLength());
System.out.println("CLient: " + source_address + ":" + source_port);
String dirname = "/home/erke/Desktop/data";
File f1 = new File(dirname);
File fl[] = f1.listFiles();
StringBuilder sb = new StringBuilder("\n");
int c=0;
for(int i = 0;i<fl.length;i++)
{
if(fl[i].canRead())
c++;
}
sb.append(c+ " files found.\n\n");
for(int i=0; i<fl.length;i++)
sb.append(fl[i].getName()+ " " + fl[i].length()+ " Bytes\n");
sb.append("\nEnter file name to Download: ");
outBuf = (sb.toString()).getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length, source_address, source_port);
socket.send(outPacket);
inBuf = new byte[1000];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
String filename = new String(inPacket.getData(), 0, inPacket.getLength());
System.out.println("Requested File: " + filename);
boolean flis = false;
int index =-1;
sb = new StringBuilder("");
for(int i=0;i<fl.length;i++)
{
if(((fl[i].getName()).toString()).equalsIgnoreCase(filename))
{
index = i;
flis = true;
}
}
if(!flis)
{
System.out.println("ERROR");
sb.append("ERROR");
outBuf = (sb.toString()).getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length, source_address, source_port);
socket.send(outPacket);
}
else
{
try
{
//File send
File ff=new File(fl[index].getAbsolutePath());
FileReader fr = new FileReader(ff);
BufferedReader brf = new BufferedReader(fr);
String s = null;
sb=new StringBuilder();
while((s=brf.readLine())!=null)
{
sb.append(s);
}
if(brf.readLine()==null)
System.out.println("File Read Succesfull, CLosing Socket");
outBuf=new byte[100000];
outBuf = (sb.toString()).getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length,source_address, source_port);
socket.send(outPacket);
} catch (Exception ioe) {
System.out.println(ioe);
}
}
}
} catch (Exception e){
System.out.println("Error\n");
}
}
}
Client side:
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class FTPClient {
public static void main(String[] args) {
DatagramSocket socket = null;
DatagramPacket inPacket = null;
DatagramPacket outPacket = null;
byte[] inBuf, outBuf;
final int PORT = 50000;
String msg = null;
Scanner src = new Scanner(System.in);
try
{
InetAddress address = InetAddress.getByName("127.0.0.1");
socket = new DatagramSocket();
msg = "";
outBuf =msg.getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length,address,PORT);
socket.send(outPacket);
inBuf = new byte[65535];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
String data = new String(inPacket.getData(), 0, inPacket.getLength());
//Print file list
System.out.println(data);
//Send file name
String filename = src.nextLine();
outBuf = filename.getBytes();
outPacket = new DatagramPacket(outBuf, 0, outBuf.length, address, PORT);
socket.send(outPacket);
//Receive file
inBuf = new byte[100000];
inPacket = new DatagramPacket(inBuf, inBuf.length);
socket.receive(inPacket);
data = new String(inPacket.getData(), 0, inPacket.getLength());
if(data.endsWith("ERROR"))
{
System.out.println("File doesn't exists.\n");
socket.close();
}
else
{
try
{
BufferedWriter pw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename)));
pw.write(data);
//Force write buffer to Fİle
pw.close();
System.out.println("File Write Succesful. Closing Socket");
socket.close();
} catch (Exception ioe) {
System.out.println("File Error\n");
socket.close();
}
}
} catch (Exception e) {
System.out.println("\nNetwork Error. Try Again Later. \n");
}
}
}

In your code you are using String to store file data in both client and the server. In order to be able to transfer any file other then a text file, in your server you should have a byte[] buffer instead of String, and use it for loading file contents. You can do this by using classes with names ending with InputStream. After you do that send those bytes over a network. Same goes for the client.
InputStream and OutputStream are used to read\write bytes from files directly, while Reader and Writer classes are specifically intended to work with text files. You cannot read\write bytes with these classes, they work only with characters and strings. You will still be able to transfer text files too though since they are also just an array of bytes.
Also you should be using TCP if you want to transfer your files without losing packets, which UDP tends to do as it doesn't have mechanisms to ensure that packets are safely delivered to a destination like TCP does.

Related

Java TCP file transfer data lost randomly [duplicate]

This question already has an answer here:
Java TCP server cannot receive message from more than one client
(1 answer)
Closed 5 years ago.
[Edit: This post has been marked as duplicate without reviewing properly. The two posts address completely different problem which the reviewer did not take time to carefully read.]
The server will connect to three instances of client. The server has three threads to receive requests from these three clients. Each of the three instances of client will have a ServerThread (the server requests for file or file list from this thread) and a UserThread (it will take user input and communicated with the server and receive file/file list depending on the user input).
Let's say client_0 wants a file that is in possession of client_1. When UserThread of client_0 requests the server for the file, the server communicates with ServerThread of client_1 and ServerThread of client_1 sends the byteArray of the file to the server. The server then sends the byteArray back to the UserThread of client_0 and client_0 then saves the byteArray as a file.
I am using the same type of code for the server to receive the bytearray from client_1 and for client_0 to receive the byteArray from the server. The server's code works perfectly everytime and receives the byteArrayperfectly but in client_0, the loop that receives the byteArray gets stuck at the last part of the file although the same type of loop is working perfectly in server. The variable position holds how much of the byteArray has been received and it doesn't reach the FILE_SIZE in the client_0 but does so in server without any problem. The System.out.println() statements confirm this.
In addition, this problem in client_0 is happening 90% of the time. In the other 10%, the loop in client_0 works just like it is supposed to! Why is this happening?
The codes are long but if anyone manages to go through and give some suggestion, it will be a great help.
Server:
package server;
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception {
String[] id={"cp 1","cp 2","cp 3"}, pass={"123","456","789"};
ServerSocket welcome = new ServerSocket(6000), tmpSocket;
Socket STsocket, UTsocket;
int startSTport = 6001;
int startUTport = 6011;
// for ServerThread of client
BufferedReader STmsgFrom[] = new BufferedReader[3];
PrintWriter STmsgTo[] = new PrintWriter[3];
DataInputStream[] STfileFrom = new DataInputStream[3];
// for UserThread of client
BufferedReader UTmsgFrom[] = new BufferedReader[3];
PrintWriter UTmsgTo[] = new PrintWriter[3];
DataOutputStream[] UTfileTo = new DataOutputStream[3];
for(int i=0; i<3; i++) {
// connecting initially
System.out.println("Waiting for client "+i);
Socket client = welcome.accept();
PrintWriter send = new PrintWriter(client.getOutputStream(),true);
BufferedReader receive = new BufferedReader(new InputStreamReader(client.getInputStream()));
// sending serial number
send.println(Integer.toString(i));
// sending ports for thread sockets
send.println(Integer.toString(startSTport+i));
send.println(Integer.toString(startUTport+i));
// accepting sockets
tmpSocket = new ServerSocket(startSTport+i);
STsocket = tmpSocket.accept();
tmpSocket = new ServerSocket(startUTport+i);
UTsocket = tmpSocket.accept();
// creating communications
STmsgFrom[i] = new BufferedReader(new InputStreamReader(STsocket.getInputStream()));
STmsgTo[i] = new PrintWriter(STsocket.getOutputStream(),true);
STfileFrom[i] = new DataInputStream(STsocket.getInputStream());
UTmsgFrom[i] = new BufferedReader(new InputStreamReader(UTsocket.getInputStream()));
UTmsgTo[i] = new PrintWriter(UTsocket.getOutputStream(),true);
UTfileTo[i] = new DataOutputStream(UTsocket.getOutputStream());
System.out.println("Connected client "+i);
}
ClientThread ct0 = new ClientThread(0,STmsgFrom,STmsgTo,STfileFrom,UTmsgFrom,UTmsgTo,UTfileTo);
ClientThread ct1 = new ClientThread(1,STmsgFrom,STmsgTo,STfileFrom,UTmsgFrom,UTmsgTo,UTfileTo);
ClientThread ct2 = new ClientThread(2,STmsgFrom,STmsgTo,STfileFrom,UTmsgFrom,UTmsgTo,UTfileTo);
ct0.start();
ct1.start();
ct2.start();
System.out.println("Server Stup Complete!");
}
}
class ClientThread extends Thread {
String msg;
int cid;
BufferedReader[] STmsgFrom;
PrintWriter[] STmsgTo;
DataInputStream[] STfileFrom;
BufferedReader[] UTmsgFrom;
PrintWriter[] UTmsgTo;
DataOutputStream[] UTfileTo;
public ClientThread(int cid,BufferedReader[] STmsgFrom,PrintWriter[] STmsgTo,DataInputStream[] STfileFrom,BufferedReader[] UTmsgFrom,PrintWriter[] UTmsgTo,DataOutputStream[] UTfileTo) {
this.cid=cid;
this.STmsgFrom=STmsgFrom;
this.STmsgTo=STmsgTo;
this.STfileFrom = STfileFrom;
this.UTmsgFrom=UTmsgFrom;
this.UTmsgTo=UTmsgTo;
this.UTfileTo = UTfileTo;
}
#Override
public void run() {
while(true) {
try {
// receiving request from receiver UserThread
msg = UTmsgFrom[cid].readLine();
if(msg.equals("get list")) { // receiver requested for file list
System.out.println("Request from "+cid+": "+msg);
for(int i=0; i<3; i++) {
if(i==cid) continue;
// sending request to sender ServerThread
STmsgTo[i].println("give list");
System.out.println("Request to "+i);
// receive file count from sender ServerThread
int cnt = Integer.parseInt(STmsgFrom[i].readLine());
System.out.println(i+" has files: "+cnt);
// sending source identity to receiver UserThread
UTmsgTo[cid].println(Integer.toString(i));
// send file count back to receiver UserThread
UTmsgTo[cid].println(Integer.toString(cnt));
// get and send file names to receiver
for(int j=0; j<cnt; j++) {
msg = STmsgFrom[i].readLine();
UTmsgTo[cid].println(msg);
}
}
} else if(msg.equals("get file")) {
// get source id and filename
int source = Integer.parseInt(UTmsgFrom[cid].readLine());
String fileName = UTmsgFrom[cid].readLine();
//System.out.println("get source id and filename");
// ask source about file
STmsgTo[source].println("give file");
STmsgTo[source].println(fileName);
boolean fileOk = Boolean.parseBoolean(STmsgFrom[source].readLine());
//System.out.println("ask source about file");
// telling receiver about file status
UTmsgTo[cid].println(Boolean.toString(fileOk));
//System.out.println("telling receiver about file");
if(fileOk) {
// get copy request from receiver
msg = UTmsgFrom[cid].readLine();
//System.out.println("receiver copy command");
if(msg.equals("yes copy")) {
System.out.println("Copying \'"+fileName+"\' from "+source+" to "+cid);
// tell sender to copy
STmsgTo[source].println("yes copy");
//System.out.println("tell sender copy command");
// copy from SENDER
// get file size
int FILE_SIZE = Integer.parseInt(STmsgFrom[source].readLine());
byte[] fileBytes = new byte[FILE_SIZE];
System.out.println("Get file size "+FILE_SIZE);
// get file data
int portion = STfileFrom[source].read(fileBytes,0,fileBytes.length);
int position = portion;
do {
portion = STfileFrom[source].read(fileBytes,position,fileBytes.length-position);
if(portion>=0) {
position += portion;
}
System.out.println("position = "+position);
} while(position<FILE_SIZE);
System.out.println("Get file data "+position);
// copy to RECEIVER
// send file size
UTmsgTo[cid].println(Integer.toString(FILE_SIZE));
//System.out.println("send file size");
// send file data
UTfileTo[cid].write(fileBytes,0,position);
UTfileTo[cid].flush();
//System.out.println("send file data");
System.out.println("Copying \'"+fileName+"\' complete");
} else {
// tell sender to ignore copy process
STmsgTo[source].println("no copy");
}
}
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
}
Client:
package client;
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) throws Exception {
String msg;
InetAddress inetAddress = InetAddress.getLocalHost();
String[] allPaths= {"H:\\Study\\Lab\\Network\\Assingment 2 and lab of 5 july\\Assignment\\files\\client_1_folder",
"H:\\Study\\Lab\\Network\\Assingment 2 and lab of 5 july\\Assignment\\files\\client_2_folder",
"H:\\Study\\Lab\\Network\\Assingment 2 and lab of 5 july\\Assignment\\files\\client_3_folder"};
// connecting to welcome socket
Socket server = new Socket(inetAddress,6000);
BufferedReader receive = new BufferedReader(new InputStreamReader(server.getInputStream()));
BufferedReader receiveUser = new BufferedReader(new InputStreamReader(System.in));
PrintWriter send = new PrintWriter(server.getOutputStream(),true);
// receiving serial number
int cid = Integer.parseInt(receive.readLine());
// receiving port numbers for thread sockets
int STport = Integer.parseInt(receive.readLine());
int UTport = Integer.parseInt(receive.readLine());
// connecting sockets
Socket STsocket = new Socket(inetAddress,STport);
Socket UTsocket = new Socket(inetAddress,UTport);
System.out.println("Connected to the server.\nSerial: "+cid+"\nFolder path: "+allPaths[cid]);
ServerThread st = new ServerThread(allPaths[cid],STsocket);
UserThread ut = new UserThread(cid,allPaths[cid],UTsocket);
st.start();
ut.start();
}
}
class UserThread extends Thread {
int cid;
String msg,folderPath;
BufferedReader msgFromServer,fromUser;
PrintWriter msgToServer;
// for file
DataInputStream fileFromServer;
BufferedOutputStream writeFile;
public UserThread(int cid,String folderPath,Socket socket) {
try {
this.cid = cid;
this.folderPath = folderPath;
fromUser = new BufferedReader(new InputStreamReader(System.in));
msgFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
msgToServer = new PrintWriter(socket.getOutputStream(),true);
// for file
fileFromServer = new DataInputStream(socket.getInputStream());
} catch(Exception ex) {
ex.printStackTrace();
}
}
#Override
public void run() {
//System.out.println("User Thread Started!");
while(true) {
try {
msg = fromUser.readLine();
if(msg.equals("get list")) {
// sending request to server
msgToServer.println("get list");
// getting file list from server
System.out.println("-------------------------------------------");
for(int i=0; i<2; i++) {
// getting source id
int source = Integer.parseInt(msgFromServer.readLine());
System.out.println("Source: "+source);
int cnt = Integer.parseInt(msgFromServer.readLine());
System.out.println("Files: "+cnt);
System.out.println("--------------");
for(int j=0; j<cnt; j++) {
msg = msgFromServer.readLine();
System.out.println(msg);
}
System.out.println("-------------------------------------------");
}
} else if(msg.equals("get file")) {
// GETTING A FILE
int source;
while(true) {
System.out.println("File Source: ");
try {
source = Integer.parseInt(fromUser.readLine());
if(0<=source && source<=2 && source!=cid) {
break;
} else {
System.out.println("Error: File source invalid. Try again.");
}
} catch(Exception ex) {
System.out.println("Error: File source invalid. Try again.");
}
}
System.out.println("File Name: ");
String fileName = fromUser.readLine();
// send request to server to check file
msgToServer.println("get file");
msgToServer.println(Integer.toString(source));
msgToServer.println(fileName);
// receiving file status
boolean fileOk = Boolean.parseBoolean(msgFromServer.readLine());
if(!fileOk) {
System.out.println("Error: File does not exist at source.");
} else {
System.out.println("File is available!!");
System.out.println("Want to copy \'"+fileName+"\'? (y/n)");
msg = fromUser.readLine();
if(msg.equals("y")||msg.equals("Y")) {
// tell server to copy file
msgToServer.println("yes copy");
// COPY PROCESS
// get file size
int FILE_SIZE = Integer.parseInt(msgFromServer.readLine());
System.out.println("File size: "+FILE_SIZE+" bytes.");
byte[] fileBytes = new byte[FILE_SIZE];
// get file data
int portion = fileFromServer.read(fileBytes,0,fileBytes.length);
int position = portion;
do {
portion = fileFromServer.read(fileBytes,position,fileBytes.length-position);
if(portion>=0) {
position += portion;
}
System.out.println("position = "+position);
} while(position<FILE_SIZE);
System.out.println("Total "+position+" bytes received.");
// write file data
File file = new File(folderPath + "\\" + fileName);
writeFile = new BufferedOutputStream(new FileOutputStream(file));
writeFile.write(fileBytes,0,position);
writeFile.flush();
writeFile.close();
System.out.println("Copying complete.");
} else {
msgToServer.println("no copy");
}
}
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
}
class ServerThread extends Thread {
String msg,folderPath;
BufferedReader msgFromServer;
PrintWriter msgToServer;
// for file
DataOutputStream fileToServer;
BufferedInputStream readFile;
public ServerThread(String folderPath,Socket socket) {
try {
this.folderPath = folderPath;
msgFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
msgToServer = new PrintWriter(socket.getOutputStream(),true);
// for file
fileToServer = new DataOutputStream(socket.getOutputStream());
} catch(Exception ex) {
ex.printStackTrace();
}
}
#Override
public void run() {
//System.out.println("Server Thread Started!");
while(true) {
try {
msg = msgFromServer.readLine();
if(msg.equals("give list")) {
//System.out.println("Request from server: "+msg);
File folder = new File(folderPath);
File[] fileList = folder.listFiles();
int cnt = fileList.length;
//System.out.println("Files: "+cnt);
// give file count back to server
msgToServer.println(Integer.toString(cnt));
// give file list back to server
for(int i=0; i<cnt; i++) {
msgToServer.println(fileList[i].getName());
}
} else if(msg.equals("give file")) {
// receive file name
String fileName = msgFromServer.readLine();
// telling server about file status
File file = new File(folderPath + "\\" + fileName);
boolean fileOk = file.exists();
msgToServer.println(Boolean.toString(fileOk));
if(fileOk) {
// getting copy request
msg = msgFromServer.readLine();
if(msg.equals("yes copy")) {
// COPY PROCESS
// send file size
int FILE_SIZE = (int)file.length();
msgToServer.println(Integer.toString(FILE_SIZE));
// read file data
readFile = new BufferedInputStream(new FileInputStream(file));
byte[] fileBytes = new byte[FILE_SIZE];
readFile.read(fileBytes,0,fileBytes.length);
readFile.close();
// send file data
fileToServer.write(fileBytes,0,fileBytes.length);
fileToServer.flush();
} // otherwise end of conversation
}
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
}
I am aware that I have done some unnecessary things like giving different ports to all the different sockets. Ignore them if they are not the reason of my problem.
ServerSocket.accept() is blocking, you can't call it twice from the same thread.
Every ServerSocket must run in its own thread.

FTP server build in java but listing it's files

How do I make the files in the server appear in a list and appear a number behind it and press its number and download by inserting its number?
The point is trading files with my self that point I can but listing the files that I have in the directory I cant, I can already download files (thats the main point)
int porto = 21;
String IP = "x.x.x.x";
public Client() {
String destinyfile = "directory";
try {
Socket MyClient = new Socket(IP, porto);
DataInputStream input = new DataInputStream(MyClient.getInputStream());
DataOutputStream output = new DataOutputStream(MyClient.getOutputStream());
System.out.println(input.readUTF());
String arquivo = JOptionPane.showInputDialog("Insert the name of the file");
output.writeUTF(arquivo);
ObjectInputStream in = new ObjectInputStream(MyClient.getInputStream());
String fileName = in.readUTF();
if(fileName != null){
long size = in.readLong();
System.out.println("Processing the file: " + fileName + " - "+ size + " bytes.");
File file = new File(destinyfile);
if(file.exists() == false){
file.mkdir();
}
FileOutputStream fos = new FileOutputStream(caminhoDestino + fileName);
byte[] buf = new byte[4096];
while (true) {
int len = in.read(buf);
if (len == -1)
break;
fos.write(buf, 0, len);
}
fos.flush();
fos.close();
}
System.out.println(input.readUTF());
MyClient.close();
} catch (Exception e) {
Server
int port = 21;
public Servidor() {
try {
ServerSocket ss = new ServerSocket(port);
String caminho = "directory";
while (true) {
System.out.println("Waiting user.");
Socket socket = ss.accept();
DataInputStream input = new DataInputStream(socket.getInputStream());
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
output.writeUTF("Welcome");
String arq = input.readUTF();
System.out.println("File: " + arq);
File file = new File(caminho + arq);
if(file.exists()){
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
System.out.println("Transfering file: " + file.getName());
out.writeUTF(file.getName());
out.writeLong(file.length());
FileInputStream filein = new FileInputStream(file);
byte[] buf = new byte[4096];
while (true) {
int len = filein.read(buf);
if (len == -1)
break;
out.write(buf, 0, len);
}
out.close();
output.writeUTF("File Sent:");
}else{
output.writeUTF("File doesnt exist!");
}
ss.close();
}
} catch (Exception e) {
If you create a File object for the parent directory of the files you want to list, you can call that object's listFiles() to get an array of File objects in that directory.
E.g.
File parent = new File("/data/folder/");
for (File child : parent.listFiles()) {
System.out.println(child.getName());
}

File Sharing Code works on localhost, fails on Network

My project consists of an application using which users can send files among themselves.
Hence as a basic unit, I developed a FileServer and a FileClient Program.
This code works perfectly fine on localhost but fails on the Network (wifi).
An estimated problem is that the client socket is getting closed or isn't responding after a certain point of time while recieving. But i cant really figure out what the problem is or how to approach the problem.
The error appears is a SocketException: Software caused connection abort. Socket write error.
FileServer CODE:
import java.net.*;
import java.io.*;
public class FileServerPC {
static String remoteIPaddress = "192.168.43.95";
static String filename;
String path;
static File selectedfile = null;
static ServerSocket servsock = null;
static Socket sock = null;
static FileInputStream fis;
static BufferedInputStream bis;
static DatagramSocket theSocket = null;
static DatagramPacket theOutput;
static OutputStream os;
byte[] mybytearray;
static double nosofpackets;
static int packetsize = 1024;
public FileServerPC() {
try {
servsock = new ServerSocket(1500);
theSocket = new DatagramSocket(9999);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
FileServerPC fs = new FileServerPC();
selectedfile = new File("C:\\flower.jpg");
filename = selectedfile.getName();
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
System.out.println("Waiting...");
sock = servsock.accept();
System.out.println("Accepted connection : " + sock);
fis = new FileInputStream(selectedfile);
System.out.println((int) selectedfile.length());
long length = selectedfile.length();
System.out.println("LENGTH: " + length);
nosofpackets = Math
.ceil(((int) selectedfile.length()) / packetsize);
// progressBar.setValue(50);
bis = new BufferedInputStream(fis);
String message = length + "`~`" + filename;
byte[] data = message.getBytes();
theOutput = new DatagramPacket(data, data.length,
InetAddress.getByName(remoteIPaddress),8888);
theSocket.send(theOutput);
byte[] newbytearray = new byte[packetsize];
int dur = (int) (selectedfile.length());
int dur1 = dur / 100;
int counter = 0;
System.out.println("duration: " + dur + "nosofpackets: "
+ nosofpackets + "dur1: " + dur1);
int val = 0;
for (int i = 0; i <= nosofpackets ; i++) {
os = sock.getOutputStream();
bis.read(newbytearray, 0, newbytearray.length);
os.write(newbytearray, 0, newbytearray.length);
counter = counter + newbytearray.length;
val = counter / dur1;
System.out.println(val);
os.flush();
}
System.out.println(val);
os.flush();
os.close();
sock.close();
theSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
};
new Thread(runnable).start();
}
}
FileClient CODE:
import java.net.*;
import java.io.*;
public class FileClientPC
{
public static void main(String[] args) throws IOException
{
long start = System.currentTimeMillis();
String remoteip="192.168.43.237";
Socket sock = new Socket(remoteip, 1500);
System.out.println("Connecting...");
InputStream is = sock.getInputStream();
DatagramSocket ds = new DatagramSocket(8888);
byte[] buffer = new byte[65507];
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
try {
ds.receive(dp);
} catch (IOException e) {
System.err.println("chat error2 " + e);
}
String s = new String(dp.getData(), 0, dp.getLength());
String temp[]=s.split("`~`");
String size = temp[0];
String name = temp[1];
System.out.println(size +" "+ name);
long sizeint = Integer.parseInt(size);
System.out.println("Filename: " + name);
FileOutputStream fos = new FileOutputStream("D:\\"+name);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int packetsize = 1024;
double nosofpackets = Math.ceil(sizeint / packetsize);
System.out.println("No of packets: "+Double.toString(nosofpackets));
byte newbytearray[];
for (int i = 0; i <= nosofpackets; i++) {
is = sock.getInputStream();
newbytearray = new byte[packetsize];
int bytesRead = is.read(newbytearray, 0, newbytearray.length);
System.out.println("Packet:" + (i + 1));
bos.write(newbytearray, 0, newbytearray.length);
}
long end = System.currentTimeMillis();
bos.close();
sock.close();
ds.close();
}
}
You need to specify which interface you want to listen to. The default is the local interface. (probably OS dependent). The API for ServerSocket explains how this works (the constructor and bind() functions for instance).

Java sending and receiving file (byte[]) over sockets

I am trying to develop a very simple client / server where the client converts a file to bytes, sends it to the server, and then converts the bytes back in to a file.
Currently the program just creates an empty file. I'm not a fantastic Java developer so any help much appreciated.
This is the server part that receives what the client sends.
ServerSocket serverSocket = null;
serverSocket = new ServerSocket(4444);
Socket socket = null;
socket = serverSocket.accept();
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
byte[] bytes = new byte[1024];
in.read(bytes);
System.out.println(bytes);
FileOutputStream fos = new FileOutputStream("C:\\test2.xml");
fos.write(bytes);
And here is the client part
Socket socket = null;
DataOutputStream out = null;
DataInputStream in = null;
String host = "127.0.0.1";
socket = new Socket(host, 4444);
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
File file = new File("C:\\test.xml");
//InputStream is = new FileInputStream(file);
// Get the size of the file
long length = file.length();
if (length > Integer.MAX_VALUE) {
System.out.println("File is too large.");
}
byte[] bytes = new byte[(int) length];
//out.write(bytes);
System.out.println(bytes);
out.close();
in.close();
socket.close();
The correct way to copy a stream in Java is as follows:
int count;
byte[] buffer = new byte[8192]; // or 4096, or more
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
Wish I had a dollar for every time I've posted that in a forum.
Thanks for the help. I've managed to get it working now so thought I would post so that the others can use to help them.
Server:
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException ex) {
System.out.println("Can't setup server on this port number. ");
}
Socket socket = null;
InputStream in = null;
OutputStream out = null;
try {
socket = serverSocket.accept();
} catch (IOException ex) {
System.out.println("Can't accept client connection. ");
}
try {
in = socket.getInputStream();
} catch (IOException ex) {
System.out.println("Can't get socket input stream. ");
}
try {
out = new FileOutputStream("M:\\test2.xml");
} catch (FileNotFoundException ex) {
System.out.println("File not found. ");
}
byte[] bytes = new byte[16*1024];
int count;
while ((count = in.read(bytes)) > 0) {
out.write(bytes, 0, count);
}
out.close();
in.close();
socket.close();
serverSocket.close();
}
}
and the Client:
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = null;
String host = "127.0.0.1";
socket = new Socket(host, 4444);
File file = new File("M:\\test.xml");
// Get the size of the file
long length = file.length();
byte[] bytes = new byte[16 * 1024];
InputStream in = new FileInputStream(file);
OutputStream out = socket.getOutputStream();
int count;
while ((count = in.read(bytes)) > 0) {
out.write(bytes, 0, count);
}
out.close();
in.close();
socket.close();
}
}
Here is the server
Open a stream to the file and send it overnetwork
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class SimpleFileServer {
public final static int SOCKET_PORT = 5501;
public final static String FILE_TO_SEND = "file.txt";
public static void main (String [] args ) throws IOException {
FileInputStream fis = null;
BufferedInputStream bis = null;
OutputStream os = null;
ServerSocket servsock = null;
Socket sock = null;
try {
servsock = new ServerSocket(SOCKET_PORT);
while (true) {
System.out.println("Waiting...");
try {
sock = servsock.accept();
System.out.println("Accepted connection : " + sock);
// send file
File myFile = new File (FILE_TO_SEND);
byte [] mybytearray = new byte [(int)myFile.length()];
fis = new FileInputStream(myFile);
bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
os = sock.getOutputStream();
System.out.println("Sending " + FILE_TO_SEND + "(" + mybytearray.length + " bytes)");
os.write(mybytearray,0,mybytearray.length);
os.flush();
System.out.println("Done.");
} catch (IOException ex) {
System.out.println(ex.getMessage()+": An Inbound Connection Was Not Resolved");
}
}finally {
if (bis != null) bis.close();
if (os != null) os.close();
if (sock!=null) sock.close();
}
}
}
finally {
if (servsock != null)
servsock.close();
}
}
}
Here is the client
Recive the file being sent overnetwork
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
public class SimpleFileClient {
public final static int SOCKET_PORT = 5501;
public final static String SERVER = "127.0.0.1";
public final static String
FILE_TO_RECEIVED = "file-rec.txt";
public final static int FILE_SIZE = Integer.MAX_VALUE;
public static void main (String [] args ) throws IOException {
int bytesRead;
int current = 0;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
Socket sock = null;
try {
sock = new Socket(SERVER, SOCKET_PORT);
System.out.println("Connecting...");
// receive file
byte [] mybytearray = new byte [FILE_SIZE];
InputStream is = sock.getInputStream();
fos = new FileOutputStream(FILE_TO_RECEIVED);
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();
System.out.println("File " + FILE_TO_RECEIVED
+ " downloaded (" + current + " bytes read)");
}
finally {
if (fos != null) fos.close();
if (bos != null) bos.close();
if (sock != null) sock.close();
}
}
}
To avoid the limitation of the file size , which can cause the Exception java.lang.OutOfMemoryError to be thrown when creating an array of the file size byte[] bytes = new byte[(int) length];, instead we could do
byte[] bytearray = new byte[1024*16];
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
OutputStream output= socket.getOututStream();
BufferedInputStream bis = new BufferedInputStream(fis);
int readLength = -1;
while ((readLength = bis.read(bytearray)) > 0) {
output.write(bytearray, 0, readLength);
}
bis.close();
output.close();
}
catch(Exception ex ){
ex.printStackTrace();
} //Excuse the poor exception handling...
Rookie, if you want to write a file to server by socket, how about using fileoutputstream instead of dataoutputstream? dataoutputstream is more fit for protocol-level read-write. it is not very reasonable for your code in bytes reading and writing. loop to read and write is necessary in java io. and also, you use a buffer way. flush is necessary. here is a code sample: http://www.rgagnon.com/javadetails/java-0542.html
Adding up on EJP's answer; use this for more fluidity.
Make sure you don't put his code inside a bigger try catch with more code between the .read and the catch block, it may return an exception and jump all the way to the outer catch block, safest bet is to place EJPS's while loop inside a try catch, and then continue the code after it, like:
int count;
byte[] bytes = new byte[4096];
try {
while ((count = is.read(bytes)) > 0) {
System.out.println(count);
bos.write(bytes, 0, count);
}
} catch ( Exception e )
{
//It will land here....
}
// Then continue from here
EDIT: ^This happened to me cuz I didn't realize you need to put socket.shutDownOutput() if it's a client-to-server stream!
Hope this post solves any of your issues

Missing bytes in sending files over TCP connection

Some bytes are missing when I'm sending files over TCP connection. Though there are times that file transfer is complete.
Sending side:
class SendFile extends Thread {
Socket s;
String toIP;
String fileName;
PrintWriter pw;
BufferedReader br;
String fromIP;
String nextHopIP;
String transferTime;
int routingIndex;
final int bufferSize = 65536;
int readFile;
byte[] buffer;
FileInputStream fileIn;
OutputStream fileOut;
long fileTransferTime;
SendFile(String toIP, String fileName) {
this.toIP = toIP;
this.fileName = fileName;
}
public void run() {
while (true) {
try {
fromIP = InetAddress.getLocalHost().getHostAddress();
nextHopIP = Tables.checkRoutingTable(toIP);
if (nextHopIP.equals("none")) {
System.out.println("Invalid IP address");
} else {
s = new Socket(nextHopIP, 3434);
fileIn = new FileInputStream(fileName);
fileOut = s.getOutputStream();
buffer = new byte[bufferSize];
pw = new PrintWriter(s.getOutputStream());
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
pw.println(fromIP);
pw.println(toIP);
pw.println(fileName.split("\\\\")[fileName.split("\\\\").length - 1]);
pw.flush();
//Send file
fileTransferTime = System.currentTimeMillis();
int sum = 0;
while ((readFile = fileIn.read(buffer)) != -1) {
fileOut.write(buffer, 0, readFile);
sum += readFile;
}
System.out.println(sum);
fileIn.close();
s.shutdownOutput();
br.readLine();
fileTransferTime = System.currentTimeMillis() - fileTransferTime;
System.out.println("File transfer time: " + fileTransferTime + " ms");
s.close();
break;
}
} catch (IOException ex) {
//Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Connection timed out. Retrying...");
}
}
}
}
Receiving side:
class FileTransferThread extends Thread {
Socket fromSocket;
Socket toSocket;
String ip;
BufferedReader fromBR;
BufferedReader toBR;
PrintWriter fromPW;
PrintWriter toPW;
String[][] delta;
String token;
String toIP;
String fromIP;
String nextHopIP;
String absoluteFileName;
String fileName;
int deltaCount;
int entryCount;
int socketIndex;
int i;
int j;
int readFile;
final int bufferSize = 65536;
byte[] buffer;
InputStream fileIn;
FileOutputStream fileOut;
OutputStream fileHopOut;
File directory;
long fileTransferTime;
FileTransferThread(Socket s) {
this.fromSocket = s;
}
public void run() {
try {
ip = InetAddress.getLocalHost().getHostAddress();
fromBR = new BufferedReader(new InputStreamReader(fromSocket.getInputStream()));
fromPW = new PrintWriter(fromSocket.getOutputStream());
fromIP = fromBR.readLine();
toIP = fromBR.readLine();
nextHopIP = Tables.checkRoutingTable(toIP);
buffer = new byte[bufferSize];
fileIn = fromSocket.getInputStream();
fileName = fromBR.readLine();
if (!fileName.equals("\\send")) {
directory = new File("c:\\" + fromIP);
directory.mkdirs();
absoluteFileName = "c:\\" + fromIP + "\\" + fileName;
fileOut = new FileOutputStream(absoluteFileName);
while (true) {
try {
//if not yet the destination IP, pass to next hop
if (!toIP.equals(ip)) {
toSocket = new Socket(toIP, 3434);
fileHopOut = toSocket.getOutputStream();
toBR = new BufferedReader(new InputStreamReader(toSocket.getInputStream()));
toPW = new PrintWriter(toSocket.getOutputStream());
toPW.println(fromIP);
toPW.println(toIP);
toPW.println(fileName);
toPW.flush();
//Send file
while ((readFile = fileIn.read(buffer)) != -1) {
fileHopOut.write(buffer, 0, readFile);
}
toSocket.shutdownOutput();
fromPW.println(toBR.readLine());
fromPW.flush();
toSocket.close();
} else {
int sum = 0;
while ((readFile = fileIn.read(buffer)) != -1) {
fileOut.write(buffer, 0, readFile);
sum += readFile;
}
System.out.println(sum);
fileOut.flush();
fileOut.close();
fromPW.println("1");
fromPW.flush();
}
fromSocket.close();
break;
} catch (IOException ex) {
//Logger.getLogger(FileTransferThread.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Connection timed out. Retrying...");
}
}
} else {
while(true) {
try {
//if not yet the destination IP, pass to next hop
if (!toIP.equals(ip)) {
toSocket = new Socket(toIP, 3434);
fileHopOut = toSocket.getOutputStream();
toBR = new BufferedReader(new InputStreamReader(toSocket.getInputStream()));
toPW = new PrintWriter(toSocket.getOutputStream());
toPW.println(fromIP);
toPW.println(toIP);
toPW.println(fileName);
toPW.flush();
//Send file
while ((readFile = fileIn.read(buffer)) != -1) {
fileHopOut.write(buffer, 0, readFile);
}
toSocket.shutdownOutput();
fromPW.println(toBR.readLine());
fromPW.flush();
toSocket.close();
} else {
while ((readFile = fileIn.read(buffer)) != -1) {
}
fromPW.println("1");
fromPW.flush();
}
fromSocket.close();
break;
}
catch (IOException ex) {
//Logger.getLogger(FileTransferThread.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Connection timed out. Retrying...");
}
}
}
fromSocket.close();
} catch (IOException ex) {
Logger.getLogger(FileTransferThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
You are not closing - and hence not flushing - the SocketOutputStream called fileout. (You really should consider less misleading names ...).
Hm ... it appears shutdownOutput does that; its javadoc writes:
Disables the output stream for this socket.
For a TCP socket, any previously written data will be sent
followed by TCP's normal connection termination sequence.
If you write to a socket output stream after invoking
shutdownOutput() on the socket, the stream will throw
an IOException.
I leave this in case anybody else has the same idea.
Note that socket.getInputStream specifies the sorts of data loss that can happen using that facility. In particular:
The network software may discard bytes
that are buffered by the socket.
Found the error. It seems that BufferedReader is getting a chunk of data which is supposed to be for the file.

Categories