Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Java
  4. Sending file though socket as byte[]

Sending file though socket as byte[]

Scheduled Pinned Locked Moved Java
sysadmintestingbeta-testing
9 Posts 3 Posters 14 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    JohnCodding
    wrote on last edited by
    #1

    I have a socket though which I'm sending files. If the file is under the buffer size (8192 in my case) then it is fine, but if the file is over that size, then when it writes to file, it writes the first chunk of 8192 bites every time. I'm using ObjectStream because beside the file, I'm sending other objects as well in the actual app, but this is the part of sending the file. Client it sends the file data (testing):

    				System.out.println("Starting client");
    				Socket socket = new Socket("localhost", port);
    				System.out.println("Client sending data");
    				ObjectOutputStream dataOut = new ObjectOutputStream(socket.getOutputStream());
    				BufferedInputStream is = new BufferedInputStream(new FileInputStream(inFile));
    				byte\[\] buffer = new byte\[8192\];
    				int sizeRead = 0;
    				while ((sizeRead = is.read(buffer, 0, 8192)) >= 0) {
    					printByte(buffer, "in"); //Function that writes to a file as strings the byte\[\], and after 8192 you can see it is the first byte\[\] each time, also it writes at the end of file
    					dataOut.writeObject(true);
    					dataOut.writeObject(buffer);
    					dataOut.writeObject(sizeRead);
    					dataOut.flush();
    				}
    				is.close();
    				System.out.println("Done sending file");
    				dataOut.writeObject(false);
    				socket.close();
    				System.out.println("Client closed");
    

    Server that creates the file:

    				System.out.println("Starting server");
    				ServerSocket server = new ServerSocket(port);
    				System.out.println("Server waiting");
    				Socket socket = server.accept();
    				System.out.println("Client connected");
    				ObjectInputStream dataIn = new ObjectInputStream(socket.getInputStream());
    				BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outFile));
    				Object auxKeepReading = dataIn.readObject();
    				if (auxKeepReading instanceof Boolean) {
    					while ((boolean) auxKeepReading) {
    						Object auxBuffer = dataIn.readObject();
    						if (!(auxBuffer instanceof byte\[\])) {
    							System.out.println("Broke byte");
    							break;
    						}
    						Object auxSize = dataIn.readObject();
    						if (!(auxSize instanceof Integer)) {
    							System.out.println("Broke int");
    							break;
    						}
    						printByte((byte\[\]) auxBuffer, "out"); //Same as on client but different file, it writes at the end of file each time
    						bos.write((byte\[\]) auxBuffer, 0, (int) auxSize);
    
    						auxKeepReading = dataIn.readObject();
    						if (!(auxKeepReading instanceof Boole
    
    J 1 Reply Last reply
    0
    • J JohnCodding

      I have a socket though which I'm sending files. If the file is under the buffer size (8192 in my case) then it is fine, but if the file is over that size, then when it writes to file, it writes the first chunk of 8192 bites every time. I'm using ObjectStream because beside the file, I'm sending other objects as well in the actual app, but this is the part of sending the file. Client it sends the file data (testing):

      				System.out.println("Starting client");
      				Socket socket = new Socket("localhost", port);
      				System.out.println("Client sending data");
      				ObjectOutputStream dataOut = new ObjectOutputStream(socket.getOutputStream());
      				BufferedInputStream is = new BufferedInputStream(new FileInputStream(inFile));
      				byte\[\] buffer = new byte\[8192\];
      				int sizeRead = 0;
      				while ((sizeRead = is.read(buffer, 0, 8192)) >= 0) {
      					printByte(buffer, "in"); //Function that writes to a file as strings the byte\[\], and after 8192 you can see it is the first byte\[\] each time, also it writes at the end of file
      					dataOut.writeObject(true);
      					dataOut.writeObject(buffer);
      					dataOut.writeObject(sizeRead);
      					dataOut.flush();
      				}
      				is.close();
      				System.out.println("Done sending file");
      				dataOut.writeObject(false);
      				socket.close();
      				System.out.println("Client closed");
      

      Server that creates the file:

      				System.out.println("Starting server");
      				ServerSocket server = new ServerSocket(port);
      				System.out.println("Server waiting");
      				Socket socket = server.accept();
      				System.out.println("Client connected");
      				ObjectInputStream dataIn = new ObjectInputStream(socket.getInputStream());
      				BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outFile));
      				Object auxKeepReading = dataIn.readObject();
      				if (auxKeepReading instanceof Boolean) {
      					while ((boolean) auxKeepReading) {
      						Object auxBuffer = dataIn.readObject();
      						if (!(auxBuffer instanceof byte\[\])) {
      							System.out.println("Broke byte");
      							break;
      						}
      						Object auxSize = dataIn.readObject();
      						if (!(auxSize instanceof Integer)) {
      							System.out.println("Broke int");
      							break;
      						}
      						printByte((byte\[\]) auxBuffer, "out"); //Same as on client but different file, it writes at the end of file each time
      						bos.write((byte\[\]) auxBuffer, 0, (int) auxSize);
      
      						auxKeepReading = dataIn.readObject();
      						if (!(auxKeepReading instanceof Boole
      
      J Offline
      J Offline
      JohnCodding
      wrote on last edited by
      #2

      On client side after sending the size that it read, I added buffer = new byte[8192]; and now I don't have the problem and it is sending new data but there are 2 problems: 1. I don't know if this is what you should do; 2. The speed is limited to 3 MB/s when using IP instead of localhost, on an internet connection of 1.000 Mbps (~125 MB/s) upload/download (they are the same). I tried to increase the buffer size but still the same speed.

      L J 2 Replies Last reply
      0
      • J JohnCodding

        On client side after sending the size that it read, I added buffer = new byte[8192]; and now I don't have the problem and it is sending new data but there are 2 problems: 1. I don't know if this is what you should do; 2. The speed is limited to 3 MB/s when using IP instead of localhost, on an internet connection of 1.000 Mbps (~125 MB/s) upload/download (they are the same). I tried to increase the buffer size but still the same speed.

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #3

        I was looking at this code earlier and wondered why you sent the buffer size after the data. It makes much more sense to send the size first. Also there is no point in sending 8192 bytes if you have only read one byte from the input file. So only send the amount of data that has been read. Tuning TCP performance is not an exact science unfortunately, but you can find plenty of discussions of the subject on the internet.

        J 1 Reply Last reply
        0
        • L Lost User

          I was looking at this code earlier and wondered why you sent the buffer size after the data. It makes much more sense to send the size first. Also there is no point in sending 8192 bytes if you have only read one byte from the input file. So only send the amount of data that has been read. Tuning TCP performance is not an exact science unfortunately, but you can find plenty of discussions of the subject on the internet.

          J Offline
          J Offline
          JohnCodding
          wrote on last edited by
          #4

          Richard MacCutchan wrote:

          I was looking at this code earlier and wondered why you sent the buffer size after the data. It makes much more sense to send the size first.

          Because when they are used it doesn't matter the order they were sent, I didn't even think about that.

          Richard MacCutchan wrote:

          Also there is no point in sending 8192 bytes if you have only read one byte from the input file. So only send the amount of data that has been read.

          I changed that now on client: dataOut.writeObject(Arrays.copyOf(buffer, sizeRead)); What about buffer = new byte[8192]; I added, is that how it should be done to send now data each time?

          					dataOut.writeObject(true);
          					dataOut.writeObject(sizeRead);
          					dataOut.writeObject(Arrays.copyOf(buffer, sizeRead));
          					dataOut.flush();
          					buffer = new byte\[8192\];
          

          Richard MacCutchan wrote:

          Tuning TCP performance is not an exact science unfortunately, but you can find plenty of discussions of the subject on the internet.

          From what I've seen they suggest two things most of the time: 1. Setting socket.setTcpNoDelay(true);. I tried that on both client and server bust still no use; 2. Using BufferedOutputStream/BufferedInputStream inside ObjectOutputStream/ObjectInputStream, but still the same 3 MB/s. Even after combining 1. and 2.

          L 1 Reply Last reply
          0
          • J JohnCodding

            Richard MacCutchan wrote:

            I was looking at this code earlier and wondered why you sent the buffer size after the data. It makes much more sense to send the size first.

            Because when they are used it doesn't matter the order they were sent, I didn't even think about that.

            Richard MacCutchan wrote:

            Also there is no point in sending 8192 bytes if you have only read one byte from the input file. So only send the amount of data that has been read.

            I changed that now on client: dataOut.writeObject(Arrays.copyOf(buffer, sizeRead)); What about buffer = new byte[8192]; I added, is that how it should be done to send now data each time?

            					dataOut.writeObject(true);
            					dataOut.writeObject(sizeRead);
            					dataOut.writeObject(Arrays.copyOf(buffer, sizeRead));
            					dataOut.flush();
            					buffer = new byte\[8192\];
            

            Richard MacCutchan wrote:

            Tuning TCP performance is not an exact science unfortunately, but you can find plenty of discussions of the subject on the internet.

            From what I've seen they suggest two things most of the time: 1. Setting socket.setTcpNoDelay(true);. I tried that on both client and server bust still no use; 2. Using BufferedOutputStream/BufferedInputStream inside ObjectOutputStream/ObjectInputStream, but still the same 3 MB/s. Even after combining 1. and 2.

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #5

            JohnCodding wrote:

            What about buffer = new byte[8192]; I added, is that how it should be done to send now data each time?

            Yes, that is fine, as you allocate the buffer before you start the read/write loop. So each read from the input file will refill the same buffer. But I would be tempted to use ObjectOutputStream write(byte[](Java Platform SE 7 )[^], rather than writeObject, to send the byte data. I have never had to do any TCP tuning so can't offer any useful suggestions, sorry.

            J 1 Reply Last reply
            0
            • L Lost User

              JohnCodding wrote:

              What about buffer = new byte[8192]; I added, is that how it should be done to send now data each time?

              Yes, that is fine, as you allocate the buffer before you start the read/write loop. So each read from the input file will refill the same buffer. But I would be tempted to use ObjectOutputStream write(byte[](Java Platform SE 7 )[^], rather than writeObject, to send the byte data. I have never had to do any TCP tuning so can't offer any useful suggestions, sorry.

              J Offline
              J Offline
              JohnCodding
              wrote on last edited by
              #6

              Richard MacCutchan wrote:

              But I would be tempted to use ObjectOutputStream write(byte[](Java Platform SE 7 )[^], rather than writeObject, to send the byte data.

              In the past when I used socket but not for files, I had some problems when I was using combination of ObjectOutputStream writeBoolean(), writeInt(), writeUTF(), writeObject(), the order was correct when writing/reading but I was still getting some exceptions, and when I switch to only writeObject() I didn't had any problems. And with objects I have more control over what the server gets from the client when the data is wrong, and shadow ban the IP if it keeps sending the wrong data based on some checks. As java class files can easily be decompiled, they can recreate the code and send part of the data good then wrong one just to be jerks or for phishing data. I have some checks on the server to know when someone clearly wasn't supposed to send data, and ignore it, and it did help.

              Richard MacCutchan wrote:

              I have never had to do any TCP tuning so can't offer any useful suggestions, sorry.

              Yeah, until now I didn't had problems, but now with files, also some that can be big, I do care about speed a lot. I'll keep looking and maybe I find a way to remove the limit. As there is clearly a limit because the speed stays around 3 MB/s and I did see someone complaining about the same exact speed, but there wasn't a solution on that thread.

              1 Reply Last reply
              0
              • J JohnCodding

                On client side after sending the size that it read, I added buffer = new byte[8192]; and now I don't have the problem and it is sending new data but there are 2 problems: 1. I don't know if this is what you should do; 2. The speed is limited to 3 MB/s when using IP instead of localhost, on an internet connection of 1.000 Mbps (~125 MB/s) upload/download (they are the same). I tried to increase the buffer size but still the same speed.

                J Offline
                J Offline
                jschell
                wrote on last edited by
                #7

                JohnCodding wrote:

                The speed is limited to 3 MB/s when using IP instead of localhost, on an internet connection of 1.000 Mbps

                Not quite sure what you are saying there but... Yes localhost and the actual network are different. So a speed difference is expected. Matter of fact if it was the same I would expect (most likely) a problem with the actual measurement or that there was a hardware/software throttle happening in the client.

                JohnCodding wrote:

                internet connection ... upload/download (they are the same).

                Noting also that I would not expect that. Even for a business. But I do want to emphasize that there is a difference between 'network' and 'internet'.

                J 1 Reply Last reply
                0
                • J jschell

                  JohnCodding wrote:

                  The speed is limited to 3 MB/s when using IP instead of localhost, on an internet connection of 1.000 Mbps

                  Not quite sure what you are saying there but... Yes localhost and the actual network are different. So a speed difference is expected. Matter of fact if it was the same I would expect (most likely) a problem with the actual measurement or that there was a hardware/software throttle happening in the client.

                  JohnCodding wrote:

                  internet connection ... upload/download (they are the same).

                  Noting also that I would not expect that. Even for a business. But I do want to emphasize that there is a difference between 'network' and 'internet'.

                  J Offline
                  J Offline
                  JohnCodding
                  wrote on last edited by
                  #8

                  jschell wrote:

                  Noting also that I would not expect that. Even for a business.

                  SpeedTest[^]

                  jschell wrote:

                  Not quite sure what you are saying there but...

                  When transferring files over internet using the code I posted for sending/receiving, the transfer speed is always limited to 3 MB/s (bounces around 3 MB/s, it goes over or under with 100-200 KB/s) instead of the actual capabilities of internet speed and hardware (SSD). If localhost is used, then the transfer is not limited to 3 MB/s.

                  J 1 Reply Last reply
                  0
                  • J JohnCodding

                    jschell wrote:

                    Noting also that I would not expect that. Even for a business.

                    SpeedTest[^]

                    jschell wrote:

                    Not quite sure what you are saying there but...

                    When transferring files over internet using the code I posted for sending/receiving, the transfer speed is always limited to 3 MB/s (bounces around 3 MB/s, it goes over or under with 100-200 KB/s) instead of the actual capabilities of internet speed and hardware (SSD). If localhost is used, then the transfer is not limited to 3 MB/s.

                    J Offline
                    J Offline
                    jschell
                    wrote on last edited by
                    #9

                    JohnCodding wrote:

                    If localhost is used, then the transfer is not limited to 3 MB/s.

                    I meant that 'localhost' and 'network' should not have the same speed. A connection, any connection, goes through actual hardware. So your speedtest is connecting to a computer somewhere. You client test app is connecting to a different computer somewhere. So something is throttling it. Best way is to test your app with another app that you control. You need two boxes. They can be local but you could also spin on a cloud box. Probably ideal on the cloud (internet connected.) If that test shows a speed limitation then it is your apps problem (with I doubt.) If not then it indicates that something at the other end is probably throttling it. Also possible that your service provider is throttling it. They are 'faking' the results with speedtest by explicitly looking for it. Or you might be hitting a data limit with your app that the document (or don't.)

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups