I have written a multi-client TCP server that has the dual purpose of sending Json (text based) command strings and also sending an SQLite database file to multiple clients. Everything is working nicely except... the database file uses the special character hex81 (decimal 129) for some internal purpose. When I read the database file into a byte array, Java converts this character to decimal -127 because of Java's signed representation of bytes. However the socket is actually transmitting this character as hex3F. So when I receive the save the data in the client and save it to a file, the database is corrupt due to the presence of h3F chars instead of h81.
Why is this happening and how do I correct it?
Here is the complete code that I am using for the server (a new instance of this class is started by a separate TCPServer class whenever a client connects):
public class TCPServerThread extends Thread {
// Connect status constants
private final static int NULL = 0;
private final static int DISCONNECTED = 1;
private final static int DISCONNECTING = 2;
private final static int BEGIN_CONNECT = 3;
private final static int CONNECTED = 4;
private final static String END_SESSION = new Character((char)0).toString(); // Indicates the end of a session
// Connection state info
private int connectionStatus = DISCONNECTED;
private static StringBuffer txBuffer = new StringBuffer("");
private static ByteArrayOutputStream txBuffer2 = new ByteArrayOutputStream();
private static File file;
// TCP Components
private ServerSocket serverSocket = null;
private Socket clientSocket = null;
private BufferedReader in = null;
private PrintWriter out = null;
private DataOutputStream out2 = null;
private String s = "";
private DecodeJson dj = new DecodeJson();
private boolean doRun;
public TCPServerThread(Socket socket) throws IOException {
doRun = true;
clientSocket = socket;
changeStatusTS(BEGIN_CONNECT, true);
}
public void run() {
while (doRun) {
try { // run every ~10 ms
Thread.sleep(10);
}
catch (InterruptedException e) {}
if (Mainscreen.shutdown == true || TCPClient.close == true)
connectionStatus = DISCONNECTING;
switch (connectionStatus) {
case BEGIN_CONNECT:
try {
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream(), true);
out2 = new DataOutputStream(clientSocket.getOutputStream());
TCPServer.writers.add(out); // add this socket to the connected clients list
changeStatusTS(CONNECTED, true);
}
// If error, clean up and output an error message
catch (IOException e) {
cleanUp();
changeStatusTS(DISCONNECTED, false);
}
break;
case CONNECTED:
try {
// Send data
if (txBuffer.length() != 0) {
for (PrintWriter writer : TCPServer.writers) {
writer.print(txBuffer);
writer.flush();
if(writer.checkError()) {
closeSocket();
changeStatusTS(DISCONNECTING, true);
}else {
changeStatusTS(NULL, true);
}
}
txBuffer.setLength(0);
}
if (txBuffer2.size() != 0) {
byte[] result = txBuffer2.toByteArray();
System.out.println(result[745] + "," + result[746] + "," + result[747] + "," + result[748] + "," + result[749] + "," + result[750]);
out2.write(result);
out2.flush();
txBuffer2.reset();
}
// Receive data
if (in.ready()) {
s = in.readLine();
if ((s != null) && (s.length() != 0)) {
// Check if it is the end of a transmission
if (s.equals(END_SESSION)) {
changeStatusTS(DISCONNECTING, true);
}
// Otherwise, receive text
else {
dj.receiveString(s);
changeStatusTS(NULL, true);
}
}
}
}
catch (IOException e) {
System.out.println("Socket error " + e);
cleanUp();
changeStatusTS(DISCONNECTED, false);
}
break;
case DISCONNECTING:
// Tell clients to disconnect as well
if (out != null) {
out.print(END_SESSION);
out.flush();
}
// Clean up (close all streams/sockets)
cleanUp();
changeStatusTS(DISCONNECTED, true);
break;
default: break;
}
}
}
// Add command to text send-buffer
public static void sendString(String s) {
synchronized (txBuffer) {
txBuffer.append(s + "\n");
}
}
// Add file data to binary send buffer
public static void sendFile(String filename) {
synchronized (txBuffer2) {
file = new File(filename);
byte[] content = new byte[(int)file.length()];
FileInputStream fin;
try {
fin = new FileInputStream(file);
fin.read(content);
System.out.println(content[745] + "," + content[746] + "," +content[747] + "," +content[748] + "," + content[749] + "," + content[750]);
txBuffer2.write(content);
fin.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException f) {
f.printStackTrace();
}
}
}
private void changeStatusTS(int newConnectStatus, boolean noError) {
// Change state if valid state
if (newConnectStatus != NULL) {
connectionStatus = newConnectStatus;
}
}
private void closeSocket(){
try {
if (clientSocket != null) {
clientSocket.close();
clientSocket = null;
}
}
catch (IOException e) { clientSocket = null; }
}
// Cleanup for disconnect
private void cleanUp() {
try {
if (serverSocket != null) {
serverSocket.close();
serverSocket = null;
}
}
catch (IOException e) { serverSocket = null; }
try {
if (clientSocket != null) {
clientSocket.close();
clientSocket = null;
}
}
catch (IOException e) { clientSocket = null; }
try {
if (in != null) {
in.close();
in = null;
}
}
catch (IOException e) { in = null; }
if (out != null) {
TCPServer.writers.remove(out); // remove this socket for the connected sockets list
out.close();
out = null;
}
doRun = false;
}
}
So as EJP suggested, the problem is due to using readers and writers.
The following code now works as expected (thanks for the tip EJP). I will get around to addressing the issue raised by VGR about wrapping client.getOutputStream() in both a PrintWriter and a BufferedOutputStream, but for now the code works nicely (this is a work in progress).
public class TCPServerThread extends Thread {
// Connect status constants
private final static int NULL = 0;
private final static int DISCONNECTED = 1;
private final static int DISCONNECTING = 2;
private final static int BEGIN_CONNECT = 3;
private final static int CONNECTED = 4;
private final static String END_SESSION = new Character((char)0).toString(); // Indicates the end of a session
// Connection state info
private int connectionStatus = DISCONNECTED;
private static StringBuffer txBuffer = new StringBuffer("");
private static BufferedOutputStream out2 = null;
private static File file;
// TCP Components
private ServerSocket serverSocket = null;
private Socket clientSocket = null;
private BufferedReader in = null;
private PrintWriter out = null;
private static BufferedInputStream fileData = null;
private String s = "";
private DecodeJson dj = new DecodeJson();
private boolean doRun;
public TCPServerThread(Socket socket) throws IOException {
doRun = true;
clientSocket = socket;
changeStatusTS(BEGIN_CONNECT, true);
}
public void run() {
while (doRun) {
try { // run every ~10 ms
Thread.sleep(10);
}
catch (InterruptedException e) {}
if (Mainscreen.shutdown == true || TCPClient.close == true)
connectionStatus = DISCONNECTING;
switch (connectionStatus) {
case BEGIN_CONNECT:
try {
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream(), true);
out2 = new BufferedOutputStream(clientSocket.getOutputStream());
TCPServer.writers.add(out); // add this socket to the connected clients list
changeStatusTS(CONNECTED, true);
}
// If error, clean up and output an error message
catch (IOException e) {
cleanUp();
changeStatusTS(DISCONNECTED, false);
}
break;
case CONNECTED:
try {
// Send data
if (txBuffer.length() != 0) {
for (PrintWriter writer : TCPServer.writers) {
writer.print(txBuffer);
writer.flush();
if(writer.checkError()) {
closeSocket();
changeStatusTS(DISCONNECTING, true);
}else {
changeStatusTS(NULL, true);
}
}
txBuffer.setLength(0);
}
if (fileData != null) {
byte[] buffer = new byte[(int) file.length()];
for (int read = fileData.read(buffer); read >=0; read = fileData.read(buffer)) out2.write(buffer, 0, read);
out2.flush();
fileData = null;
}
// Receive data
if (in.ready()) {
s = in.readLine();
if ((s != null) && (s.length() != 0)) {
// Check if it is the end of a transmission
if (s.equals(END_SESSION)) {
changeStatusTS(DISCONNECTING, true);
}
// Otherwise, receive text
else {
dj.receiveString(s);
changeStatusTS(NULL, true);
}
}
}
}
catch (IOException e) {
System.out.println("Socket error " + e);
cleanUp();
changeStatusTS(DISCONNECTED, false);
}
break;
case DISCONNECTING:
// Tell clients to disconnect as well
if (out != null) {
out.print(END_SESSION);
out.flush();
}
// Clean up (close all streams/sockets)
cleanUp();
changeStatusTS(DISCONNECTED, true);
break;
default: break;
}
}
}
// Add command to text send-buffer
public static void sendString(String s) {
synchronized (txBuffer) {
txBuffer.append(s + "\n");
}
}
// Add file data to binary send buffer
public static void sendFile(String filename) {
file = new File(filename);
try {
fileData = new BufferedInputStream(new FileInputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
private void changeStatusTS(int newConnectStatus, boolean noError) {
// Change state if valid state
if (newConnectStatus != NULL) {
connectionStatus = newConnectStatus;
}
}
private void closeSocket(){
try {
if (clientSocket != null) {
clientSocket.close();
clientSocket = null;
}
}
catch (IOException e) { clientSocket = null; }
}
// Cleanup for disconnect
private void cleanUp() {
try {
if (serverSocket != null) {
serverSocket.close();
serverSocket = null;
}
}
catch (IOException e) { serverSocket = null; }
try {
if (clientSocket != null) {
clientSocket.close();
clientSocket = null;
}
}
catch (IOException e) { clientSocket = null; }
try {
if (in != null) {
in.close();
in = null;
}
}
catch (IOException e) { in = null; }
if (out != null) {
TCPServer.writers.remove(out); // remove this socket for the connected sockets list
out.close();
out = null;
}
doRun = false;
}
}
Related
Does it possible, to get from client and
objetObjectInputStream
and
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
for example, some client send me tet message, and someone send files. Should I make a new socket server for each?
public class ServerRequests {
Connection con = new Connection();
private Socket socket;
private BufferedReader in;
private BufferedWriter out;
public ServerRequests(Socket socket) throws IOException {
this.socket = socket;
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
run();
}
public void run() {
String word;
try {
String object;
ObjectInputStream obIn = new ObjectInputStream(socket.getInputStream());
while ((object = (String) obIn.readObject()) != null){
if (object.contains("F47S")){
String[] result = object.split(":");
String fileName = result[1];
String url = result[2];
String culture = result[3];
System.out.println("FileName:" +fileName);
System.out.println("url:" +url);
FileOutputStream outOb = null;
if(culture.contains("test")) {
outOb = new FileOutputStream(fileName);
}
DataInputStream inOb = new DataInputStream(socket.getInputStream());
byte[] bytes = new byte[5*1024];
int count, total=0;
long lenght = inOb.readLong();
while ((count = inOb.read(bytes)) > -1) {
total+=count;
outOb.write(bytes, 0, count);
if (total==lenght) break;
}
outOb.close();
}
}
}catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
// while (true) {
word = in.readLine();
System.out.println(word);
if (word != null) {
String[] result = word.split(":");
String type = result[0];
if (type.contains("AUTH")) {
String login = result[2];
String pass = result[4];
String gui = con.checkLogin(pass, login);
auth(gui);
}
} catch (IOException e) {
}
}
private void auth(String gui) {
try {
out.write(gui + "\n");
out.flush();
} catch (IOException ignored) {
}
}
private void success(String status) {
try {
out.write(status+ "\n");
out.flush();
} catch (IOException ignored) {
}
}
}
So I'm doing this app for a coursework project and I am getting this error when I try to communicate with server:
java.io.StreamCorruptedException: invalid stream header: 43686F6F
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:806)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at Client.ChatClient.<init>(ChatClient.java:31)
at Client.ChatClient.main(ChatClient.java:102)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Here is my Server Code:
public class ChatServer implements Observer {
private ServerSocket serverSocket = null;
private ArrayList<ClientHandler> clients = null;
private Executor service = Executors.newFixedThreadPool(10);
public ChatServer( int port ) {
try {
serverSocket = new ServerSocket( port );
}
catch (IOException e) {
e.printStackTrace();
}
clients = new ArrayList<ClientHandler>();
Thread t = new Thread( new ServerLoop() );
t.start();
}
public void tellEveryone( String message ) {
Iterator it = clients.iterator();
while ( it.hasNext() ) {
System.out.println( 1 );
ClientHandler client = (ClientHandler) it.next();
client.send(message);
}
System.out.println( message );
}
#Override
public void update(Observable o, Object arg) {
System.out.println("from server - updateMethod : " + arg );
}
public class ServerLoop implements Runnable {
public void run() {
try {
while (true) {
Socket clientSocket = serverSocket.accept();
ClientHandler c = new ClientHandler(clientSocket);
clients.add(c);
c.addObserver(ChatServer.this);
service.execute(c);
tellEveryone("new client");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main( String[] args ) {
ChatServer s = new ChatServer( 5000 );
}
}
This is my Client Handler (main part):
public class ClientHandler extends Observable implements Runnable {
private Scanner reader = null;
private PrintWriter writer = null;
private String path = "../";
private Socket client;
private BufferedOutputStream bufferedOutputStream;
private boolean isConnected = false;
private ObjectOutputStream outputStream = null;
private String sourceDirectory = "/home/csunix/sc16hsm/IdeaProjects/ServerClient/src/Server/folder1";
private String destinationDirectory = "/home/csunix/sc16hsm/IdeaProjects/ServerClient/src/Client/Downloads/";
private int fileCount = 0;
private FileEvent fileEvent = null;
public ClientHandler( Socket client ) {
try {
this.client=client;
reader = new Scanner( client.getInputStream() );
writer = new PrintWriter( client.getOutputStream(), true );
bufferedOutputStream = new BufferedOutputStream(client.getOutputStream());
}
catch (IOException e) {
e.printStackTrace();
}
}
public void locateFiles() {
File srcDir = new File(sourceDirectory);
if (!srcDir.isDirectory()) {
System.out.println("Source directory is not valid ..Exiting the client");
System.exit(0);
}
File[] files = srcDir.listFiles();
fileCount = files.length;
if (fileCount == 0) {
System.out.println("Empty directory ..Exiting the client");
System.exit(0);
}
for (int i = 0; i < fileCount; i++) {
System.out.println("Sending " + files[i].getAbsolutePath());
sendFile(files[i].getAbsolutePath(), fileCount - i - 1);
System.out.println(files[i].getAbsolutePath());
}
}
public void sendFile(String fileName, int index) {
fileEvent = new FileEvent();
fileEvent.setDestinationDirectory(destinationDirectory);
fileEvent.setSourceDirectory(sourceDirectory);
File file = new File(fileName);
fileEvent.setFilename(file.getName());
fileEvent.setRemainder(index);
DataInputStream diStream = null;
try {
diStream = new DataInputStream(new FileInputStream(file));
long len = (int) file.length();
byte[] fileBytes = new byte[(int) len];
int read = 0; int numRead = 0;
while (read < fileBytes.length && (numRead = diStream.read(fileBytes, read, fileBytes.length - read)) >= 0) {
read = read + numRead;
}
fileEvent.setFileData(fileBytes);
fileEvent.setStatus("Success");
} catch (Exception e) {
e.printStackTrace();
fileEvent.setStatus("Error");
}
try {
outputStream.writeObject(fileEvent);
} catch (IOException e) {
e.printStackTrace();
}
}
public void listFolders(){
File file = new File("../");
String[] directories = file.list(new FilenameFilter() {
#Override
public boolean accept(File current, String name) {
return new File(current, name).isDirectory();
}
});
send(Arrays.toString(directories));
}
public void listAll(String fileName){
File folder = new File(path + "/" + fileName);
path = folder.getPath();
System.out.println(path);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
writer.println("File: " + listOfFiles[i].getName());
} else if (listOfFiles[i].isDirectory()) {
writer.println("Directory: " + listOfFiles[i].getName());
}
}
}
public void send( String message ) {
writer.println( message );
}
public void run() {
String message;
writer.println("Choose a file");
listAll("");
while ((message = reader.nextLine()) != null) {
writer.println("Choose a file");
listAll(message);
setChanged();
notifyObservers( message );
if(message.equals("download")) {
System.out.println("MESSAGE FROM CLIENT: " + message);
writer.println("ready");
locateFiles();
}
}
}
}
This is my Client code:
public class ChatClient {
private Scanner socketIn = null;
private PrintWriter socketOut = null;
private Scanner keyboardIn = null;
private Socket socket = null;
private ObjectInputStream inputStream = null;
private FileEvent fileEvent;
private File dstFile = null;
private FileOutputStream fileOutputStream = null;
public ChatClient( String host, int port ) {
try {
Socket socket = new Socket( host, port );
socketIn = new Scanner( socket.getInputStream() );
socketOut = new PrintWriter( socket.getOutputStream(), true );
keyboardIn = new Scanner( System.in );
inputStream = new ObjectInputStream(socket.getInputStream());
}
catch( IOException e ) {
e.printStackTrace();
}
}
public void downloadFiles() {
while (socket.isConnected()) {
try {
fileEvent = (FileEvent) inputStream.readObject();
if (fileEvent.getStatus().equalsIgnoreCase("Error")) {
System.out.println("Error occurred ..with file" + fileEvent.getFilename() + "at sending end ..");
}
String outputFile = fileEvent.getDestinationDirectory() + fileEvent.getFilename();
if (!new File(fileEvent.getDestinationDirectory()).exists()) {
new File(fileEvent.getDestinationDirectory()).mkdirs();
}
dstFile = new File(outputFile);
fileOutputStream = new FileOutputStream(dstFile);
fileOutputStream.write(fileEvent.getFileData());
fileOutputStream.flush();
fileOutputStream.close();
System.out.println("Output file : " + outputFile + " is successfully saved ");
if (fileEvent.getRemainder() == 0) {
System.out.println("Whole directory is copied...So system is going to exit");
System.exit(0);
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
private void talktoServer() {
String message;
Thread readerThread = new Thread( new IncomingReader() );
readerThread.start();
while ((message = keyboardIn.nextLine()) != null) {
System.out.println("client typed: " + message);
socketOut.println( message );
}
}
private class IncomingReader implements Runnable {
public void run() {
String message;
while ((message = socketIn.nextLine()) != null) {
System.out.println("client read: " + message);
if(message.equals("ready")) {
downloadFiles();
}
}
}
}
public static void main( String[] args ) {
ChatClient c = new ChatClient( "127.0.0.1", 5000 );
c.talktoServer();
}
}
Any help at all would be greatly appreciated!
I am collecting data from Android App(Accelerometer and Gyro) and send it to Desktop app via Java Socket but in high rates
(SENSOR_DELAY_FASTEST,SENSOR_DELAY_GAME)
Notes :
readingsList : contains all reading from sensors
I remove from list the data being sent to server
Only data sent once and i made sure it's ordered from client side
but i got them unordered in server side ( I received all data but not ordered)
processData(String reading) function may takes time but not too much
Client Code :
class SocketClientThread implements Runnable {
public SocketClientThread(){
}
public void run() {
while (!Thread.currentThread().isInterrupted() && breathingStarted) {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
PrintWriter out =
new PrintWriter(socket.getOutputStream(), true);
socket.setSendBufferSize(Integer.MAX_VALUE);
socket.setReceiveBufferSize(Integer.MAX_VALUE);
int lastCount = readingsList.size();
out.println(readingsList);
out.flush();
out.close();
int toberemoved = lastCount;
if(readingsList.size() > 0){
for (int i = 0; i < toberemoved; i++) {
readingsList.remove(0);
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
Server Code :
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(minutes*60*1000);
Thread thread = new Thread() {
public void run() {
while(!isStopped)
{
try
{
Socket connection = serverSocket.accept();
connection.setReceiveBufferSize(Integer.MAX_VALUE);
connection.setSendBufferSize(Integer.MAX_VALUE);
BufferedReader input =
new BufferedReader(new InputStreamReader(connection.getInputStream()));
PrintWriter out =
new PrintWriter(connection.getOutputStream(), true);
String inputLine;
while ((inputLine = input.readLine()) != null) {
recentReading = inputLine;
String oldReading = recentReading;
String modifiedReading = oldReading.replace("[", "");
modifiedReading = modifiedReading.replace("]", "");
String [] readings = modifiedReading.split(",");
for (int i = 0; i < readings.length; i++) {
String currentReading = readings[i].trim();
String [] tokens = currentReading.split("_");
processData(currentReading);
}
}
}catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
display.syncExec(new Runnable() {
public void run() {
statusVal.setText("Socket timed out!");
}
});
break;
}catch(SocketException s)
{
if(serverSocket.isClosed()){
display.syncExec(new Runnable() {
public void run() {
statusVal.setText("Disconnected");
}
});
}
break;
}catch(IOException e)
{
e.printStackTrace();
break;
}
}
}
};
thread.setDaemon(true);
thread.start();
I am getting data after it's time (not ordered)
I'm trying to save a mp3 file from the server to the client and play it after that. I am loading the playlist and after that trying to play a song(The song is supposed to be saved on the client PC and played after that). I am building the application with JavaFXpackage main;
Controller class:
public class AudioController {
#FXML
private ResourceBundle resources;
#FXML
private URL location;
#FXML
private Button nextButton;
#FXML
private Button playButton;
#FXML
private ListView<String> playlist;
#FXML
private Button previousButton;
#FXML
private Button stopButton;
#FXML
void initialize() {
final AudioClient audioClient = new AudioClient("127.0.0.1", 3000);
audioClient.setUpConnection();
ArrayList<String> songList = audioClient.getPlaylist();
ObservableList<String> songs = FXCollections
.observableArrayList(songList);
playlist.setItems(songs);
playButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
String songToPlay = playlist.getSelectionModel()
.getSelectedItem();
if (songToPlay != null) {
try {
String linkToSong = audioClient.getSong(songToPlay);
Media song = new Media(linkToSong);
MediaPlayer mediaPlayer = new MediaPlayer(song);
mediaPlayer.play();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
}
}
Client class
public class AudioClient {
protected BufferedReader socketReader;
protected PrintWriter socketWriter;
protected InputStream is;
protected String hostIP;
protected int hostPort;
public AudioClient(String hostIP, int hostPort) {
this.hostIP = hostIP;
this.hostPort = hostPort;
}
public ArrayList<String> getPlaylist() {
ArrayList<String> fileLines = new ArrayList<String>();
try {
socketWriter.println("Playlist");
socketWriter.flush();
String line = null;
while ((line = socketReader.readLine()) != null) {
fileLines.add(line);
}
} catch (IOException e) {
System.out.println("There was a problem reading");
}
return fileLines;
}
public String getSong(String songName) throws IOException {
socketWriter.println("Request " + songName);
socketWriter.flush();
String filePath = new String("D:\\" + songName + ".mp3");
FileOutputStream fos = new FileOutputStream(new File(filePath));
BufferedOutputStream bos = new BufferedOutputStream(fos);
int count;
byte[] buffer = new byte[4096];
while ((count = is.read(buffer, 0, buffer.length)) != -1) {
bos.write(buffer, 0, count);
}
return filePath;
}
public void setUpConnection() {
try {
Socket client = new Socket(hostIP, hostPort);
socketReader = new BufferedReader(new InputStreamReader(
client.getInputStream()));
InputStream is = client.getInputStream();
socketWriter = new PrintWriter(client.getOutputStream());
} catch (UnknownHostException e) {
System.out.println("Error setting up socket connection: unknown host at "
+ hostIP + ":" + hostPort);
} catch (IOException e) {
System.out.println("Error setting up socket connection: " + e);
}
}
public void tearDownConnection() {
try {
socketWriter.close();
socketReader.close();
} catch (IOException e) {
System.out.println("Error tearing down socket connection: " + e);
}
}
Class for handling connections to the server
public class ConnectionHandler implements Runnable {
private Socket socketToHandle;
public ConnectionHandler(Socket aSocketToHandle) {
socketToHandle = aSocketToHandle;
}
#Override
public void run() {
try {
PrintWriter streamWriter = new PrintWriter(
socketToHandle.getOutputStream());
BufferedReader streamReader = new BufferedReader(
new InputStreamReader(socketToHandle.getInputStream()));
String songToPlay = null;
while ((songToPlay = streamReader.readLine()) != null) {
if (songToPlay.equals("Playlist")) {
File songsTxt = new File(
"D:/Universitet i dr/JAVA/AudioPlayer/src/main/media/songsList.txt");
String song = null;
try {
FileReader reader = new FileReader(songsTxt);
BufferedReader songReader = new BufferedReader(reader);
while ((song = songReader.readLine()) != null) {
streamWriter.println(song);
}
} catch (FileNotFoundException e) {
System.out.println("File dosen't exist");
} catch (IOException e) {
System.out.println("Can't read from the file");
}
} else if (songToPlay.startsWith("Request ")) {
songToPlay = songToPlay.replaceFirst("Request ", "");
File songPath = new File(
"D:/Universitet i dr/JAVA/AudioPlayer/src/main/media/"
+ songToPlay);
BufferedInputStream inStream = new BufferedInputStream(
new FileInputStream(songPath));
BufferedOutputStream outStream = new BufferedOutputStream(
socketToHandle.getOutputStream());
byte[] buffer = new byte[4096];
for (int read = inStream.read(buffer); read >= 0; read = inStream.read(buffer)) {
outStream.write(buffer, 0, read);
}
}
}
} catch (Exception e) {
System.out.println("Error handling a client: " + e);
}
}
i have written a java code to transfer files from one server to another using the concept of socket programming. now in the same code i also want to check for the network connection availability before each file is transferred. i also want that the files transferred should be transferred according to their numerical sequence. And while the files are being transferred the transfer progress of each file i.e the progress percentage bar should also be visible on the screen.
i will really appreciate if someone can help me with the code. i am posting the code i have written for file transfer.
ClientMain.java
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ClientMain {
private DirectoryTxr transmitter = null;
Socket clientSocket = null;
private boolean connectedStatus = false;
private String ipAddress;
String srcPath = null;
String dstPath = "";
public ClientMain() {
}
public void setIpAddress(String ip) {
this.ipAddress = ip;
}
public void setSrcPath(String path) {
this.srcPath = path;
}
public void setDstPath(String path) {
this.dstPath = path;
}
private void createConnection() {
Runnable connectRunnable = new Runnable() {
public void run() {
while (!connectedStatus) {
try {
clientSocket = new Socket(ipAddress, 3339);
connectedStatus = true;
transmitter = new DirectoryTxr(clientSocket, srcPath, dstPath);
} catch (IOException io) {
io.printStackTrace();
}
}
}
};
Thread connectionThread = new Thread(connectRunnable);
connectionThread.start();
}
public static void main(String[] args) {
ClientMain main = new ClientMain();
main.setIpAddress("10.6.3.92");
main.setSrcPath("E:/temp/movies/");
main.setDstPath("D:/tcp/movies");
main.createConnection();
}
}
(DirectoryTxr.java)
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class DirectoryTxr {
Socket clientSocket = null;
String srcDir = null;
String dstDir = null;
byte[] readBuffer = new byte[1024];
private InputStream inStream = null;
private OutputStream outStream = null;
int state = 0;
final int permissionReqState = 1;
final int initialState = 0;
final int dirHeaderSendState = 2;
final int fileHeaderSendState = 3;
final int fileSendState = 4;
final int fileFinishedState = 5;
private boolean isLive = false;
private int numFiles = 0;
private int filePointer = 0;
String request = "May I send?";
String respServer = "Yes,You can";
String dirResponse = "Directory created...Please send files";
String fileHeaderRecvd = "File header received ...Send File";
String fileReceived = "File Received";
String dirFailedResponse = "Failed";
File[] opFileList = null;
public DirectoryTxr(Socket clientSocket, String srcDir, String dstDir) {
try {
this.clientSocket = clientSocket;
inStream = clientSocket.getInputStream();
outStream = clientSocket.getOutputStream();
isLive = true;
this.srcDir = srcDir;
this.dstDir = dstDir;
state = initialState;
readResponse(); //starting read thread
sendMessage(request);
state = permissionReqState;
} catch (IOException io) {
io.printStackTrace();
}
}
private void sendMessage(String message) {
try {
sendBytes(request.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* Thread to read response from server
*/
private void readResponse() {
Runnable readRunnable = new Runnable() {
public void run() {
while (isLive) {
try {
int num = inStream.read(readBuffer);
if (num > 0) {
byte[] tempArray = new byte[num];
System.arraycopy(readBuffer, 0, tempArray, 0, num);
processBytes(tempArray);
}
} catch (SocketException se) {
System.exit(0);
} catch (IOException io) {
io.printStackTrace();
isLive = false;
}
}
}
};
Thread readThread = new Thread(readRunnable);
readThread.start();
}
private void sendDirectoryHeader() {
File file = new File(srcDir);
if (file.isDirectory()) {
try {
String[] childFiles = file.list();
numFiles = childFiles.length;
String dirHeader = "$" + dstDir + "#" + numFiles + "&";
sendBytes(dirHeader.getBytes("UTF-8"));
} catch (UnsupportedEncodingException en) {
en.printStackTrace();
}
} else {
System.out.println(srcDir + " is not a valid directory");
}
}
private void sendFile(String dirName) {
File file = new File(dirName);
if (!file.isDirectory()) {
try {
int len = (int) file.length();
int buffSize = len / 8;
//to avoid the heap limitation
RandomAccessFile raf = new RandomAccessFile(file, "rw");
FileChannel channel = raf.getChannel();
int numRead = 0;
while (numRead >= 0) {
ByteBuffer buf = ByteBuffer.allocate(1024 * 100000);
numRead = channel.read(buf);
if (numRead > 0) {
byte[] array = new byte[numRead];
System.arraycopy(buf.array(), 0, array, 0, numRead);
sendBytes(array);
}
}
System.out.println("Finished");
} catch (IOException io) {
io.printStackTrace();
}
}
}
private void sendHeader(String fileName) {
try {
File file = new File(fileName);
if (file.isDirectory())
return;//avoiding child directories to avoid confusion
//if want we can sent them recursively
//with proper state transitions
String header = "&" + fileName + "#" + file.length() + "*";
sendHeader(header);
sendBytes(header.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private void sendBytes(byte[] dataBytes) {
synchronized (clientSocket) {
if (outStream != null) {
try {
outStream.write(dataBytes);
outStream.flush();
} catch (IOException io) {
io.printStackTrace();
}
}
}
}
private void processBytes(byte[] data) {
try {
String parsedMessage = new String(data, "UTF-8");
System.out.println(parsedMessage);
setResponse(parsedMessage);
} catch (UnsupportedEncodingException u) {
u.printStackTrace();
}
}
private void setResponse(String message) {
if (message.trim().equalsIgnoreCase(respServer) && state == permissionReqState) {
state = dirHeaderSendState;
sendDirectoryHeader();
} else if (message.trim().equalsIgnoreCase(dirResponse) && state == dirHeaderSendState) {
state = fileHeaderSendState;
if (LocateDirectory()) {
createAndSendHeader();
} else {
System.out.println("Vacant or invalid directory");
}
} else if (message.trim().equalsIgnoreCase(fileHeaderRecvd) && state == fileHeaderSendState) {
state = fileSendState;
sendFile(opFileList[filePointer].toString());
state = fileFinishedState;
filePointer++;
} else if (message.trim().equalsIgnoreCase(fileReceived) && state == fileFinishedState) {
if (filePointer < numFiles) {
createAndSendHeader();
}
System.out.println("Successfully sent");
} else if (message.trim().equalsIgnoreCase(dirFailedResponse)) {
System.out.println("Going to exit....Error ");
// System.exit(0);
} else if (message.trim().equalsIgnoreCase("Thanks")) {
System.out.println("All files were copied");
}
}
private void closeSocket() {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean LocateDirectory() {
boolean status = false;
File file = new File(srcDir);
if (file.isDirectory()) {
opFileList = file.listFiles();
numFiles = opFileList.length;
if (numFiles <= 0) {
System.out.println("No files found");
} else {
status = true;
}
}
return status;
}
private void createAndSendHeader() {
File opFile = opFileList[filePointer];
String header = "&" + opFile.getName() + "#" + opFile.length() + "*";
try {
state = fileHeaderSendState;
sendBytes(header.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
}
}
private void sendListFiles() {
createAndSendHeader();
}
}
(ServerMain.java)
public class ServerMain {
public ServerMain() {
}
public static void main(String[] args) {
DirectoryRcr dirRcr = new DirectoryRcr();
}
}
(DirectoryRcr.java)
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
public class DirectoryRcr {
String request = "May I send?";
String respServer = "Yes,You can";
String dirResponse = "Directory created...Please send files";
String dirFailedResponse = "Failed";
String fileHeaderRecvd = "File header received ...Send File";
String fileReceived = "File Received";
Socket socket = null;
OutputStream ioStream = null;
InputStream inStream = null;
boolean isLive = false;
int state = 0;
final int initialState = 0;
final int dirHeaderWait = 1;
final int dirWaitState = 2;
final int fileHeaderWaitState = 3;
final int fileContentWaitState = 4;
final int fileReceiveState = 5;
final int fileReceivedState = 6;
final int finalState = 7;
byte[] readBuffer = new byte[1024 * 100000];
long fileSize = 0;
String dir = "";
FileOutputStream foStream = null;
int fileCount = 0;
File dstFile = null;
public DirectoryRcr() {
acceptConnection();
}
private void acceptConnection() {
try {
ServerSocket server = new ServerSocket(3339);
socket = server.accept();
isLive = true;
ioStream = socket.getOutputStream();
inStream = socket.getInputStream();
state = initialState;
startReadThread();
} catch (IOException io) {
io.printStackTrace();
}
}
private void startReadThread() {
Thread readRunnable = new Thread() {
public void run() {
while (isLive) {
try {
int num = inStream.read(readBuffer);
if (num > 0) {
byte[] tempArray = new byte[num];
System.arraycopy(readBuffer, 0, tempArray, 0, num);
processBytes(tempArray);
}
sleep(100);
} catch (SocketException s) {
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException i) {
i.printStackTrace();
}
}
}
};
Thread readThread = new Thread(readRunnable);
readThread.start();
}
private void processBytes(byte[] buff) throws InterruptedException {
if (state == fileReceiveState || state == fileContentWaitState) {
//write to file
if (state == fileContentWaitState)
state = fileReceiveState;
fileSize = fileSize - buff.length;
writeToFile(buff);
if (fileSize == 0) {
state = fileReceivedState;
try {
foStream.close();
} catch (IOException io) {
io.printStackTrace();
}
System.out.println("Received " + dstFile.getName());
sendResponse(fileReceived);
fileCount--;
if (fileCount != 0) {
state = fileHeaderWaitState;
} else {
System.out.println("Finished");
state = finalState;
sendResponse("Thanks");
Thread.sleep(2000);
System.exit(0);
}
System.out.println("Received");
}
} else {
parseToUTF(buff);
}
}
private void parseToUTF(byte[] data) {
try {
String parsedMessage = new String(data, "UTF-8");
System.out.println(parsedMessage);
setResponse(parsedMessage);
} catch (UnsupportedEncodingException u) {
u.printStackTrace();
}
}
private void setResponse(String message) {
if (message.trim().equalsIgnoreCase(request) && state == initialState) {
sendResponse(respServer);
state = dirHeaderWait;
} else if (state == dirHeaderWait) {
if (createDirectory(message)) {
sendResponse(dirResponse);
state = fileHeaderWaitState;
} else {
sendResponse(dirFailedResponse);
System.out.println("Error occurred...Going to exit");
System.exit(0);
}
} else if (state == fileHeaderWaitState) {
createFile(message);
state = fileContentWaitState;
sendResponse(fileHeaderRecvd);
} else if (message.trim().equalsIgnoreCase(dirFailedResponse)) {
System.out.println("Error occurred ....");
System.exit(0);
}
}
private void sendResponse(String resp) {
try {
sendBytes(resp.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private boolean createDirectory(String dirName) {
boolean status = false;
dir = dirName.substring(dirName.indexOf("$") + 1, dirName.indexOf("#"));
fileCount = Integer.parseInt(dirName.substring(dirName.indexOf("#") + 1, dirName.indexOf("&")));
if (new File(dir).mkdir()) {
status = true;
System.out.println("Successfully created directory " + dirName);
} else if (new File(dir).mkdirs()) {
status = true;
System.out.println("Directories were created " + dirName);
} else if (new File(dir).exists()) {
status = true;
System.out.println("Directory exists" + dirName);
} else {
System.out.println("Could not create directory " + dirName);
status = false;
}
return status;
}
private void createFile(String fileName) {
String file = fileName.substring(fileName.indexOf("&") + 1, fileName.indexOf("#"));
String lengthFile = fileName.substring(fileName.indexOf("#") + 1, fileName.indexOf("*"));
fileSize = Integer.parseInt(lengthFile);
dstFile = new File(dir + "/" + file);
try {
foStream = new FileOutputStream(dstFile);
System.out.println("Starting to receive " + dstFile.getName());
} catch (FileNotFoundException fn) {
fn.printStackTrace();
}
}
private void writeToFile(byte[] buff) {
try {
foStream.write(buff);
} catch (IOException io) {
io.printStackTrace();
}
}
private void sendBytes(byte[] dataBytes) {
synchronized (socket) {
if (ioStream != null) {
try {
ioStream.write(dataBytes);
} catch (IOException io) {
io.printStackTrace();
}
}
}
}
}
ClientMain.java and DirectoryTxr.java are the two classes under client application. ServerMain.java and DirectoryRcr.java are the two classes under Server application.
run the ClientMain.java and ServerMain.java
You can sort an array using Arrays.sort(...)
ie
String[] childFiles = file.list();
Arrays.sort(childFiles);
As I understand it, this will sort the files in natural order, based on the file name.
You can modify this by passing a custom Comparator...
Arrays.sort(childFiles, new Comparator<File>() {...}); // Fill out with your requirements...
Progress monitoring will come down to your requirements. Do you want to see only the overall progress of the number of files, the individual files, a combination of both?
What I've done in the past is pre-iterated the file list, calculated the total number of bytes to be copied and used a ProgressMonitor to display the overall bytes been copied...
Otherwise you will need to supply your own dialog. In either case, you will need use SwingUtilities.invokeLater to update them correctly.
Check out Concurrency in Swing for more details.
Network connectivity is subjective. You could simply send a special "message" to there server and wait for a response, but this only suggests that the message was sent and a recipt was received. It could just as easily fail when you start transfering the file again...