简体   繁体   中英

Socket's input byte stream wrapped in two different stream types?

I'm trying to implement such a protocol:

Client side:
 1) client sends     command (String)
 2) client sends     object
 3) client receives  object or data   [depends on command]
Server side:
 1) server reads     command (String)
 2) server receives  object           [type depends on command]
 3) server sends     object or data   [depends on command]

On client side, I'm doing something like this (program blocks on line, marked with "!!!"):

/** Retrieves required wrapper streams */
private void getSocketStreams() {
    try {
        inputStream         = new DataInputStream(
                                    connection.getInputStream());

        /* !!! here is a problem: can I do next line's stuff? */
        inputObjectStream   = new ObjectInputStream(
                                    connection.getInputStream());

        outputWriter        = new BufferedWriter(
                                new OutputStreamWriter(
                                    connection.getOutputStream()));
        outputObjectStream  = new ObjectOutputStream(
                                    connection.getOutputStream());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

/** "put" command processor */
private int processCmdPut(OrderInfo orderInfo) {

    /* Send command to peer */
    try {
        outputWriter.write("put");
        outputWriter.newLine();
        outputWriter.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }

    /* Send inserted object to peer */
    sendObject(orderInfo);

    /* Get from peer inserted info id */
    int id = -1;
    try {
        id = inputStream.readInt();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return id;
}


/**
 * Sends object to peer.
 * @param obj object to send.
 */
public void sendObject(Object obj){
    try {
        outputObjectStream.writeObject(obj);
        outputObjectStream.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Server's side actions a mirrored client's.

The question about line, marked with "!!!": is it possible to wrap socket's byte stream with two different high-lever streams and read/write into them by turns (one by one)? Am I wrong? There is my error or misunderstanding?

Buffering tends to make using different decorators chains difficult at best. You really don't want to be mixing text and binary data on the same stream. I suggest writing text in the same format you are using for the binary data.

Here is server side code, just in case:

/** Retrieves required wrapper streams */
private void getSocketStreams() {
    try {
        inputReader         = new BufferedReader(
                                new InputStreamReader(
                                    clientSocket.getInputStream()));
        inputObjectStream   = new ObjectInputStream(
                                    clientSocket.getInputStream());
        outputStream        = new DataOutputStream(
                                    clientSocket.getOutputStream());
        outputObjectStream  = new ObjectOutputStream(
                                    clientSocket.getOutputStream());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

/**
 * Process distinct command from client.
 * @param cmd command to process
 * @return connection state flag.
 */
private boolean processCmd(String cmd) {
    if ("put".equals(cmd)) {
        System.out.println(cmd);
        processCmdPut();
    } else if ("bye".equals(cmd)) {
        System.out.println(cmd);
        return false;
    }
    return true;
}

/** "put" command processor */
private void processCmdPut() {

    /* Reciever from a peer an object to put into data source */
    OrderInfo orderInfo = (OrderInfo) receiveObject();

    /* Put recieved object into a data source */
    int id = ordersService.put(orderInfo);

    /* Send to peer inserted data id */
    try {
        outputStream.writeInt(id);
        outputStream.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

/**
 * Recieves an object from peer.
 * @return recieved object, or <tt>null</tt> on error.
 */
public Object receiveObject() {
    Object res = null;
    try {
        res = inputObjectStream.readObject();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return res;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM