我用ServerSocket传送一组byte[]到client端,一共是86个字节,但是到client端后,只接收到82个字节, 后来,我分把server端传送的byte[]和client端接收的byte[]当成int型打印出来,发现丢失的字节是前四个,分别为-84,-19,0,5,原来我以为是client端接收的方式不当,后来发现,无论用BufferedInputStream或DataInputStream来包装输入流,都一样会有丢失的情况,请问这是什么原因造的?怎么解决呢?
调试欢乐多
import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;import sun.security.krb5.internal.bp;public class TServer implements Runnable
{
public void launch() throws Exception
{
TBean bean=new TBean();
bean.setId("111");
bean.setName("terry");
Objecter objer=new Objecter(bean);
byte b[]=objer.objectToBytes();
//这两行就是我写的Objecter,可以把Object对象变成byte[],代码在下面
ServerSocket server=new ServerSocket(TTestSocket.PORT);
System.out.println("Server is starting......");
while(true)
{
Socket client=server.accept();
OutputStream os=client.getOutputStream();
if(os!=null)
{
BufferedOutputStream bos=new BufferedOutputStream(os);
System.out.println("Server sended "+b.length+" bytes.");
String sendedContent=new String(b,0,b.length);
System.out.println(senedContent);
System.out.println("#################################");
for (int i = 0; i < b.length; i++)
{
System.out.print((int)b[i]);
System.out.print(',');
}
System.out.println('\n');
bos.write(b);
bos.flush();
os.close();
bos.close();
}
else
{
System.out.println("disconnect....");
} os.close();
client.close();
}
}
public void run()
{
try
{
launch();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
-----------------Client---------------------------------package shuffle;import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.Socket;public class TClient implements Runnable
{
public void launch() throws Exception
{
System.out.println("Client is starting......");
Socket client=new Socket("127.0.0.1",TTestSocket.PORT);
InputStream is=client.getInputStream();
//*************** BufferedInputStream的方式********************
if(is!=null)
{
BufferedInputStream bis=new BufferedInputStream(is);
ObjectInputStream ois=new ObjectInputStream(bis);
byte b[]=new byte[bis.available()];
bis.read(b);
System.out.println("client received:"+b.length+" bytes");
System.out.println("**********************************");
for (int i = 0; i < b.length; i++)
{
System.out.print((int)b[i]);
System.out.print(',');
}
System.out.println('\n');
String msg=new String(b,0,b.length);
System.out.println(msg);
// TBean bean=(TBean)ois.readObject();
// System.out.println("@@ name:"+bean.getName());
bis.close();
ois.close();
FileOutputStream fos=new FileOutputStream("after.txt");
fos.write(b);
fos.flush();
fos.close();
}
else
{
System.out.println("received null....");
}
is.close();
client.close();
} public void run()
{
try
{
launch();
//Thread.sleep(3000);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}____________________Objecter________________________________package shuffle;import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;public class Objecter
{
Object obj;
public Objecter(Object obj)
{
this.obj=obj;
}
public byte[] objectToBytes() throws Exception
{
byte b[]=null;
File tmp=new File("tmp.txt");
FileOutputStream fos=new FileOutputStream(tmp);
BufferedOutputStream bos=new BufferedOutputStream(fos);
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
FileInputStream fis=new FileInputStream(tmp);
BufferedInputStream bis=new BufferedInputStream(fis);
b=new byte[bis.available()];
bis.read(b);
fos.close();
bos.close();
oos.close();
fis.close();
bis.close();
return b;
}
}-----------------调用测试类------------------------------package shuffle;public class TTestSocket
{
public static int PORT=13564;
public static void main(String[] args) throws Exception
{
Thread t1=new Thread(new TServer());
Thread t2=new Thread(new TClient());
t2.start();
t1.start();
}
}
这个对象要序列化
首先传入ObjectInputStream构造器中的数据流对象不管是InputStream,BufferedInputStream,DataInputStream在他们传入到ObjectInputStrea以后自身的数据被修改,这样做可以防止这些数据流的read方法,如果在调用read方法的话会报java.io.EOFException的错误,因为数据流本身已经被修改了。这样可以尽可能的避免对象的修改,保持对象的正确性,一致性。我做了测试如果在TClient中得到TBean 的对象以后在调用Objecter对象把Client中的TBean还原成byte[]结果就和Server传过来得一样了。但前提示对象没有经过任何数据流的解析只是通过ObjectInputStream.readObject()得到的。