Reputation: 63
In my project, I'm using a DataOutputStream
and DataInputStream
to send and receive bytes using sockets with threads.
Client
public void run(){
while(isRunning) {//which is true upon connection of the socket to the server
if(scanner.hasNext()){ // I use a scanner to test the program
dos = new DataOutputStream(new OutputStream(socket.getOutputStream));
byte[] toServer = scanner.next().getBytes();
dos.writeInt(toServer.length);
dos.write(toServer);
}
}
}
Server
public void run(){
while(isRunning){
if(scanner.hasNext()){
dis = new DataInputStream(new InputStream(socket.getInputStream));
int arrLength = dis.readInt();
byte[] fromClient = new byte[arrLength];
dis.read(fromClient, 0, fromClient.length);
System.out.println("Your string is: " + new String(fromClient));
}
}
}
The problem is, when I print out the new String(fromClient)
on the server side, the first character of the word/sentence is always missing. When I enter the word "Test"
on the client, the server prints out "est"
. But when I enter " Test"
(with a space at the beginning), the server prints out "Test"
. I don't understand what's wrong? Is there a problem with my byte conversion?
Upvotes: 2
Views: 5383
Reputation: 310869
You should use readFully() rather than read(), and you shouldn't keep reconstructing the streams for every read or write. Use the same streams for the life of the socket. Also what is the scanner attached to? If it's attached to the socket it will consume data from it.
Upvotes: 0
Reputation: 116858
The below code works for me. Given the typos in the post, I suspect that this is not the actual code that is running but rather an approximation and that this a bug in the real code. Here's some things to look for:
If you have a dis.readByte();
after the readInt()
call, that obviously will cut off the lead character. Make sure that your writes and reads are completely symmetric. Also make sure that your stream chain is symmetric.
If you are getting your stream from another class, make sure that it is not doing any read methods itself.
The current post is doing a new InputStream()
(and OutputStream
) which won't compile since they are abstract. If there is buffering in there you will need to make sure that you dos.flush();
. That would cause a hang however and not partial input.
String file = "/tmp/x";
DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
String inputString = "Test";
byte[] toServer = inputString.getBytes();
dos.writeInt(toServer.length);
dos.write(toServer);
DataInputStream dis = new DataInputStream(new FileInputStream(file));
int arrLength = dis.readInt();
byte[] fromClient = new byte[arrLength];
dis.read(fromClient, 0, fromClient.length);
// works fine for me
assertEquals(inputString, new String(fromClient));
Upvotes: 2