I have problem with filetransfer using SocketChannels: client ends to transfer the file, but the server still wait more byte from client. This causes a timeout, and the file will be saved less than a small part. The server remains stucked here: "fileChannel.transferFrom(socketChannel, 0, fileLength);".
Everything that happens before is working properly.
server:
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
import javax.imageio.ImageIO;
public class RequestHandler implements Runnable {
private SocketChannel socketChannel;
BufferedReader stringIn;
public RequestHandler(SocketChannel socketChannel) {
this.socketChannel = socketChannel;
// this.serverSocketChannel = socketChannel;
System.out.println("RequestHandler initialized");
}
public static int getLastPush(String dir) {
return new File("./" + dir).listFiles().length + 1;
}
public void run() {
LoadConfig config = null;
try {
config = new LoadConfig();
} catch (IOException e) {
e.printStackTrace();
}
String type = null;
try {
socketChannel.socket().setSoTimeout(10000);
MainServer.log("Client connected from: " + socketChannel);
// Prendere immagine
DataInputStream dis = new DataInputStream(socketChannel.socket().getInputStream());
// Leggo string
stringIn = new BufferedReader(new InputStreamReader(socketChannel.socket().getInputStream()));
// Invio al client
DataOutputStream dos = new DataOutputStream(socketChannel.socket().getOutputStream());
// leggo in ricezione
MainServer.log("Attendo auth");
String auth = stringIn.readLine();
// check auth
MainServer.log("Auth ricevuto: " + auth);
String pass = config.getPass();
if (pass.equals(auth)) {
dos.writeBytes("OK\n");
System.out.println("Client Authenticated");
type = stringIn.readLine();
System.out.println("fileType: " + type);
dos.writeBytes(type + "\n");
Integer i = getLastPush(config.getFolder());
String fileName = i.toString();
System.out.println("fileName: " + fileName);
switch (type) {
case "img":
// transfer image
int len = dis.readInt();
System.out.println("Transfer started.");
byte[] data = new byte[len];
dis.readFully(data);
System.out.println("Transfer ended.");
File toWrite = new File(config.getFolder() + "/" + fileName + ".png");
ImageIO.write(ImageIO.read(new ByteArrayInputStream(data)), "png", toWrite);
dos.writeBytes("http://" + config.getDomain() + "/" + toWrite.getName());
break;
case "file":
// transfer file
System.out.println("Transfer started.");
readFileFromSocket(config.getFolder() + "/" + fileName + ".zip");
System.out.println("Transfer ended.");
System.out.println("Sending link...");
dos.writeBytes("http://" + config.getDomain() + "/" + fileName + ".zip");
break;
default:
}
i++;
System.out.println("Chiudo");
dos.close();
dis.close();
stringIn.close();
} else {
dos.writeBytes("Invalid Id or Password");
System.out.println("Invalid Id or Password");
dos.close();
dis.close();
stringIn.close();
}
socketChannel.close();
} catch (Exception exc) {
exc.printStackTrace();
}
System.out.println("----------");
}
public void readFileFromSocket(String fileName) {
RandomAccessFile aFile = null;
try {
aFile = new RandomAccessFile(fileName, "rw");
FileChannel fileChannel = aFile.getChannel();
long fileLength = Long.parseLong(stringIn.readLine());
System.out.println("File length: " + fileLength);
fileChannel.transferFrom(socketChannel, 0, fileLength);
fileChannel.close();
Thread.sleep(1000);
fileChannel.close();
System.out.println("End of file reached, closing channel");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
client:
import java.awt.AWTException;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
import javax.imageio.ImageIO;
public class Uploader {
private BufferedImage img;
private byte[] bytes;
private SocketChannel socketChannel;
private String link;
private String fileName;
DataOutputStream dos;
// Per gli screen parziali
public Uploader(Rectangle r, String ip, int port) throws IOException, AWTException {
SocketChannel socketChannel = createChannel(ip, port);
this.socketChannel = socketChannel;
Rectangle screenRect = new Rectangle(0, 0, 0, 0);
for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
screenRect = screenRect.union(gd.getDefaultConfiguration().getBounds());
}
this.img = new Robot().createScreenCapture(screenRect).getSubimage(r.x, r.y, r.width, r.height);
ByteArrayOutputStream outputArray = new ByteArrayOutputStream();
ImageIO.write(img, "png", outputArray);
outputArray.flush();
this.bytes = outputArray.toByteArray();
outputArray.close();
}
// Per gli screen completi
public Uploader(BufferedImage bi, String ip, int port) throws IOException {
SocketChannel socketChannel = createChannel(ip, port);
this.socketChannel = socketChannel;
this.img = bi;
ByteArrayOutputStream outputArray = new ByteArrayOutputStream();
ImageIO.write(img, "png", outputArray);
outputArray.flush();
this.bytes = outputArray.toByteArray();
outputArray.close();
}
// Per i file
public Uploader(String fileName, String ip, int port) throws UnknownHostException, IOException {
SocketChannel socketChannel = createChannel(ip, port);
this.socketChannel = socketChannel;
// this.socket = new Socket(ip, port);
this.fileName = fileName;
}
public void send(String pass, String type) throws IOException {
dos = new DataOutputStream(socketChannel.socket().getOutputStream());
BufferedReader stringIn = new BufferedReader(new InputStreamReader(socketChannel.socket().getInputStream()));
try {
socketChannel.socket().setSoTimeout(10000);
// send auth
System.out.println("Sending auth");
dos.writeBytes(pass + "\n");
System.out.println("Auth sent: " + pass);
this.link = stringIn.readLine();
// this.link = os.println();
System.out.println("Auth reply: " + link);
if (this.link.equals("OK")) {
System.out.println("Sending type: " + type);
dos.writeBytes(type + "\n");
// Controllo e aspetto che il server abbia ricevuto il type
// corretto
if (stringIn.readLine().equals(type)) {
System.out.println("Il server riceve un: " + type);
switch (type) {
// image transfer
case "img":
System.out.println("Uploading image...");
dos.writeInt(bytes.length);
dos.write(bytes, 0, bytes.length);
dos.flush();
break;
// file transfer
case "file":
sendFile(fileName);
break;
// default case, hmm
default:
break;
}
// return link
System.out.println("Waiting link...");
this.link = stringIn.readLine();
System.out.println("Returned link: " + link);
bytes = null;
} else {
System.out.println("The server had a bad interpretation of the fileType");
}
} else {
System.out.println("Closed");
}
dos.close();
stringIn.close();
socketChannel.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public SocketChannel createChannel(String ip, int port) {
SocketChannel socketChannel = null;
try {
socketChannel = SocketChannel.open();
SocketAddress socketAddress = new InetSocketAddress(ip, port);
socketChannel.connect(socketAddress);
System.out.println("Connected, now sending the file...");
} catch (IOException e) {
e.printStackTrace();
}
return socketChannel;
}
public void sendFile(String fileName) {
RandomAccessFile aFile = null;
try {
File file = new File(fileName);
aFile = new RandomAccessFile(file, "r");
FileChannel inChannel = aFile.getChannel();
long bytesSent = 0, fileLength = file.length();
System.out.println("File length: " + fileLength);
dos.writeBytes(fileLength + "\n");
// send the file
while (bytesSent < fileLength) {
bytesSent += inChannel.transferTo(bytesSent, fileLength - bytesSent, socketChannel);
}
inChannel.close();
Thread.sleep(1000);
System.out.println("End of file reached..");
aFile.close();
System.out.println("File closed.");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public String getLink() {
return link;
}
}
You're losing data in the BufferedReader. If you look at the file that has been received you'll see that part of it is missing at the beginning.
You can't mix buffered and unbuffered input on the same channel. I suggest you use a DataInputStream and use read/writeUTF() to transfer the filename, andread/writeLong() to transfer the length.
I can't imagine why you're using different code to transfer images and other files. It's all bytes.
Related
I am writing a simple web server program for class that sends files to the web browser on request. I have written as much as I could. The difficulty is getting the data written to the OutputStream. I don't know what I am missing. I couldn't get the simple request to show up on the web browser.
I wrote it to the "name" OutputStream but when I reload the tab in the browser with the URL: "http://localhost:50505/path/file.txt" or any other like that "localhost:50505" it doesn't show up what I wrote to the OutputStream "name". It is supposed to show that.
package lab11;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketImpl;
import java.util.Scanner;
import java.io.OutputStream;
import java.io.PrintWriter;
public class main {
private static final int LISTENING_PORT = 50505;
public static void main(String[] args) {
ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(LISTENING_PORT);
}
catch (Exception e) {
System.out.println("Failed to create listening socket.");
return;
}
System.out.println("Listening on port " + LISTENING_PORT);
try {
while (true) {
Socket connection = serverSocket.accept();
System.out.println("\nConnection from "
+ connection.getRemoteSocketAddress());
handleConnection(connection);
}
}
catch (Exception e) {
System.out.println("Server socket shut down unexpectedly!");
System.out.println("Error: " + e);
System.out.println("Exiting.");
}
}
public static void handleConnection(Socket sok) {
try {
// Scanner in = new Scanner(sok.getInputStream());
InputStream one = sok.getInputStream();
InputStreamReader isr = new InputStreamReader(one);
BufferedReader br = new BufferedReader(isr);
String rootDirectory = "/files";
String pathToFile;
// File file = new File(rootDirectory + pathToFile);
StringBuilder request = new StringBuilder();
String line;
line = br.readLine();
while (!line.isEmpty()) {
request.append(line + "\r\n");
line = br.readLine();
}
// System.out.print(request);
String[] splitline = request.toString().split("\n");
String get = null;
String file = null;
for (String i : splitline) {
if (i.contains("GET")) {
get = i;
String[] splitget = get.split(" ");
file = splitget[1];
}
}
}
OutputStream name = sok.getOutputStream();
Boolean doesexist = thefile.exists();
if (doesexist.equals(true)) {
PrintWriter response = new PrintWriter(System.out);
response.write("HTTP/1.1 200 OK\r\n");
response.write("Connection: close\r\n");
response.write("Content-Length: " + thefile.length() + "\r\n");
response.flush();
response.close();
sendFile(thefile, name);
} else {
System.out.print(thefile.exists() + "\n" + thefile.isDirectory() + "\n" + thefile.canRead());
}
}
catch (Exception e) {
System.out.println("Error while communicating with client: " + e);
}
finally { // make SURE connection is closed before returning!
try {
sok.close();
}
catch (Exception e) {
}
System.out.println("Connection closed.");
}
}
private static void sendFile(File file, OutputStream socketOut) throws
IOException {
InputStream in = new BufferedInputStream(new FileInputStream(file));
OutputStream out = new BufferedOutputStream(socketOut);
while (true) {
int x = in.read(); // read one byte from file
if (x < 0)
break; // end of file reached
out.write(x); // write the byte to the socket
}
out.flush();
}
}
So, I don't know what I really did wrong.
When I load the browser with localhost:50505 it just says can't connect or localhost refused to connect.
You are writing the HTTP response in System.out. You should write it in name, after the headers, in the body of the response. You probably want to describe it with a Content-Type header to make the receiver correctly show the file.
I wrote a Java server application that returns a file when it is requested by a browser. The browser makes a GET request to my socket and the socket returns the file. But the browser (firefox in my case) treats the html file as a regular text file and does not render the actual page. So the browser shows the whole html source code. How can I fix that?
Here the Code:
package ml.mindlabor.networking;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
static final int PORT = 9806;
static final int MAX_BYTES_PER_STREAM = 10_000; // 10 kB
static final String FILE_SYSTEM_PATH = "C:\\Users\\SBrau\\eclipse-workspace\\Networking\\src\\ml\\mindlabor\\networking\\Files\\public_html";
static boolean running = true;
ServerSocket ss = null;
Socket soc = null;
public static void main(String[] args) {
Server server = new Server();
// When the connection could not be established
System.out.println("Waiting for connection ...");
if (!server.connect()) return;
server.listenForResponse();
}
public Server() {
try {
ss = new ServerSocket(PORT);
} catch (IOException e) {
System.err.println("Could not create ServerSocket on Port " + PORT);
shutdown();
}
}
boolean respond(String response) {
try {
PrintWriter out = new PrintWriter(soc.getOutputStream(), true);
out.println(response);
return true;
} catch (IOException e) {
System.err.println("Could not send to Port " + PORT);
}
return false;
}
boolean respond(byte[] response) {
try {
soc.getOutputStream().write(response);
return true;
} catch (IOException e) {
System.err.println("Could not send to Port " + PORT);
}
return false;
}
boolean respondFile(String relPath) {
String path = Server.FILE_SYSTEM_PATH + relPath;
File file = new File(path);
try {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
byte[] buffer = new byte[(int)file.length()]; // or 4096, or more
in.read(buffer, 0, buffer.length);
soc.getOutputStream().write(buffer, 0, buffer.length);
System.out.println("Loaded :D");
in.close();
soc.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
String rawDataToString(byte[] rawData) {
return new String(rawData);
}
void listenForResponse() {
new Thread(() -> {
while (true) {
try {
DataInputStream in = new DataInputStream(soc.getInputStream());
byte[] packetData = new byte[MAX_BYTES_PER_STREAM];
in.read(packetData);
receivedPackage(packetData);
} catch (IOException e) {
System.err.println("Could not get data from port " + PORT);
shutdown();
}
}
}).start();
}
void shutdown() {
Server.running = false;
}
void receivedPackage(byte[] pkg) {
String request = new String(pkg).trim();
// GET Request for file
if (request.contains("GET ")) {
String[] arr = request.split(" ");
respondFile(arr[1].trim());
}
}
boolean connect() {
try {
soc = ss.accept();
//soc.setKeepAlive(true);
System.out.println("Connected!");
return true;
} catch (IOException e) {
System.err.println("Could not wait for connection on port " + PORT);
shutdown();
}
return false;
}
}
Ok. Got it. I solved it by rewriting the following method:
boolean respondFile(String relPath) {
String path = Server.FILE_SYSTEM_PATH + relPath;
File file = new File(path);
try {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
PrintWriter out = new PrintWriter(soc.getOutputStream());
BufferedOutputStream dataOut = new BufferedOutputStream(soc.getOutputStream());
byte[] fileData = readFileData(file, (int)file.length());
out.println("HTTP/1.1 501 Not Implemented");
out.println("Content-type: text/html");
out.println(); // blank line between headers and content, very important !
out.flush();
dataOut.write(fileData, 0, fileData.length);
dataOut.flush();
System.out.println("Loaded :D");
in.close();
soc.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
private byte[] readFileData(File file, int fileLength) throws IOException {
FileInputStream fileIn = null;
byte[] fileData = new byte[fileLength];
try {
fileIn = new FileInputStream(file);
fileIn.read(fileData);
} finally {
if (fileIn != null)
fileIn.close();
}
return fileData;
}
I need to transfer few files to different computers, 1 file per 1 computer. Now i can only transfer 1 file to 1 computer. Also some computers from my IP pool can be offline, how can i avoid Exception?
Also I have all code in github:
https://github.com/xym4uk/Diplom/tree/master/src/xym4uk/test
Client
package xym4uk.test;
import java.io.*;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class FileClient {
private static Socket sock;
private static String fileName;
private static BufferedReader stdin;
private static PrintStream ps;
public static void main(String[] args) throws IOException {
public static void sendFile(File myFile) {
//connecting
try {
sock = new Socket("localhost", 4444);
ps = new PrintStream(sock.getOutputStream());
ps.println("1");
} catch (Exception e) {
System.err.println("Cannot connect to the server, try again later.");
System.exit(1);
}
try {
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
dis.readFully(mybytearray, 0, mybytearray.length);
OutputStream os = sock.getOutputStream();
//Sending file name and file size to the server
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(myFile.getName());
dos.writeLong(mybytearray.length);
dos.write(mybytearray, 0, mybytearray.length);
dos.flush();
System.out.println("File " + myFile.getName() + " sent to Server.");
} catch (Exception e) {
System.err.println("File does not exist!");
}
DataBase.setRecord(sock.getInetAddress().toString(), myFile.getName());
try {
sock.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void receiveFile(String fileName) {
try {
sock = new Socket("localhost", 4444);
ps = new PrintStream(sock.getOutputStream());
ps.println("2");
ps.println(fileName);
} catch (Exception e) {
System.err.println("Cannot connect to the server, try again later.");
System.exit(1);
}
try {
int bytesRead;
InputStream in = sock.getInputStream();
DataInputStream clientData = new DataInputStream(in);
fileName = clientData.readUTF();
OutputStream output = new FileOutputStream(("received_from_server_" + fileName));
long size = clientData.readLong();
byte[] buffer = new byte[1024];
while (size > 0 && (bytesRead = clientData.read(buffer, 0, (int) Math.min(buffer.length, size))) != -1) {
output.write(buffer, 0, bytesRead);
size -= bytesRead;
}
output.close();
in.close();
System.out.println("File " + fileName + " received from Server.");
} catch (IOException ex) {
Logger.getLogger(CLIENTConnection.class.getName()).log(Level.SEVERE, null, ex);
}
try {
sock.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server
package xym4uk.test;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class FileServer {
private static ServerSocket serverSocket;
private static Socket clientSocket = null;
public static void main(String[] args) throws IOException {
try {
serverSocket = new ServerSocket(4444);
System.out.println("Server started.");
} catch (Exception e) {
System.err.println("Port already in use.");
System.exit(1);
}
while (true) {
try {
clientSocket = serverSocket.accept();
System.out.println("Accepted connection : " + clientSocket.getInetAddress());
Thread t = new Thread(new CLIENTConnection(clientSocket));
t.start();
} catch (Exception e) {
System.err.println("Error in connection attempt.");
}
}
}
}
ClientConnection
package xym4uk.test;
import java.io.*;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CLIENTConnection implements Runnable {
private Socket clientSocket;
private BufferedReader in = null;
public CLIENTConnection(Socket client) {
this.clientSocket = client;
}
#Override
public void run() {
try {
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String clientSelection;
while ((clientSelection = in.readLine()) != null) {
switch (clientSelection) {
case "1":
receiveFile();
break;
case "2":
String outGoingFileName;
while ((outGoingFileName = in.readLine()) != null) {
sendFile(outGoingFileName);
}
break;
default:
System.out.println("Incorrect command received.");
break;
}
in.close();
break;
}
} catch (IOException ex) {
Logger.getLogger(CLIENTConnection.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void receiveFile() {
try {
int bytesRead;
DataInputStream clientData = new DataInputStream(clientSocket.getInputStream());
String fileName = clientData.readUTF();
OutputStream output = new FileOutputStream(("received_from_client_" + fileName));
long size = clientData.readLong();
byte[] buffer = new byte[1024];
while (size > 0 && (bytesRead = clientData.read(buffer, 0, (int) Math.min(buffer.length, size))) != -1) {
output.write(buffer, 0, bytesRead);
size -= bytesRead;
}
output.close();
clientData.close();
System.out.println("File "+fileName+" received from client.");
} catch (IOException ex) {
System.err.println("Client error. Connection closed.");
}
}
public void sendFile(String fileName) {
try {
//handle file read
File myFile = new File(fileName);
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
dis.readFully(mybytearray, 0, mybytearray.length);
//handle file send over socket
OutputStream os = clientSocket.getOutputStream();
//Sending file name and file size to the client
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(myFile.getName());
dos.writeLong(mybytearray.length);
dos.write(mybytearray, 0, mybytearray.length);
dos.flush();
System.out.println("File "+fileName+" sent to client.");
} catch (Exception e) {
System.err.println("File does not exist!");
}
}
}
These classes succeed to communicate when they are on the same computer. But as soon as we move the "Antenna" to another computer(still on same network) the server still gets the package BUT the client just keeps waiting for a reply.
We have checked som other threads at this site but we still can't find our problem. Anyone who can help?
SERVER RECEIVER CLASS:
package Server;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.sql.Timestamp;
import java.util.Vector;
public class RecieverProxy extends Thread {
private DatagramSocket socket;
private static int length;
private String reqS;
public static java.util.Date date = new java.util.Date();
public static Timestamp currentTimestamp = new Timestamp(date.getTime());
#Override
public void run() {
try {
System.out.println(currentTimestamp + " Server[IP=\""
+ InetAddress.getLocalHost().getHostAddress()
+ "\"]: Local server is Running...");
System.out.println(currentTimestamp
+ " SERVER: Connecting to MySQL server...");
DbUpdater.readyDatabase();
System.out.println(currentTimestamp
+ " SERVER: MySQL server is connected!");
} catch (UnknownHostException e) {
e.printStackTrace();
System.exit(1);
}
System.err.println(currentTimestamp + " SERVER: Ready... waiting...");
try {
recieveSendUDP();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* The method will wait for a request, process the request, and then return
* the reply.
*
* #throws InterruptedException
*/
public boolean recieveSendUDP() throws IOException, InterruptedException {
socket = new DatagramSocket(6789);
// modtag forespørgsler
while (true) {
try {
byte[] bytes = new byte[1000];
DatagramPacket request = new DatagramPacket(bytes, bytes.length);
socket.receive(request);
length = request.getLength();
String replyS = "ERROR";
String oldreqS = new String(request.getData());
if (oldreqS == "[]") {
System.out.println(currentTimestamp
+ " None bluetooth devices nearby");
replyS = "None bluetooth devices nearby";
} else {
String subreqS = oldreqS.substring(0, length);
String leftreqS = subreqS.replace("[", "'");
String rightreqS = leftreqS.replace("]", "'");
reqS = rightreqS.replaceAll(", ", "','");
replyS = currentTimestamp
+ " SERVER: MAC addresses recieved.";
}
// gør svar klar
int dstPort = request.getPort();
InetAddress dstAdr = request.getAddress();
System.out.println(currentTimestamp
+ " SERVER: Sending reply to IP: " + dstAdr.toString()
+ " på port " + dstPort);
DatagramSocket replySocket = new DatagramSocket();
replySocket.send(new DatagramPacket(replyS.getBytes(), replyS
.getBytes().length, new InetSocketAddress(dstAdr,
dstPort)));
replySocket.close();
DbUpdater.dbUpdate(reqS);
} catch (Exception e) {
}
}
}
}
ANTENNA SENDER CLASS:
package Antenna;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.sql.Timestamp;
import java.util.Vector;
public class SendRemoteDevices {
public static java.util.Date date = new java.util.Date();
public static Timestamp currentTimestamp = new Timestamp(date.getTime());
public static void runMacSender() throws IOException, InterruptedException {
Vector<String> macAdds;
macAdds = RemoteDeviceDiscovery.getMacVec();
System.out.println(currentTimestamp
+ " ANTENNA: Sending macaddresses: " + macAdds);
sendMacc(macAdds);
}
public static void sendMacc(Vector<String> macAdd) {
String request = new Vector<String>(macAdd).toString().trim();
String reply = sendReceive(request);
}
// send string and receive string
// her skal serverens addresse stå
#SuppressWarnings("resource")
public static String sendReceive(String request) {
String ip = "192.168.10.106";
String serverIP = ip; // sæt anden IP ind hvis du kører
// mellem
// to maskiner
DatagramSocket ds = null;
byte[] bytes = request.getBytes(); // husk : er seperator
// sending package after encrypting.
try {
ds = new DatagramSocket();
ds.send(new DatagramPacket(bytes, bytes.length,
new InetSocketAddress(serverIP, 6789)));
System.out.println(currentTimestamp
+ " ANTENNA: Send this to serveren: \"" + request + "\"");
System.out.println(currentTimestamp
+ " ANTENNA: Waiting for answer from Server...");
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// gør mig klar til at modtage
byte[] repBytes = new byte[1000];
DatagramPacket repGram = new DatagramPacket(repBytes, repBytes.length);
try {
ds.receive(repGram);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} // receive
// trim er nødvendigt
String reply = new String(repGram.getData()).trim();
System.out.println(currentTimestamp
+ " ANTENNA: Reply from Server: \"" + reply + "\"");
try { // fordi den ikke printer ovenstående før menuen
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return reply;
}
}
I've been working on a Client/Server project and I'm stuck. I'm trying to write a back-up server so I can back-up my files to a remote computer. The problem is when I try to back-up my /home/user file, it gives me the following error on the server side:
java.io.UTFDataFormatException: malformed input around byte ...
I first send the size of the file, then I read the file into a byte array and then is send this byte array at once to the server, who receives it in a byte array it constructed using the file size. Is it a better solution to divide files into chunks or will the error remain?
This usually happens on a .zip file, but it doesn't always happen so that is why I'm confused. Can anyone help me out?
Code:
Server:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private ServerSocket server;
private Socket acceptingSocket;
public Server(int port){
try {
server = new ServerSocket(port);
} catch (IOException e) {
System.out.println("Try again");
}
}
public void run(){
BufferedInputStream buffer = null;
DataInputStream reader = null;
int size = 0;
try {
acceptingSocket = server.accept();
buffer = new BufferedInputStream(acceptingSocket.getInputStream());
reader = new DataInputStream(buffer);
size = reader.readInt();
} catch (IOException e1) {
}
System.out.println("Size: " + size);
for(int j = 0; j < size; j++){
try {
String path = reader.readUTF();
System.out.println("Path: " + path);
long length = reader.readLong();
System.out.println("Length: "+length);
boolean dir = reader.readBoolean();
System.out.println("Dir? " + dir);
path = "/backup" + path;
File file = new File(path);
if(!dir){
int t = file.getAbsolutePath().lastIndexOf("/");
String dirs = file.getAbsolutePath().substring(0, t);
File direcs = new File(dirs);
System.out.println(direcs.mkdirs());
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] b = new byte[(int) length];
int bytes = reader.read(b, 0, (int)length);
if(bytes != -1)
bos.write(b,0,(int)length);
BufferedOutputStream out = new BufferedOutputStream(acceptingSocket.getOutputStream());
DataOutputStream writer = new DataOutputStream(out);
writer.writeUTF("File " + file.getAbsolutePath() + " is created!");
writer.flush();
bos.close();
} else file.mkdirs();
} catch (IOException e) {
System.out.println(e);
}
}
}
public static void main(String[] args){
int port = Integer.parseInt(args[0]);
Server server = new Server(port);
while(true)
server.run();
}
}
Client:
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;
public class Client {
private DataInputStream serverToClient;
private Socket client;
private DataOutputStream clientToServer;
private String name;
public Client(String name, int port){
try {
client = new Socket(name, port);
//receive response server
serverToClient = new DataInputStream(client.getInputStream());
//send message to server
clientToServer = new DataOutputStream(client.getOutputStream());
this.name = name;
}
catch (IOException e) {
}
}
public void backUp(String filePath){
File file = new File(filePath);
CopyOnWriteArrayList<File> files = new CopyOnWriteArrayList<File>();
if(file.exists()){
try{
if(file.isDirectory()){
ArrayList<File> f = setToList(file.listFiles());
files.addAll(f);
for(File sendF : files){
if(sendF.isDirectory()){
files.addAll(setToList(sendF.listFiles()));
if(!setToList(sendF.listFiles()).isEmpty()) files.remove(sendF);
}
}
} else{
files.add(file);
}
clientToServer.writeInt(files.size());
for(File fi : files){
boolean dir = false;
if(fi.isDirectory()) dir = true;
clientToServer.writeUTF(fi.getAbsolutePath());
System.out.println(fi.getAbsolutePath());
long length = fi.length();
clientToServer.writeLong(length);
clientToServer.writeBoolean(dir);
System.out.println(length);
if(!dir){
FileInputStream fis = new FileInputStream(fi);
BufferedInputStream bis = new BufferedInputStream(fis);
byte[] buffer = new byte[(int)length];
bis.read(buffer, 0, (int)length);
clientToServer.write(buffer);
System.out.println(serverToClient.readUTF());
bis.close();
fis.close();
}
}
} catch(IOException e){
}
} else System.out.println("File doesn't exist");
}
private ArrayList<File> setToList(File[] listFiles) {
ArrayList<File> newFiles = new ArrayList<File>();
for(File lf : listFiles){
newFiles.add(lf);
}
return newFiles;
}
public static void main(String[] args){
String name = args[0];
int port = Integer.parseInt(args[1]);
System.out.println("Name: " + name + " Port: " + port);
Client client = new Client(name, port);
File file = new File(args[2]);
if(file.exists())client.backUp(args[2]);
else System.out.println("File doesn't exist");
}
}