Overclock.net banner

file transfers in java help

389 Views 3 Replies 2 Participants Last post by  ColSanderz
Hey everyone,

My friend and i have been stuck on this one for a while. We're writing a program for our computer science class that facilitates file transfers between two comuters over lan or over the internet.

That part works fine. The problem we are running into, is that when the file gets to the other side, a few bytes are lost over the internet, leaving the recieving program thinking the file is "complete" when it really isn't. Second, the recieving program does not reconstruct the file in the original order. (so if it sent 'ABCDE', the other program might recieve 'EBCAD'. The entire file is there, but in the wrong order).

Is there a way to correct this? And/or to make sure that all the bytes were successfully transfered and that the file was correctly constructed on the other side?

Thanks in advance
1 - 4 of 4 Posts
for reference, this is what we have so far

Code:

Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.util.*;

class VServListener extends Thread
{
ServerSocket listen;
UI current;

VServListener(UI current)
{
try
{
listen = new ServerSocket(10000);
this.current = current;
}
catch (Exception e)
{
e.printStackTrace();
}
}

public void run()
{
while (true)
{
try
{
new VobixServer(listen.accept(), current).start();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
class VobixServer extends Thread
{
Socket sock;
UI current;

VobixServer(Socket sock, UI current)
{
super("VobixServer");

try
{
this.sock = sock;
this.current = current;
}
catch (Exception e)
{
e.printStackTrace();
}
}

public void run()
{
try
{
PrintWriter commOut = new PrintWriter(sock.getOutputStream(), true);
Scanner commIn = new Scanner(sock.getInputStream());
FileOutputStream fos = null;
BufferedOutputStream fileOut = null;
String comm = commIn.nextLine();

if (comm.equals("requestingfilelist"))
{
LocalProfile p = current.getCurrentProfile();

if (p != null)
{
for (int i = 0; i < p.getFileList().length; i++)
{
commOut.println(i + ". " + p.getFile(i).getName());
}
}

commOut.println("finished");
}
else
if (comm.equals("filerequested"))
{
int index = Integer.parseInt(commIn.nextLine());
File f = current.getCurrentProfile().getFile(index);
commOut.println(f.getName());
commOut.println(f.length());
byte[] bites = new byte[(int)f.length()];

FileInputStream fis = new FileInputStream(f);
BufferedInputStream fileIn = new BufferedInputStream(fis);
fileIn.read(bites, 0, bites.length);

OutputStream dataOut = sock.getOutputStream();
dataOut.write(bites, 0, bites.length);
dataOut.flush();
}

commOut.println("finished");

commOut.close();
commIn.close();
sock.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
class VobixClient
{
Socket sock;

VobixClient()
{

}

void getFile(RemoteProfile r, int index, String dest)
{
int bytesRead;
int current = 0;

try
{
sock = new Socket(r.getIP(), 10000);
PrintWriter commOut = new PrintWriter(sock.getOutputStream(), true);
Scanner commIn = new Scanner(sock.getInputStream());
String comm;

commOut.println("filerequested");
commOut.println(index + "");
String filename = commIn.nextLine();
int filesize = Integer.parseInt(commIn.nextLine());

byte[] bites = new byte[filesize];
InputStream dataIn = sock.getInputStream();
FileOutputStream fos = new FileOutputStream(dest + filename);
BufferedOutputStream fileOut = new BufferedOutputStream(fos);
bytesRead = dataIn.read(bites, 0, bites.length);
current = bytesRead;

do
{
bytesRead = dataIn.read(bites, current, (bites.length - current));

if (bytesRead >= 0)
{
current += bytesRead;
}
}while(bytesRead > -1);

fileOut.write(bites, 0, current);
fileOut.flush();
fileOut.close();
sock.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}

String[] getFileList(RemoteProfile r)
{
ArrayList ar = new ArrayList();
String[] fileList = null;

try
{
sock = new Socket(r.getIP(), 10000);
PrintWriter commOut = new PrintWriter(sock.getOutputStream(), true);
Scanner commIn = new Scanner(sock.getInputStream());
String comm;

commOut.println("requestingfilelist");

while (!(comm = commIn.nextLine()).equals("finished"))
{
ar.add(comm);
}

commOut.close();
commIn.close();
sock.close();
}
catch (Exception e)
{
e.printStackTrace();
}

fileList = new String[ar.size()];

for (int i = 0; i < ar.size(); i++)
{
fileList[i] = (String)ar.get(i);
}

return fileList;
}
}
class KOptionPane extends JDialog implements ActionListener
{
JLabel name;
JLabel ip;
JTextField getname;
JTextField getip;
JButton confirm;

KOptionPane()
{
super(new JFrame(), true);
}

public void showInputDialog()
{
Container c = getContentPane();
name = new JLabel("Name of Profile");
ip = new JLabel("IP Address");
getname = new JTextField(15);
getip = new JTextField(15);
confirm = new JButton("Confirm");
confirm.addActionListener(this);
SpringLayout s = new SpringLayout();
c.setLayout(s);
c.add(name);
c.add(ip);
c.add(getname);
c.add(getip);
c.add(confirm);
s.putConstraint(SpringLayout.NORTH, name, 5, SpringLayout.NORTH, c);
s.putConstraint(SpringLayout.WEST, name, 5, SpringLayout.WEST, c);
s.putConstraint(SpringLayout.NORTH, ip, 5, SpringLayout.SOUTH, name);
s.putConstraint(SpringLayout.WEST, ip, 5, SpringLayout.WEST, c);
s.putConstraint(SpringLayout.NORTH, getname, 5, SpringLayout.NORTH, c);
s.putConstraint(SpringLayout.EAST, getname, 5, SpringLayout.EAST, c);
s.putConstraint(SpringLayout.NORTH, getip, 5, SpringLayout.SOUTH, name);
s.putConstraint(SpringLayout.EAST, getip, 5, SpringLayout.EAST, c);
s.putConstraint(SpringLayout.NORTH, confirm, 5, SpringLayout.SOUTH, getip);
s.putConstraint(SpringLayout.WEST, confirm, 110, SpringLayout.WEST, c);
setTitle("Remote Profile");
setSize(290, 120);
setLocationRelativeTo(null);
setVisible(true);
}

public void actionPerformed(ActionEvent evt)
{
dispose();
}

public String getName()
{
return getname.getText();
}

public String getIP()
{
return getip.getText();
}
}
class RemoteProfile
{
String name;
String ip;

RemoteProfile(String name, String ip)
{
this.name = name;
this.ip = ip;
}

public String getName()
{
return name;
}

public String getIP()
{
return ip;
}
}
class LocalProfile
{
File[] fileList;
String name;

LocalProfile(String name)
{
this.name = name;
fileList = new File[0];
}

public void addFile(File f)
{
File[] temp = new File[fileList.length + 1];

for (int i = 0; i < fileList.length; i++)
{
temp[i] = fileList[i];
}

temp[fileList.length] = f;
fileList = temp;
}

public String getName()
{
return name;
}

public File[] getFileList()
{
return fileList;
}

public File getFile(int i)
{
return fileList[i];
}
}
class UI extends JFrame implements ActionListener
{
JTextArea hostFileList;
JTextArea remoteFileList;
JScrollPane hostScrollPane;
JScrollPane remoteScrollPane;
JButton addFile;
JButton requestFile;
JTextField indexField;
JLabel hostLabel;
JLabel remoteLabel;
JComboBox hostProfileChooser;
JComboBox remoteProfileChooser;
String[] remoteProfilesMnemonic;
String[] hostProfilesMnemonic;
LocalProfile[] hostProfiles;
RemoteProfile[] remoteProfiles;
VServListener listener;
VobixClient fileCatcher;
String destination;

UI()
{
//Initialize data components
hostProfiles = new LocalProfile[0];
hostProfilesMnemonic = new String[0];
remoteProfiles = new RemoteProfile[0];
remoteProfilesMnemonic = new String[0];

//Initialize GUI components
Container c = getContentPane();
hostFileList = new JTextArea(15, 30);
remoteFileList = new JTextArea(15, 30);
hostScrollPane = new JScrollPane(hostFileList);
remoteScrollPane = new JScrollPane(remoteFileList);
addFile = new JButton("Add shareable file");
addFile.addActionListener(this);
requestFile = new JButton("Get file at index");
requestFile.addActionListener(this);
indexField = new JTextField(2);

initProfiles();

hostLabel = new JLabel("Local Profile");
remoteLabel = new JLabel("Remote Profile");
hostProfileChooser = new JComboBox(hostProfilesMnemonic);
hostProfileChooser.addActionListener(this);
remoteProfileChooser = new JComboBox(remoteProfilesMnemonic);
remoteProfileChooser.addActionListener(this);

//Initialize communication components
listener = new VServListener(this);
listener.start();
fileCatcher = new VobixClient();

//Create GUI layout
SpringLayout s = new SpringLayout();
c.setLayout(s);
c.add(hostProfileChooser);
c.add(hostScrollPane);
c.add(remoteProfileChooser);
c.add(remoteScrollPane);
c.add(hostLabel);
c.add(remoteLabel);
c.add(addFile);
c.add(requestFile);
c.add(indexField);
s.putConstraint(SpringLayout.NORTH, hostProfileChooser, 5, SpringLayout.NORTH, c);
s.putConstraint(SpringLayout.WEST, hostProfileChooser, 15, SpringLayout.WEST, c);
s.putConstraint(SpringLayout.NORTH, hostScrollPane, 10, SpringLayout.SOUTH, hostProfileChooser);
s.putConstraint(SpringLayout.WEST, hostScrollPane, 15, SpringLayout.WEST, c);
s.putConstraint(SpringLayout.NORTH, remoteProfileChooser, 5, SpringLayout.NORTH, c);
s.putConstraint(SpringLayout.WEST, remoteProfileChooser, -342, SpringLayout.EAST, c);
s.putConstraint(SpringLayout.NORTH, remoteScrollPane, 10, SpringLayout.SOUTH, remoteProfileChooser);
s.putConstraint(SpringLayout.EAST, remoteScrollPane, -10, SpringLayout.EAST, c);
s.putConstraint(SpringLayout.NORTH, hostLabel, 10, SpringLayout.NORTH, c);
s.putConstraint(SpringLayout.WEST, hostLabel, 10, SpringLayout.EAST, hostProfileChooser);
s.putConstraint(SpringLayout.NORTH, remoteLabel, 10, SpringLayout.NORTH, c);
s.putConstraint(SpringLayout.WEST, remoteLabel, 10, SpringLayout.EAST, remoteProfileChooser);
s.putConstraint(SpringLayout.WEST, addFile, 105, SpringLayout.WEST, c);
s.putConstraint(SpringLayout.NORTH, addFile, 10, SpringLayout.SOUTH, hostScrollPane);
s.putConstraint(SpringLayout.NORTH, indexField, 10, SpringLayout.SOUTH, remoteScrollPane);
s.putConstraint(SpringLayout.EAST, indexField, -220, SpringLayout.EAST, c);
s.putConstraint(SpringLayout.NORTH, requestFile, 10, SpringLayout.SOUTH, remoteScrollPane);
s.putConstraint(SpringLayout.WEST, requestFile, 10, SpringLayout.EAST, indexField);

//Tells program to call saveProfiles upon closing
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent evt)
{
try
{
saveProfiles();
}
catch (Exception e){e.printStackTrace();};
System.exit(0);
}
});

c.setBackground(Color.gray);
setTitle("Vobix File Transfer");
setSize(710, 370);
//setResizable(false);
setVisible(true);
}

//Loads profiles from INI
private void initProfiles()
{
hostProfilesMnemonic = addProfile(hostProfilesMnemonic, "New");
remoteProfilesMnemonic = addProfile(remoteProfilesMnemonic, "New");

try
{
Scanner ini = new Scanner(new File("Vobix.ini"));
destination = ini.nextLine();

while (ini.hasNextLine())
{
if (ini.nextLine().equals("l"))
{
LocalProfile p = new LocalProfile(ini.nextLine());
String file = "";

while (!(file = ini.nextLine()).equals("-p"))
{
if (new File(file).exists())
{
p.addFile(new File(file));
}
}

hostProfilesMnemonic = addProfile(hostProfilesMnemonic, p.getName());
hostProfiles = addProfile(hostProfiles, p);
}
else
{
RemoteProfile r = new RemoteProfile(ini.nextLine(), ini.nextLine());
ini.nextLine();

remoteProfilesMnemonic = addProfile(remoteProfilesMnemonic, r.getName());
remoteProfiles = addProfile(remoteProfiles, r);
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}

private String[] addProfile(String[] ar, String name)
{
String[] temp = new String[ar.length + 1];

for (int i = 0; i < ar.length; i++)
{
temp[i] = ar[i];
}

temp[ar.length] = name;
return temp;
}

private LocalProfile[] addProfile(LocalProfile[] ar, LocalProfile p)
{
LocalProfile[] temp = new LocalProfile[ar.length + 1];

for (int i = 0; i < ar.length; i++)
{
temp[i] = ar[i];
}

temp[ar.length] = p;
return temp;
}

private RemoteProfile[] addProfile(RemoteProfile[] ar, RemoteProfile p)
{
RemoteProfile[] temp = new RemoteProfile[ar.length + 1];

for (int i = 0; i < ar.length; i++)
{
temp[i] = ar[i];
}

temp[ar.length] = p;
return temp;
}

//Save all profile into to INI, will be called upon program exit
private void saveProfiles()
{
try
{
File save = new File("Vobix.ini");
FileWriter fw = new FileWriter(save);

fw.write(destination + "rn");

for (LocalProfile p : hostProfiles)
{
fw.write("lrn");
fw.write(p.getName() + "rn");

for (File f : p.getFileList())
{
fw.write(f.getPath() + "rn");
}

fw.write("-prn");
}

for (RemoteProfile r : remoteProfiles)
{
fw.write("rrn");
fw.write(r.getName() + "rn");
fw.write(r.getIP() + "rn");
fw.write("-prn");
}

fw.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}

public LocalProfile getCurrentProfile()
{
return getLocalProfile((String)hostProfileChooser.getSelectedItem());
}

private LocalProfile getLocalProfile(String s)
{
for (LocalProfile p : hostProfiles)
{
if (p.getName().equals(s))
{
return p;
}
}

return null;
}

private RemoteProfile getRemoteProfile(String s)
{
for (RemoteProfile r : remoteProfiles)
{
if (r.getName().equals(s))
{
return r;
}
}

return null;
}

public void actionPerformed(ActionEvent evt)
{
if (evt.getSource().equals(hostProfileChooser))
{
if (hostProfileChooser.getSelectedItem().equals("New"))
{
String name = JOptionPane.showInputDialog(this, "Name your new profile");

if (name.equals(""))
{
return;
}

hostProfiles = addProfile(hostProfiles, new LocalProfile(name));
hostProfileChooser.addItem(name);
}
else
{
LocalProfile p = getLocalProfile((String)hostProfileChooser.getSelectedItem());
hostFileList.setText("");

for (int i = 0; i < p.getFileList().length; i++)
{
hostFileList.append(i + ". " + p.getFile(i).getName() + "n");
}
}
}
else
if (evt.getSource().equals(remoteProfileChooser))
{
if (remoteProfileChooser.getSelectedItem().equals("New"))
{
KOptionPane get = new KOptionPane();
get.showInputDialog();

remoteProfiles = addProfile(remoteProfiles, new RemoteProfile(get.getName(), get.getIP()));
remoteProfileChooser.addItem(get.getName());
}
else
{
RemoteProfile r = getRemoteProfile((String)remoteProfileChooser.getSelectedItem());
requestFileList(r);
}
}
else
if (evt.getSource().equals(addFile))
{
JFileChooser jfc = new JFileChooser();
LocalProfile p = getLocalProfile((String)hostProfileChooser.getSelectedItem());

jfc.showDialog(this, "Vobix");

p.addFile(jfc.getSelectedFile());
}
else
if (evt.getSource().equals(requestFile))
{
RemoteProfile r = getRemoteProfile((String)remoteProfileChooser.getSelectedItem());
getRemoteFile(r, Integer.parseInt(indexField.getText()));
}

refreshFileLists();
}

private void getRemoteFile(RemoteProfile r, int index)
{
fileCatcher.getFile(r, index, destination);
}

private void requestFileList(RemoteProfile r)
{
remoteFileList.setText("");

for (String s : fileCatcher.getFileList(r))
{
remoteFileList.append(s + "rn");
}
}

private void refreshFileLists()
{
String sel = (String)hostProfileChooser.getSelectedItem();

if (!sel.equals("New"))
{
LocalProfile p = getLocalProfile((String)hostProfileChooser.getSelectedItem());
hostFileList.setText("");

for (int i = 0; i < p.getFileList().length; i++)
{
hostFileList.append(i + ". " + p.getFile(i).getName() + "n");
}
}
}
}
class main
{
public static void main(String[] args)
{
new UI();
}
}
See less See more
You're using some pre-constructed thingy called OutputStream dataOut = sock.getOutputStream(); and then sending the entire file all at once in one single call. So we don't know what OutputStream does or is or how it works, and I highly doubt you can just make one single call and have the file all be sent properly, that sounds a little too easy, even for java.

What you want to do is, split the file into manageable chunks, say 1000 bytes, and then create a packet that contains the information you need to send to the client, such as what chunk #ID this is. Create a structure like so:

Code:
Code:
struct {
    unsigned long ID;
    unsigned long CRC;
    byte[1000] Data;
}packet;
Populate it with the correct values. For instance, the first packet would have an ID of 0, the next one 1, the next one 2, ect. Send them one by one, having the client spit back a reply of "I have accepted the packet and it is correct", and then send the next one. You can also send many packets at once, say 10, and have the client reply back with "I have recv all 10 packets correctly, send the next 10" or "I am missing packet 8, please send it again with another 10 fresh packets". You get the idea...
See less See more
  • Rep+
Reactions: 1
you saved our day!
rep+

thanks man
1 - 4 of 4 Posts
This is an older thread, you may not receive a response, and could be reviving an old thread. Please consider creating a new thread.
Top