Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sending multiple byte array over the socket

Tags:

java

I want to send multiple byte array from the client and server ?

I was able to send/Receive one byte array from client and send / Receive one byte array from server :

My code is like this :

server :

 Socket sock=null;
  ByteArrayOutputStream input=null;
  OutputStream out=null;
    InputStream in=null;
  try{
      ServerSocket server_sock=new ServerSocket(2972);


    sock=server_sock.accept(); 

   in = 
       sock.getInputStream();
    out=sock.getOutputStream();
    }catch(IOException e){
      System.out.println(e.getMessage());
  }
 String word="";

  //1-Receive

  try{

    ByteArrayOutputStream serverinput=new ByteArrayOutputStream();
 int len=0;
byte[] buf=new byte[1000];
        while ((len = in.read(buf))>=0) {
              serverinput.write(buf, 0, len);

        }

      sock.shutdownInput();

        word=new String(serverinput.toByteArray());
    System.out.println("Client send 1"+word);

    }catch(Exception e){
      System.out.println(e.getMessage());
  }


   String st="Server is a king";
try{ 
   out.write(st.getBytes());

   out.flush();

}catch(Exception e){
      System.out.println(e.getMessage());
  }

client :

 Socket sock=null;
    OutputStream out=null;
    InputStream in=null;


  try{
      sock=new Socket("127.0.0.1",2972);
      }catch(IOException e){
      System.out.println(e.getMessage());
  }


String word="Hellow World"  ;
    try{
    in = 
       sock.getInputStream();
    out=sock.getOutputStream();
    }catch(IOException e){
      System.out.println(e.getMessage());
  }

//1- send
   try{

       System.out.println("Your string is"+word+"converted to byte"+word.getBytes());

    out.write(word.getBytes());
    out.flush();
 sock.shutdownOutput();
    }catch(Exception e){
      System.out.println(e.getMessage());
  }

    try{  ByteArrayOutputStream serverinput=new ByteArrayOutputStream();
 int len=0;
byte[] buf=new byte[1000];
        while ((len = in.read(buf))>=0) {
              serverinput.write(buf, 0, len);


        }
    System.out.println("server send 1 "+new String(serverinput.toByteArray()));
     System.out.println("Your string is"+word+"converted to byte"+word.getBytes());

    }catch(Exception e){
      System.out.println(e.getMessage());
  }

This code is working fine for one submitting from client and server but it does not work when I want to send / receive more byte array ?

It is working only when I use shutdown because both client and server reading and writing to the data.

Therefore, I can not use the socket channel again ... is there is alternative solution? ...that does not lead to deadlock.

like image 233
Programming_Lover Avatar asked Apr 29 '11 02:04

Programming_Lover


1 Answers

The problem you have is that you don't currently have any way to say when one byte array ends and the next one starts. (In your "one array" solution, the end of the byte array corresponds to the end of stream. And of course, once the stream has been ended / closed, it cannot be reopened without creating a new Socket, etcetera.)

The simple way to solve this is as follows, using DataOutputStream and DataInputStream pairs wrapped around the respective socket streams:

  • To send a byte array:

    1. Convert data to bytes.

    2. Send the byte array size using the DataOutputStream.writeInt(int) method.

    3. Send the byte array using DataOutputStream.write(byte[]) method.

  • To receive a byte array:

    1. Receive the byte array size using the DataInputStream.readInt() method.

    2. Allocate a byte array of the required size.

    3. Receive the bytes into the byte array using the DataInputStream.read(byte[], int, int) method ... repeatedly until you've gotten all of the bytes.

By sending the size of the byte array at the front, you tell the receiver how many bytes to read. You can repeat this process as many times as you need. The sender can indicate to the receiver that there are no more byte arrays to send by simply closing the socket stream.

Note - this is pseudo-code. I assume that you are capable of turning it into working Java.

Don't forget to insert BufferedInputStreams and BufferedOutputStreams into the respective stream chains ... to reduce system call overheads.

like image 130
Stephen C Avatar answered Nov 15 '22 06:11

Stephen C