Hot questions for Using Transmission Control Protocol in serialization

Question:

since im spliting the string to the client menu, my programs turns to bug because the swicth doesnt do anything on the client and since it doesnt do anything it doesnt start any method, and thats why when server gets the output and start the download file, when it starts writing the client doesnt acept it, because his menu didnt started the receive function, any tip to make the switch and the server work and synchronized methods? client realices send file while server does upload, and client realices receivefile when server does download all cuz of the input to the cli

this is my conexion Server

package eagz.org;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class ConexionServer1 extends Thread{
private static ServerSocket ss;
private static Socket s = null;
public static String path = "C:\\Users\\Eduardo\\Desktop\\Eduardo\\Uru\\Clases Programacion\\POO\\CLI\\server\\";
static Scanner input = new Scanner (System.in);
private static BufferedReader in = null;

    ConexionServer1(Socket s){
        this.s = s; }

    public void run(){
        try{
            menu(); } //line 33
        finally{
                try {
                    s.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }   } }



    public static void menu() {
        try {
            while(true){
            ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream()); // line 47
            ObjectInputStream ois = new ObjectInputStream(s.getInputStream()); 
            String msg = (String)ois.readObject();
            System.out.println(msg);
            String[] cmds = msg.split(" ");
        /*  in = new BufferedReader(new InputStreamReader(
                    s.getInputStream()));
            String clientSelection = in.readLine();
            String[] cmds = clientSelection.split(" ");
            String[] cmds = clientSelection.split("");*/    
            switch(cmds[0]){
            case "create":  ;
            File f = new File(cmds[1]);
                if(!f.exists()){
                    create(cmds[1]);
                    oos.writeObject(">> File Created"); }
                else{
                    create(cmds[1]);
                    oos.writeObject(">> File not created"); }
                break;

            case "delete":
                File f1 = new File(cmds[1]);
                    delete(cmds[1]);
                    if(!f1.exists()){
                        oos.writeObject(" File Deleted ");  }   
                    else{
                        oos.writeObject(" File not found"); }
                break;

            case "download":
                download(cmds[1]);
                oos.writeObject("Sucess");
                break;

            case "upload":
                upload(cmds[1]);
                oos.writeObject("Sucessfull");
                break;

            default:
                System.out.println("Undefined Operation");
                oos.writeObject("Undefined Operation");
                break;
            }//case
        oos.close();
        ois.close();
            }}
         catch (IOException | ClassNotFoundException e) {       e.printStackTrace();    }
    }


    public static void create (String filename){
        File f = new File(path + filename);
        try{if(!f.exists()){
            f.createNewFile();
            System.out.println(">> File Created");              
        }
        else {
            System.err.println(">> File Already Exists");   }
        } 
        catch(Exception e){e.printStackTrace();}
    }//create


    public static void delete (String filename){
        File f = new File(path + filename);
        try{if(f.exists()){
            f.delete();
            System.out.println(">>File Deleted");   }
        else{
            System.err.println(">>Error, File doesnt exist's"); }
        }
        catch(Exception e){e.printStackTrace();}
    }

    public static void upload (String filename){
        File f = new File(path + filename);
        try{
            DataInputStream clientData = new DataInputStream(s.getInputStream());
        //    String fileName = clientData.readUTF();
            OutputStream os = new FileOutputStream(("received from client -> " + f));
            long size = clientData.readLong();
            byte[] buffer = new byte[1024];
            int i = clientData.read(buffer,0,(int) size);
                while(size > 0 && (i) > 0){
                    os.write(buffer, 0, i);
                    size -= i;
                }
            os.flush();
            clientData.close();

     System.out.println("File "+filename+" received from client.");
    }       catch (IOException ex) {
        System.err.println("Client error. Connection closed.");}
}



    public static void download (String filename){
         try {
               File myFile = new File(path + filename);
               byte[] mybytearray = new byte[(int) myFile.length()];
               FileInputStream fis = new FileInputStream(myFile);
               BufferedInputStream bis = new BufferedInputStream(fis);
               DataInputStream dis = new DataInputStream(bis);
               dis.readFully(mybytearray, 0, mybytearray.length);
               OutputStream os = s.getOutputStream();
               DataOutputStream dos = new DataOutputStream(os);
               dos.writeUTF(myFile.getName());
               dos.writeLong(mybytearray.length);
               dos.write(mybytearray, 0, mybytearray.length);
               dos.flush();
               System.out.println("File "+ filename +" sent to client.");
           } catch (Exception e) {
               System.err.println("File does not exist!");
           }    
    }
}

this is my client class

package eagz.org;


public class Cliente {
public static String path = "C:\\Users\\Eduardo\\Desktop\\Eduardo\\Uru\\Clases Programacion\\POO\\CLI\\cliente";
private static Socket s;
private static String fileName;
private static BufferedReader stdin;
private static PrintStream os;
static int PORT = 9000;
static String IP = "localhost"; //use your ip
static Scanner input = new Scanner (System.in);

public static void main(String[] args) throws IOException {
    try {
        s = new Socket(IP ,PORT);
        stdin = new BufferedReader(new InputStreamReader(System.in));

        System.err.println("-- Client  --");
        System.out.println("Connecting to Server ->" +  IP  + "/" + PORT);
        System.out.println("Commands: "+" -> Create "+" -> Delete "+" -> Download "+" -> Upload");
        System.out.println("C:>");

        String inp = input.nextLine();
        String [] cmds = inp.split("");

        ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
        oos.writeObject(inp);

        ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
    //  System.out.println("From Server : " + servermsg);

            switch (cmds[0]) {
                    case "upload":
           //  os.println(cmds);
                        //oos.writeObject(inp);
                        sendFile(cmds[1]);

                        break;
                    case "download":
                        //System.err.print("Enter file name: ");
                        fileName = cmds[1];
                        oos.writeObject(cmds[0] + fileName);
                        receiveFile(fileName);
                        break;
                }   
            //String servermsg = (String) ois.readObject();
            System.out.println("From Server : " );
        } catch (Exception e) { 
            e.printStackTrace();
    }
}


public synchronized  static void sendFile(String fileName) {
    try {
        File myFile = new File(path + fileName);
        byte[] mybytearray = new byte[(int) myFile.length()];
        FileInputStream fis = new FileInputStream(myFile);
        BufferedInputStream bis = new BufferedInputStream(fis);
        DataInputStream dis = new DataInputStream(bis);
        dis.readFully(mybytearray, 0, mybytearray.length);
        OutputStream os = s.getOutputStream();
        DataOutputStream dos = new DataOutputStream(os);
        dos.writeUTF(myFile.getName());
        dos.writeLong(mybytearray.length);
        dos.write(mybytearray, 0, mybytearray.length);
        dos.flush();
        System.out.println("File "+fileName+" sent to Server.");
    } catch (Exception e) {
        System.err.println("File does not exist!");
    }
}

public synchronized static void receiveFile(String fileName) {
    try {
        File f = new File(path + fileName);
        InputStream is = s.getInputStream();
        DataInputStream clientData = new DataInputStream(is);
        fileName = clientData.readUTF();
        OutputStream os = new FileOutputStream(("received from server -> " + f));
        long size = clientData.readLong();
        byte[] buffer = new byte[1024];

        int i = clientData.read(buffer,0,(int) size);
            while (size > 0 && (i) != -1) {
                os.write(buffer, 0, i);
                size -= i;
            }
        os.close();
        clientData.close();
        System.out.println("File "+fileName+" received from Server.");
    } catch (Exception e) {   
        e.printStackTrace();
    }
}
}

and this is my server

package eagz.org;


public class Server extends Thread {
public static final int PORT = 9000;
public static ServerSocket ss = null; 
public static Socket s = null;

public static void main(String[] args) {
    try {
        ss = new ServerSocket(PORT);
        System.err.println("- -  Server - -");
        while(true){
            s = ss.accept();
            System.out.println("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
            System.out.println("NEW CONNECTION WORKING ON ADDRESS -> " + s.getInetAddress().getHostName());
            Thread conect = new ConexionServer1(s);
            conect.start();
        }
    } catch (IOException e) {   
        System.err.println("Port already in use.");
        e.printStackTrace();}

    finally{
        try {
            s.close();
            ss.close();
        } catch (Exception e) { e.printStackTrace();    }
    }
}
}

and this is my error

NEW CONNECTION WORKING ON ADDRESS -> Eduardo
download cesar.txt
java.net.SocketException: Socket is closed
File cesar.txt sent to client.
at java.net.Socket.getOutputStream(Socket.java:943)
at eagz.org.ConexionServer1.menu(ConexionServer1.java:47)
at eagz.org.ConexionServer1.run(ConexionServer1.java:33)

Answer:

Closing the input or output stream of a socket closes the other stream and the socket, and you are doing this at several points.

However there are numerous other problems with this code.

  1. You describe it as an FTP server but you are using Java Serialization, which is a different protocol. It is not an FTP server.
  2. You are creating new object streams every time you go to read the next message, instead of retaining them for the life of the socket. This will cause this problem or one like it.
  3. You are mixing ObjectInputStream and DataInputStream on the same socket. This will not work.
  4. You are ignoring the boolean returned by File.delete(), and you are catching a non-existent Exception that cannot be thrown, short of an NPE or other programming bug, in the same method.
  5. You are catching, logging, and otherwise ignoring exceptions when they should be reported to the peer.
  6. You are assuming that a file size fits into an int.
  7. You are assuming that a file to be downloaded fits into memory, and needlessly doing so when you could just as well copy a small buffer at a time, say 8192 bytes.
  8. Your receiveFile() method can over-run the received data. For a correct way to transfer multiple files, or even one file while keeping the connection open, see this answer.

Question:

I am trying to send object over TCP thanks to serialization in client-server application. TCP client is written on android system and I use ObjectOutputStream to send an object. TCP server is written with spring integration and I try to read this object using deserializer. Something like this:

<int-ip:tcp-connection-factory id="hosServer"
    serializer="connectionSerializeDeserialize"
    deserializer="connectionSerializeDeserialize" ..... >

In class which implements Serializer and Deserializer interfaces I am createing ObjectInputStream from InputSream which is the argument in deserializer method. Its working fine to the moment where I try to connect one more time to the server. Then I receive EOFException during reading object form ObjectInputStream by readObject() method.

public class CommandConverter implements Serializer<Command>, Deserializer<Command>{

    private ObjectInputStream ois = null;
    private ObjectOutputStream oos = null;
    private CommandBuilder commandBuilder = new CommandBuilder();

    public Command deserialize(InputStream inputStream) throws IOException {
        if (ois == null)
            ois = new ObjectInputStream(inputStream);
        Command cmd = null;
        try {
            cmd = (Command) ois.readObject();
        } catch (ClassNotFoundException e) {
            commandBuilder.setCommandBuilder(new ImproperCommandBuilder());
            commandBuilder.createCommand();
            cmd = commandBuilder.getCommand();
        } catch (InvalidClassException e) {
            commandBuilder.setCommandBuilder(new ImproperCommandBuilder());
            commandBuilder.createCommand();
            cmd = commandBuilder.getCommand();
        }
        return cmd;
    }

What is the best way to get object sending over TCP in spring integration?


Answer:

The Serializer and Deserializer implementations must be thread-safe. The simplest way to reach that is to make the implementation stateless.

Since you have those properties in your class, they become shared between different calls. And having such a state it makes the behavior unpredictable.

The ObjectInputStream and ObjectOutputStream are not designed for sharing state.

So, you have to create ObjectInputStream all the time the deserialize() is called:

ObjectInputStream ois = new ObjectInputStream(inputStream);

and so on.

Question:

i'm trying to send an object from c# to java over a TCP connection but it does not work. Java tell me there is an error and i don't know why

java.io.StreamCorruptedException: invalid stream header: 3C3F786D
    at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
    at java.io.ObjectInputStream.<init>(Unknown Source)
    at ClientThread.run(ClientThread.java:34)
    at java.lang.Thread.run(Unknown Source)

I googled it already but found no precise answer for my problem. I have serialized my c# class with and xml serializer. I've found the code on the internet.

Here is the c# code

        var cmd = new Command();
        cmd.setType(5);

        var xmlSerializer = new XmlSerializer(typeof(Command));

        using (var memoryStream = new MemoryStream())
        {
            xmlSerializer.Serialize(memoryStream, cmd);
        }

        String sendMsg = message + ";";
        try
        {
            if (tcp_stream.CanWrite)
            {
                xmlSerializer.Serialize(tcp_stream, cmd);
            }
            tcp_stream.Flush();
        }
        catch (Exception exception)
        {
            MessageBox.Show("Error..... " + exception);
        }

And the Java server code is

try {

    ObjectOutputStream sOutput = new ObjectOutputStream(socket.getOutputStream());
    ObjectInputStream sInput = new ObjectInputStream(
    socket.getInputStream());
    this.message = (Message) sInput.readObject();
    System.out.println("MessageType: " + this.message.getType());
}
catch (IOException e) {
    System.out.println("Can not get message. " + e.getMessage());
    e.printStackTrace();
    break;
}
catch (ClassNotFoundException e) {
    e.printStackTrace();
}

Thanks for any answers. Any help is appreciated.


Answer:

Java binary serialization and .NET XML serialization are not compatible with each other. Java binary serialization is compatible with itself and that is pretty much it. You need to pick a common format which can be serialized and deserialized by both. Some examples might include some flavor of XML or JSON or BSON, Google Protobuf, etc.

Question:

inStream = new ObjectInputStream(this.socket.getInputStream());
Packet rank = (Packet)inStream.readObject();

Hi, I supposed to receive an array from two clients. I can only receive from a client and prompt an error like this : Thanks in advance

 java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:209)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2338)
    at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2351)
    at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2822)
    at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:804)
    at java.io.ObjectInputStream.<init>(ObjectInputStream.java:301)
    at ServerGraph$Handler.run(ServerGraph.java:350)

Answer:

I supposed to receive an array from two clients. I can only receive from a client and prompt an error like this

 java.net.SocketException: Connection reset

I think you may be misunderstanding how sockets work. A socket represents a connection between one client and one server. You seem to be saying that that you are expecting to get data from 2 different clients on a single Socket. That is not possible. It doesn't make sense. You need a separate Socket for each client that your server is communicating with.

What you are seeing (the Connection reset) is explicable: the peer (i.e. the client or client's OS), has reset the connection for some reason. The Java (?) client application might called close() or shutdownOutput(), or it might have just exited.

(You haven't shown us enough code to suggest the best way to fix your problem. Are the sockets being opened by the clients or the server?)