IndexOutOfBoundsException when transferring a file through sockets. urgent data transfer control - java

How can I resolve this error when transferring a file through sockets:
java.lang.IndexOutOfBoundsException
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:326)
at Client.getFile(Client.java:18)
I implemented a client server application for transferring a file using the TCP protocol. Server is parallel. It is also necessary to implement transmission control using urgent data. I did not find a solution on Java on the Internet.
Class Server:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private ServerSocket serverSocket;
public void start(int port) throws IOException {
serverSocket = new ServerSocket(port);
while (true)
new ClientHandler(serverSocket.accept()).start();
}
public void stop() throws IOException{
serverSocket.close();
}
private static class ClientHandler extends Thread {
private Socket clientSocket;
private DataOutputStream out;
private FileInputStream in;
public ClientHandler(Socket socket) {
this.clientSocket = socket;
}
public void run() {
try {
out = new DataOutputStream(clientSocket.getOutputStream());
out.writeInt((int) Prop.FILE_1.length());
} catch (IOException e) {
e.printStackTrace();
}
try {
in = new FileInputStream(Prop.FILE_1);
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
byte buf[] = new byte[512];
int len = 0;
try {
len = in.read(buf);
} catch (IOException e) {
e.printStackTrace();
}
if(len == -1) {
break;
}
try {
out.write(buf, 0, len);
} catch (IOException e) {
e.printStackTrace();
}
try {
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
/*try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}*/
}
}
}
Class Client:
import java.io.*;
import java.net.Socket;
public class Client {
private Socket clientSocket;
private FileOutputStream out;
private DataInputStream in;
public String getFile() throws IOException {
int i = 0;
int len;
byte buf[] = new byte[512];
Integer fileSize;
fileSize = in.readInt();
while (i < fileSize) {
len = in.read(buf);
if (len == -1) {
break;
}
i += len;
out.write(buf, 0, len);
out.flush();
}
out.close();
return in.readUTF();
}
public void startConnection(String ip, int port) throws IOException {
clientSocket = new Socket(ip, port);
out = new FileOutputStream(Prop.FILE_2);
in = new DataInputStream(clientSocket.getInputStream());
}
public void stopConnection() throws IOException {
in.close();
out.close();
clientSocket.close();
}
}
Test
public class TestCS {
#Test
// (threadPoolSize = 3, invocationCount = 6, timeOut = 1000)
public void givenClient1__whenServerResponds__thenCorrect() throws IOException {
SoftAssert softAssert = new SoftAssert();
Client client1 = new Client();
client1.startConnection("127.0.0.1", 555);
String file = client1.getFile();
System.out.println(file);
client1.stopConnection();
softAssert.assertEquals(file, "First file!!!");
softAssert.assertAll();
}
}

You are reading InputStream wrongly. The logic you are trying to put there is already available in DataInputStream.read(..) method. All you have to do is to check how many bytes it read from the stream.
Change your while loop in Client like this
while (i < fileSize) {
// javadoc for below : - https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#read(byte[])
len = in.read(buf);
if(len<0) {
break;
}
i += len;
out.write(buf, 0, len);
out.flush();
}
Note : I have not checked your logic. All I checked and corrected is the Exception you got.
Also, typically we do not read fileSize upfront. You generally keep on reading stream till you get EOF (-1) from the stream. Please check that logic as well.

Related

StreamCorruptedException: invalid type code: 64

I'm trying to send Message object from Server module to Client module. Unfortunately it throw java.io.StreamCorruptedException: invalid type code: 64 error. Does anyone know what is the problem with code below?
Client class from Server module
private boolean needToRun;
public final Socket socket;
private OutputStream outputStream;
private InputStream inputStream;
private ObjectOutputStream objOut;
private ObjectInputStream objIn;
public Client(Socket socket) {
this.needToRun = true;
this.socket = socket;
try {
this.outputStream = socket.getOutputStream();
this.inputStream = socket.getInputStream();
this.objOut = new ObjectOutputStream(outputStream);
this.objIn = new ObjectInputStream(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
run();
}
public void send(Message msg) {
try {
objOut.writeObject(msg);
objOut.flush();
objOut.reset();
} catch (Exception ex){
ex.printStackTrace();
}
}
public void close() {
needToRun = false;
}
public void run() {
new Thread(() -> {
while(needToRun) {
try {
int amount = inputStream.available();
if (amount != 0) {
Message msg = (Message) objIn.readObject();
receivedContent(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
public void receivedContent(Message msg) {
for (Client connection : Server.clients) {
connection.send(msg);
}
}
the Client class from Client module looks the same but receivedContent looks like this:
public void receivedContent(Message msg) {
String errorName = msg.content().trim();
MainPane.addLabel(errorName);
}
and last one Server class, which accepts socket connections:
while (true) {
System.out.println("running");
try {
System.out.println("Waiting for client...");
Socket socket = serverSocket.accept();
clients.add(new Client(socket));
} catch (Exception e) {
if (!serverSocket.isClosed()) {
stopServer();
}
break;
}
}

Send files with java socket

i am sending files from two java applications here the source code of the server and the client
public class FileClient {
private Socket s;
public FileClient(String host, int port, String file) {
try {
s = new Socket(host, port);
sendFile(file);
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendFile(String file) throws IOException {
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[4096];
while ((fis.read(buffer) > 0)) {
dos.write(buffer);
}
fis.close();
dos.close();
}
public static void main(String[] args) {
FileClient fc = new FileClient("192.168.0.167", 1988, "C:/Users/mhattabi/Desktop/fileData.txt");
}
}
and here the source code of the server
public class FileServer extends Thread {
private ServerSocket ss;
public FileServer(int port) {
try {
ss = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (true) {
try {
Socket clientSock = ss.accept();
saveFile(clientSock);
// ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void saveFile(Socket clientSock) throws IOException {
DataInputStream dis = new DataInputStream(clientSock.getInputStream());
FileOutputStream fos = new FileOutputStream("fileData.txt");
byte[] buffer = new byte[4096];
int filesize = 15123; // Send file size in separate msg
int read = 0;
int totalRead = 0;
int remaining = filesize;
while((read = dis.read(buffer)) > 0) {
totalRead += read;
System.out.println("read " + totalRead + " bytes.");
fos.write(buffer, 0, read);
}
fos.close();
dis.close();
}
public static void main(String[] args) {
FileServer fs = new FileServer(1988);
fs.start();
}
}
the problem that in the server i received the file but there is extra character in it look like this.Any help will be appreciated thanks
Usual problem.
while ((fis.read(buffer) > 0)) {
dos.write(buffer);
}
You're ignoring the count returned by the read, and assuming that it filled the buffer. It should be:
while ((count = fis.read(buffer) > 0)) {
dos.write(buffer, 0, count);
}
Curiously enough you have this right in the server. NB You don't need a DataOutputStream here.
byte[] buffer = new byte[4096];
I think the" extra character" come from this place;every time you write 4096 byte
,at last time it happened less than 4096 byte.and then you get extra character

Network communication isnĀ“t working

I made a little game. Now i want to get the highscore from my Server. The code on the client:
private int getOnlineHighscore() {
int highscore = 0;
try {
socket = new Socket("localhost", 444);
input = socket.getInputStream();
System.out.println(input);
highscore = input.read();
input.close();
socket.close();
input = null;
socket = null;
} catch (Exception e) {
System.out.println("Verbindung fehlgeschlagen!");
}
System.out.println(highscore);
return highscore;
}
And on the Server:
import java.io.*;
import java.net.*;
public class ReadServer extends Thread {
private Socket socket;
public ReadServer(Socket socket) {
super();
this.socket = socket;
}
public void run() {
try {
System.out.println(socket.getInetAddress());
String result = "";
try (BufferedReader br = new BufferedReader(
new FileReader(System.getProperty("user.home") + "/AppData/Roaming/GameServer/.sg"))) {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
System.out.println("2");
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
System.out.println("3");
result = sb.toString();
System.out.println("3.5");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("4");
socket.getOutputStream().write(Integer.parseInt(result));
System.out.println(result);
} catch (Exception e) {
}
try {
socket.close();
} catch (Exception e) {
}
}
public static void main(String[] Args) {
Socket socket = null;
ServerSocket server = null;
try {
server = new ServerSocket(444);
while (true) {
socket = server.accept();
new ReadServer(socket).start();
}
} catch (Exception e) {
}
try {
server.close();
} catch (Exception e) {
}
}
}
If I run it, the client function returns:
-1
The server writes in the console(not important I think):
/127.0.0.1
2
3
3.5
4
How to solve the problem? I want to send an int stored on my Server to a client.
-Jakob
-1 is returned by read() to specify end of stream , make sure data to be read is being returned .
What is the highscore stored in the file? I believe the file is empty and it fails on parsing the integer but as your catch block is empty, you don't see the exception. Put printStacktrace or rethrow.
Another problem is that OutputStream sends only bytes and therefore write method sends only low 8 bits. To send int wrap the stream with DataOutputStream and DataInputStream on the client side.

Java: A client/server file transfer (incomplete files)

I am building an application that will send file across the network through sockets.
There are 2 programs. Server and Client each have two classes Download and Upload.
public class Download implements Runnable{
public ServerSocket server;
public Socket socket;
public int port;
public String saveTo = "";
public InputStream In;
public FileOutputStream Out;
public Download(String saveTo){
try {
server = new ServerSocket(1544);
port = 1544;
this.saveTo = saveTo;
}
catch (IOException ex) {
System.out.println("Exception [Download : Download(...)]");
}
}
#Override
public void run() {
try {
socket = server.accept();
In = socket.getInputStream();
Out = new FileOutputStream(saveTo);
byte[] buffer = new byte[1024];
int count;
while((count = In.read(buffer)) >= 0){
Out.write(buffer, 0, count);
}
Out.flush();
if(Out != null){ Out.close(); }
if(In != null){ In.close(); }
if(socket != null){ socket.close(); }
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
and class Upload:
public class Upload implements Runnable{
public String addr;
public int port;
public Socket socket;
public FileInputStream In;
public OutputStream Out;
public File file;
public Upload(String addr, int port, File filepath){
super();
try {
file = filepath;
socket = new Socket("127.0.0.1",1545);
Out = socket.getOutputStream();
In = new FileInputStream(filepath);
}
catch (Exception ex) {
System.out.println("Exception [Upload : Upload(...)]");
}
}
#Override
public void run() {
try {
byte[] buffer = new byte[1024];
int count;
while((count = In.read(buffer)) >= 0){
Out.write(buffer, 0, count);
}
Out.flush();
if(In != null){ In.close(); }
if(Out != null){ Out.close(); }
if(socket != null){ socket.close(); }
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
And in the class server:
File myFile = new File("temp");
Upload upl = new Upload("temp", 1544,myFile)
fileThreadSend = new Thread(upl);
fileThreadSend.start();
and in class client:
Download dwn = new Download("temp");
Thread fileThread = new Thread(dwn);
fileThread.start();
the problem runs but it doesn't transfer all the file
sometimes it transfer just 9kb of it and sometimes 20 MBS.
what is wrong?
I tried to search but couldn't find applicable any solution.
Thanks in advance
Don't be bothered and use what the JDK has to offer:
create a file from an InputStream;
send the contents of a file to an OutputStream.
More details here. And don't forget to use try-with-resources.
Also, avoid using Thread directly and use an ExecutorService instead.

How to Run Server Client code using Socket Programming in Java Eclipse?

Client code:
import java.io.*;
import java.net.*;
public class SimpleClient {
public static void main(String[] args) throws IOException {
Socket clientSocket = null;
try {
clientSocket = new Socket(args[0], 4442);
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + args[0] + ".");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for " +
"the connection to: " + args[0] + "");
System.exit(1);
}
BufferedInputStream in;
BufferedOutputStream out;
try {
in = new BufferedInputStream(clientSocket.getInputStream());
out = new BufferedOutputStream(clientSocket.getOutputStream());
} catch (IOException e) {
System.out.println(e.toString());
return;
}
byte[] m_txt = args[1].getBytes();
out.write(m_txt, 0, m_txt.length);
out.flush();
byte[] m_rcv = new byte[m_txt.length];
int n = in.read(m_rcv, 0, m_rcv.length);
if (n != m_rcv.length) {
System.out.println("Some data are lost ...");
}
System.out.println(new String(m_rcv));
out.close();
in.close();
clientSocket.close();
}
}
Server:
import java.io.*;
import java.net.*;
public class SimpleServer {
public static void main(String[] args) throws IOException {
boolean listening = true;
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4442);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
while(listening) {
Socket clientSocket = serverSocket.accept();
(new SimpleConHandler(clientSocket)).start();
}
serverSocket.close();
}
}
Connection Handler:
import java.io.*;
import java.net.*;
public class SimpleConHandler extends Thread
{
private Socket clientSocket;
public SimpleConHandler(Socket clientSocket) {
this.clientSocket = clientSocket;
}
public void run() {
BufferedInputStream in;
BufferedOutputStream out;
try {
in = new BufferedInputStream(clientSocket.getInputStream());
out = new BufferedOutputStream(clientSocket.getOutputStream());
} catch (IOException e) {
System.out.println(e.toString());
return;
}
try {
byte[] msg = new byte[4096];
int bytesRead = 0;
int n;
while((n = in.read(msg, bytesRead, 256)) != -1) {
bytesRead += n;
if (bytesRead == 4096) {
break;
}
if (in.available() == 0) {
break;
}
}
for(int i=bytesRead; i>0; i--) {
out.write(msg[i-1]);
}
out.flush();
} catch(IOException e1) {
System.out.println(e1.toString());
}
try {
out.close();
in.close();
clientSocket.close();
} catch ( IOException e2 ) {;}
}
}
First i RUN Server, but when i try to RUN Client, the error which i am getting is:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at SimpleClient.main(SimpleClient.java:11)
May be i have to use different consoles to run both the Server and the Client? If so, then please tell me the way. i am using Java Eclipse 1.6 SE.
clientSocket = new Socket(args[0], 4442);
Your program needs a command line argument:
java your.Program <ip>

Categories