在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問(wèn)答/Java/ [java I/O]在socket傳輸中,用writeUnshared()寫入對(duì)

[java I/O]在socket傳輸中,用writeUnshared()寫入對(duì)象,每次發(fā)送的是第一個(gè)對(duì)象

writeUnshared的API:
Writes an "unshared" object to the ObjectOutputStream. This method is identical to writeObject, except that it always writes the given object as a new, unique object in the stream (as opposed to a back-reference pointing to a previously serialized instance). Specifically:

  • An object written via writeUnshared is always serialized in the same manner as a newly appearing object (an object that has not been written to the stream yet), regardless of whether or not the object has been written previously.

  • If writeObject is used to write an object that has been previously written with writeUnshared, the previous writeUnshared operation is treated as if it were a write of a separate object. In other words, ObjectOutputStream will never generate back-references to object data written by calls to writeUnshared.

之前是用writeObject,不過(guò)在流中反復(fù)發(fā)送第一次發(fā)送的對(duì)象,調(diào)用hashcode()判斷了是同一對(duì)象,就不再寫這個(gè)對(duì)象到流了。后來(lái)查API看到了writeUnshared()方法

通過(guò) writeUnshared 寫入的對(duì)象總是作為新出現(xiàn)對(duì)象(未曾將對(duì)象寫入流中)被序列化,不管該對(duì)象以前是否已經(jīng)被寫入過(guò)。
但修改過(guò)后,仍未解決~

  • client

        try {
            DatagramSocket socket = new DatagramSocket(clientSocketAddr);
            DataPacketHeader dph = new DataPacketHeader(true,true,1,12);
            DataPacket dp = new DataPacket(dph);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream dos = new ObjectOutputStream(baos);
            int count = 0;
           for(int i = 0;i<3;i++){
               count++;
               dph.setAckNum(count);
               dos.writeUnshared(dph);//here!!!!!
                dos.flush();
               byte buf[] = baos.toByteArray();
               DatagramPacket dpk = new DatagramPacket(buf,buf.length,serverSocketAddr);
               socket.send(dpk);
               //dos.close();
           }
        } catch (SocketException e) {
            e.printStackTrace();
        }
  • server

        ByteArrayInputStream bais = null;
        ObjectInputStream ois = null;
        DatagramSocket socket = null;
        try {
            socket = new DatagramSocket(serverSocketAddr);
            byte recvBuf[] = new byte[1024 * 100];
            DatagramPacket recvDp = new DatagramPacket(recvBuf, recvBuf.length);
            DataPacketHeader dataPacket = null;
            while (true) {
                socket.receive(recvDp);
                bais = new ByteArrayInputStream(recvBuf);
                ois = new ObjectInputStream(bais);
                 dataPacket = (DataPacketHeader) ois.readUnshared();//here!!!!!
                System.out.println(dataPacket.getAckNum()+"|"+dataPacket.getSeqNum());
            }
        }catch(xxx){
           xxx
        }
        ...

所要序列化的對(duì)象

package main.common;

import java.io.Serializable;

public class DataPacketHeader implements Serializable {
    private boolean ACK;
    private boolean SYN;
    private int ackNum;
    private int seqNum;
    private int packetLength;

    public DataPacketHeader(boolean ACK, boolean SYN, int ackNum, int seqNum) {
        this.ACK = ACK;
        this.SYN = SYN;
        this.ackNum = ackNum;
        this.seqNum = seqNum;
        //this.packetLength = packetLength;
    }

    public boolean isACK() {
        return ACK;
    }

    public void setACK(boolean ACK) {
        this.ACK = ACK;
    }

    public boolean isSYN() {
        return SYN;
    }

    public void setSYN(boolean SYN) {
        this.SYN = SYN;
    }

    public int getAckNum() {
        return ackNum;
    }

    public void setAckNum(int ackNum) {
        this.ackNum = ackNum;
    }

    public int getSeqNum() {
        return seqNum;
    }

    public void setSeqNum(int seqNum) {
        this.seqNum = seqNum;
    }

    public int getPacketLength() {
        return packetLength;
    }

    public void setPacketLength(int packetLength) {
        this.packetLength = packetLength;
    }
}

結(jié)果:
1|12
1|12
1|12
讀取到的是同一對(duì)象

回答
編輯回答
敢試

你可以試下打印每次發(fā)送的packet的長(zhǎng)度,可以知道每次發(fā)送的對(duì)象都是逐步增大的,說(shuō)明bytearray中保存的數(shù)組一直在增大,所以,在server端讀的第一個(gè)對(duì)象永遠(yuǎn)是 1|12.
如果你想實(shí)現(xiàn)每次讀出來(lái)不一樣,就只能在for循環(huán)中new ByteArrayOutputStream和 ObjectOutputStream

    for (int i = 0; i < 3; i++) {
         count++;
         dph.setAckNum(count);
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ObjectOutputStream dos = new ObjectOutputStream(baos);
         dos.writeUnshared(dph);//here!!!!!

注:

  1. ByteArrayOutputStream的close中并未做任何事情,所以對(duì)baos.close也就沒(méi)有作用
  2. ObjectOutputStream的close中會(huì)調(diào)用flush,寫入到warpper的outputStream,并重置自己的position
2017年12月29日 07:28