java readInt() on server doesn't get the good int

Multi tool use
Multi tool use
The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


java readInt() on server doesn't get the good int



I'm implementing a "little" client/server app, like a Cloud.
The problem is: I'm new to Java.
So I've learned it a bit fast, and same for client/server communication, database, frames, threads.



I'm pretty sure my code won't be the best one, but the fact is: I have to use Java, and I have to do this fast. I won't try to optimize it, I just need it to work.



I have already implemented a lot, so I won't give all the code here, just explain what happens before my problem:
The main prog on client side opens a login frame. The client can register or login. Registration is working well, so let's say he logs in. If authentication works, that opens another frame, with "browse" and "upload" options. The idea is, he browse a file and then upload it. When he clicks on upload, it should call the upload function, which will send a byte[2] array to the server with a DataOutputStream object. (it sends first the size of the array, and then the array)



On the server side, when authentication works, it'll give the client socket to a "Cloud" class, which - until now - is just supposed to receive a byte array (it'll do more later, but for now I can't get this byte array)



But the server receives a size of 1970302063 instead of 2. I've checked the size before the writeInt on client size, it's 2. After the readInt on the server side, it's 1970302063.


writeInt


readInt



I don't understand it. Can the server receive something else somewhere and my beautiful 2 be lost in a buffer?



Server side:


public class Server {

public static void main(String zero) throws IOException {

ServerSocket serverSocket ;
Socket clientSocket ;
int tmp = 0; //when everything works, tmp will disappear

DataBase DB = new DataBase();
System.out.println("ouverture du server");
serverSocket = new ServerSocket(2017);


while(tmp<1) { //limit the number of connections allowed.
try {

clientSocket = serverSocket.accept();
Thread t = new Thread(new Connect(clientSocket, DB));
t.start();

//clients.printAll(); //just to see the DB.

}catch (IOException e) {
e.printStackTrace();
}
tmp++;
}
serverSocket.close();
}
}



As you can see, I'm authorising just 1 connection, because I'm still testing it and I don't want to change the port number each time I got an error / change something. With that I'll just have to restart server after each test.


public class Connect implements Runnable{
private DataBase DB;
private Socket clientSocket;

public Connect(Socket socket, DataBase DB) {
this.clientSocket = socket;
this.DB = DB;
}

public void run() {
try {
BufferedReader in;
PrintWriter out;
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream());
String mode = in.readLine();
String clientID = in.readLine();
String clientPwd = in.readLine();
if (mode.equals("auth")) {
Authentification auth = new Authentification (clientID, clientPwd, DB);
out.write(auth.getMessage()+"rn");
out.flush();
if (auth.getMessage().equals("Login Successfull. Welcome in SecureCloud!"))
new Cloud(clientSocket, DB); //launch Cloud.
}
else if (mode.equals("reg")) {
Registration reg= new Registration(clientID, clientPwd, DB);
out.write(reg.getMessage()+"rn");
out.flush();
}

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

try {
this.clientSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}



Now, here: authentication and registration will set up a connection, and the client socket is closed at the end. BUT, if the authentication is successful, then it create a new Cloud:


public class Cloud {
public Cloud(Socket clientSocket, DataBase DB) {
try {
DataInputStream dIn = new DataInputStream(clientSocket.getInputStream());
int length = dIn.readInt(); // read length of incoming message
System.out.println("byte array size: "+length);
byte shorthash;
if(length!=2) {
System.err.println("Incorrect size for shorthash!");
}

else {
shorthash = new byte[length];
dIn.readFully(shorthash, 0, shorthash.length); // read the message
System.out.println(shorthash);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}



As you can see, for now it doesn't do much. I know I'll have to add a while(true) loop so that the client can upload more files, but for now I'll be happy if I can send just this byte array.



Now, client side. I'll skip the main, it just open the login frame. I'll also skip most of the login Frame, it's just a frame...here is what happens when client click on "login":


public void actionPerformed(ActionEvent e)
{
if (e.getSource()==connectButton) {
Connection con = new Connection();
con.auth(username.getText(), password.getText());
if(con.getServerAnswer().equals("Login Successfull. Welcome in SecureCloud!")) {
this.setVisible(false);
con.setConnection(true);
con.setUsername(username.getText());
new Load_Frame(con.getUsername(),con.getSocket());
}
else System.out.println("erreur: " + con.getServerAnswer());
}
else if (e.getSource()==registerButton) {
this.setVisible(false);
new Registration_Frame();
}
}



So, it creates the connection and launch the authentification process (con.auth) with username and password. If it's successfull, it'll open the Load Frame with the username and socket used for this connection.
I'll skip again most of Load Frame, here are the actions:


public void actionPerformed(ActionEvent e)
{
if (e.getSource()== uploadButton) {
this.filename = uploadField.getText();
File file = new File(filename);
//TODO: change the upload function:
try {
client.upload(file);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
else if (e.getSource()== downloadButton) {
this.filename = downloadField.getText();
//TODO: change the download function
//download(filename);
}

else if (e.getSource()== browseButton) {
JFileChooser jc = new JFileChooser();
if(jc.showOpenDialog(this) != 1)
uploadField.setText(jc.getSelectedFile().getAbsolutePath());
}
}



And, last but not least, the "upload" function, called by client.upload(file):


client.upload(file)


public void upload(File originalFile) throws NoSuchAlgorithmException, NoSuchPaddingException, IOException {

//create the "FileData" object, which make the shorthash of the file.
FileData myfile = new FileData(originalFile, fileID);

//say to the server that we want to upload:
PrintWriter mode;
mode = new PrintWriter(socket.getOutputStream());
mode.println("upload");
mode.flush();

//Send shorthash to the server:
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
System.out.println("byte array size: "+myfile.shortHash.length);
out.writeInt(myfile.shortHash.length); // send the length of the byte array
//out.flush();
out.write(myfile.shortHash); //send the array

}



I've tried with and without the out.flush(), it doesn't make any difference.


out.flush()



With all that, here are the answers I get:

From client:


Asking for authentification...
Login Successfull. Welcome in SecureCloud!
No file uploaded
byte array size: 2



From server:


Connection to SQLite has been established.
ouverture du server
byte array size: 1970302063
Incorrect size for shorthash!



Of course, since I know the size of the byte array, I could easily tell the server "hey, the size is 2!" (I mean, directly initialize my array with new byte[2] )
But I would like to understand what happens here. Plus, if I'm not receiving the good size, maybe I won't receive the good array.





You appear to be writing text and reading in binary. I suggest you do one or the other not both unless you like confusion.
– Peter Lawrey
7 secs ago









By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

d8Tyhue6 gXyyWvdx49Dx155NHr8 sDd,9i0MXFKfNnBAAFiAzudbgUftsVdxe8ws3yP a
wCQiV,MSNLw3R,tUVONy13KX8sJajpsJUrFG,TW2Iok2 kVXJTgN1I BLGCco3ita5A6SFA,I,9Te0Yr6XUG,7qyjBSydCX0RjkON9Yg5U

Popular posts from this blog

Visual Studio Code: How to configure includePath for better IntelliSense results

Spring cloud config client Could not locate PropertySource

Makefile test if variable is not empty