问题
I faced an issue while transferring file from client to server. So I did a simple client and server code in java using sockets. I found some unexpected behavior. I can't find why it happens so. Following is the code
Server side code:
import java.io.*;
import java.net.*;
class Server
{
public static void main(String args[])
{
ServerSocket ser;
try {
ser=new ServerSocket(9000);
Socket cnfcon=ser.accept();
OutputStream outstr=cnfcon.getOutputStream();
InputStream inpstr=cnfcon.getInputStream();
PrintWriter out=new PrintWriter(outstr,true);
BufferedReader inp=new BufferedReader(new InputStreamReader(inpstr));
File f=new File("test.txt");
InputStream fis= new FileInputStream(f);
long size=f.length();
System.out.println("Start Server");
out.println(f.getName());
out.println(size);
byte[] buff1=new byte[]{0,1,2,3,4,5,6,7,8,9};
byte[] buff2=new byte[]{7,1,2,3,8,5,6,7,8,9};
outstr.write(buff1);
//inpstr.read(); -- tried including this and removing this
outstr.write(buff2);
//inpstr.read();
fis.close();
inp.close();
ser.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
client side code:
import java.io.*;
import java.net.*;
class test
{
public static void main(String args[]) throws UnknownHostException, IOException
{
Socket cnfcon=new Socket("127.0.0.1",9000);
OutputStream outstr=cnfcon.getOutputStream();
InputStream inpstr=cnfcon.getInputStream();
PrintWriter out=new PrintWriter(outstr,true);
BufferedReader inp=new BufferedReader(new InputStreamReader(inpstr));
File f=new File(inp.readLine()+"t"); //"t" - dummy
f.createNewFile();
FileOutputStream fos=new FileOutputStream(f);
int size=Integer.parseInt(inp.readLine());
byte buff[]=new byte[1024];
System.out.println("Start Client");
inpstr.read(buff, 0, 10);
disp(buff);
//outstr.write(1); -- tried including this and removing this
inpstr.read(buff, 0, 10);
disp(buff);
//outstr.write(1); 1 - dummy value
fos.close();
out.close();
cnfcon.close();
}
public static void disp(byte buff[])
{
for(int i=0;i<10;i++)
System.out.print(buff[i]);
System.out.println();
}
};
I am sending two buffers from server to client.
Here I expect first buffer should come first and next for next time. But its unpredictable.
Some times it works as expected. Some times it gets the 2nd buff for both time. Some times all bytes in the buffer are zero.
I tried adding outstr.flush() before the message passing.
Is there any other way to implement this?
To be more clear, it seems client is not waiting for server to send or vice versa.
The output is different every time.
Suggestions are appreciated.
回答1:
The problems are at least two:
You're ignoring the count returned by
read()
, and assuming it filled the buffer. It isn't obliged to do that. It isn't contracted to transfer more than one byte. You have to loop:while ((count = in.read(buffer)) > 0) { out.write(buffer, 0, count); }
Data is disappearing into the buffered readers/writers/streams, and it is caused by using too many parts of the I/O stack. Don't use multiple readers, writers, and streams, on the same socket. Use a single output stream or writer and a single input stream or reader for the life of the socket. As you are writing binary data you shouldn't be using readers or writers at all.
Contrary to other answers here, it isn't necessary to add flushes or sleeps in this code, as long as you close everything correctly, or to fiddle around with available()
results either.
回答2:
Try adding a Thread.sleep()
in the client when it receives the buffers? Not sure if it will work.
回答3:
Let me guess , you are on Microsoft windows ?
First chunk your data into small chunks ( let's say 1kb ), but you are already doing that and then sleep a little bit in both your read and write loops. Call flush when possible after writes, and Be sure to make sure you don't read more than input stream.availible()
Your code should work on every other os without issue , without modification.
来源:https://stackoverflow.com/questions/28421496/java-socket-read-and-write-unexpected-behavior