File transfer using non-blocking sockets - data mysteriously  vanish

Hello,
I need to pass some big amount of data using sockets. I my appliaction I have noticed that sometimes I didn't get all bytes. To check it out I wrote simple client + server to figure out what is happening. So:
- I have a sender and receiver application
- I'm trying to transfer 5MB text file.
- On receiver side, output file is never larget than 3MB
- If I put some timeout on sender side (1ms timeout between write operations) everything works fine.
Could someone tell me what I do wrong? Why data disappears and when? The same file transfered using old sockets goes always fine...
Thanks in advance!
Here is complete source for receiver and sender:
RECEIVER:
import java.io.FileOutputStream;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class ReceiverA {
      * @param args
     public static void main(String[] args) {
          String outputFile = "c:\\outputA.txt", host = "127.0.0.1";          
          int port = 8001, bufferSize = 10240;
          try {
               ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
               Selector selector = Selector.open();
               ServerSocketChannel server = ServerSocketChannel.open();
               server.configureBlocking(false);
               server.socket().bind(new InetSocketAddress(host, port));
               server.register(selector, SelectionKey.OP_ACCEPT);
               System.out.println("Server started");
               while(true)
                    selector.select();
                    Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                    while (iterator.hasNext()) {
                         SelectionKey key = (SelectionKey) iterator.next();
                         iterator.remove();
                         if (key.isAcceptable()) {                              
                              SocketChannel client = server.accept();
                              client.configureBlocking(false);
                              client.register(selector, SelectionKey.OP_READ);                              
                              continue;
                         SocketChannel channel = (SocketChannel) key.channel();
                         int counter = 1;
                         if ( key.isReadable() ) {
                              FileOutputStream os = new FileOutputStream(outputFile);
                              int res;
                              do
                                   buffer.clear();
                                   res = channel.read(buffer);
                                   counter += res;
                                   System.out.println(res);
                                   buffer.flip();
                                   os.write(buffer.array(), 0, buffer.limit());
                              while( res >= 0 );          
                              channel.close();
                              os.close();          
                              System.out.println("Receiver: " + counter);
                              return;
          } catch (Exception e) {
               e.printStackTrace();
}SENDER:
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class SenderA {
     public static void main(String[] args) {
          String inputFile = "c:\\inputA.txt" , host = "127.0.0.1";          
          int port = 8001, bufferSize = 10240;
          try {
               ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
               byte[] byteArr = new byte[buffer.capacity()];
               Selector selector = Selector.open();
               SocketChannel connectionClient = SocketChannel.open();     
               connectionClient.configureBlocking(false);
               connectionClient.connect(new InetSocketAddress(host, port));
               connectionClient.register(selector, SelectionKey.OP_CONNECT);
               while(true) {
                    selector.select();
                    Iterator<SelectionKey> iterator = selector.selectedKeys()
                              .iterator();
                    while (iterator.hasNext()) {
                         SelectionKey key = (SelectionKey) iterator.next();
                         iterator.remove();
                         SocketChannel client = (SocketChannel) key.channel();
                         if (key.isConnectable()) {
                              if (client.isConnectionPending()) {
                                   System.out.println("Trying to finish connection");
                                   try {
                                        client.finishConnect();
                                   } catch (IOException e) {
                                        e.printStackTrace();
                              client.register(selector, SelectionKey.OP_WRITE);
                              continue;
                         if(key.isWritable()) {
                              FileInputStream is = new FileInputStream(inputFile);
                              int res;
                              int counter = 0;
                              do
                                   buffer.clear();
                                   res = is.read(byteArr, 0, byteArr.length);                                   
                                   System.out.println(res);
                                   if ( res == -1 ) break;
                                   counter += res;
                                   buffer.put(byteArr, 0, Math.min(res, buffer.limit()));
                                   buffer.flip();
                                   client.write(buffer);
                                    * When I remove comment file transfer goes OK!
                                   //Thread.sleep(1);
                              while( res != -1 );          
                              client.close();
                              is.close();          
                              System.out.println("Receiver: " + counter);
                              return;
          catch(Exception e) {
               e.printStackTrace();
}

There are at least two problems here.
A. In the receiver you should test for -1 from the read() immediately, rather than continue with the loop and try to write -1 bytes to the file.
B. In the sender you are ignoring the return value of client.write(), which can be anything from 0 to the buffer length. If you get 0 you should wait for another OP_WRITE to trigger; if you get a 'short write' you need to retry it until you've got nothing left to write from the current buffer, before you read any more data. This is where the data is vanishing.

Similar Messages

  • Troubles with timeout using java.nio.channels and non-blocking sockets

    Hello.
    I have a server application that employs java.nio.channels with non-blocking sockets.
    The server waits for connections. The client should connect and be first in sending data.
    Timeouts are significant! If client exceeds the allowed time to send data, the server should break the connection.
    The huge trouble I've discovered that I cannot control the timeout when client connects but remains silent.
    My code looks as follows:
    <pre>
    Selector oSel;
    SocketChannel oSockChan;
    Socket oSock;
    SelectionKey oSelKey;
    Iterator<SelectionKey> oItSelKeys;
    int iCurrState, iMask, iCount;
    iCurrState = INT_SERVER_WORKING;
    iMask = SelectionKey.OP_ACCEPT | SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE;
    while ( iCurrState == INT_SERVER_WORKING )
    try
    *// retrieving next action*
    iCount = oSel.select();
    if ( iCount > 0 )
    oItSelKeys = oSel.selectedKeys().iterator();
    while ( oItSelKeys.hasNext() )
    oSelKey = oItSelKeys.next();
    oItSelKeys.remove();
    if ( oSelKey.isValid() )
    switch ( oSelKey.readyOps() & iMask ) {
    case SelectionKey.OP_ACCEPT :
    oSockChan = oSSockChan.accept();
    oSockChan.configureBlocking(false);
    oSock = oSockChan.socket();
    oSock.setKeepAlive(true);
    oSockChan.register(oSel,SelectionKey.OP_READ,new MyPacket(oSock.getInetAddress(),oSock.getPort()));
    break;
    case SelectionKey.OP_READ :
    oSelKey.interestOps(0);
    ((MyPacket) oSelKey.attachment()).inRequest(); *// preparing request*
    this.getReader().add(oSelKey); *// sending key to reading thread*
    break;
    case SelectionKey.OP_WRITE :
    oSelKey.interestOps(0);
    ((MyRequest) oSelKey.attachment()).inResponse(); *// preparing response*
    this.getWriter().add(oSelKey); *// sending key to writing thread*
    break;
    case SelectionKey.OP_CONNECT :
    default :
    *// nothing to do*
    catch ( IOException oExcept )
    *// do some actions*
    </pre>
    Timeouts are easily controlled by reading and writing threads (see OP_READ and OP_WRITE ).
    But when a client just connects without consequent data send, the state of this connection remains as OP_ACCEPT. The connection remains open for arbitrarily large time and I cannot control it!
    Please help with idea how can I terminate such connections!

    How can I process the keys that weren't selected at the bottom of the loop? Should I use the method keys() ?Yes. Form a new set from keys() and removeAll(selectedKeys()). Do that before you process selectedKeys().
    And the second moment: as I understood a single key may contain several operations simultaneously? Thus I should use several if's (but not if/else 'cause it's the equivalent of switch ... case ).If there is anything unclear about 'your switch statement is invalid. You need an if/else chain' I fail to see what it is. Try reading it again. And if several ifs were really the equivalent of "switch ... case", there wouldn't be a problem in the first place. They're not, and there is.

  • Writing Java Non-Blocking Socket Server for  Winsock Client

    Hi.
    Im a newbie to Sockets. I need to write a Non-Blocking Socket server (using java.nio) that accepts connection and reads the data sent by WinSock clients, and write them to another winsock client. Its quite intriguing. How do I do that? Is it possible?
    Thanks in advance
    Arun

    Well, in traditional 4.2 BSD sockets, you'd fill up a set of filedescriptors of connections (an array of bits usually), and push that in the read parameter of a call to 'select'. Select then blocks until at least one of the file descriptors become available for reading, or writing if you also made an fd_set full of file descriptors (but you can usually write freely to a socket, so there is not much use for that). Then you start finding out which of these file descriptors have actually become available for reading, and you pass those to a bunch of worker-threads. The advantage is that your set of worker-threads can be quite small, while your number of connections can still be quite large (unless, of course, everyone of your clients start talking all at once, but that is no different from the one-socket-one-thread-model that java.net.* forces upon you).
    In java, the 'select' call is replaced by a call to java.nio.channels.Selector.select(); and then the fishing out of the selected stuff comes from java.nio.channels.Selector.selectedKeys().
    To add a thingy to a selector, use (for example) java.nio.channel.ServerSocketChannel.register(Selector, ops, att);
    whereby the ops parameter is the kind of action you'd like to select this channel for; SelectionKey.OP_READ etc..
    The workerthread bit is also easy to write, but I leave that to you as an exercise.

  • Java.io.IOException: Connection timed out while using non-blocking NIO

    Hi,
    I am using non-blocking NIO on jdk 1.6 to transfer files between two processes. The problem is that the sender thread times out on the write call even though it's in non-blocking mode. It doesn't make sense. The receiver on the other end is running fine, and even tries to read from the socket after the sender drops the connection, and throws a Connection reset by peer exception. I should mention that the receiver is sometimes busy doing other stuff, and may be a second or two late in issuing the read call. But if I understand correctly, default TCP timeout is about 2 minutes, so there's no reason why it should timeout in a second or two. I'd appreciate it if anyone has any insight.
    Thanks!

    No I have definitely completed the connection since I it happens a while after the transfer has actually started and part of the file has already been transferred. Oh btw, I should mention that it doesn't always happen. It's intermittent. And it's not a network issue since iperf tests between the two nodes show nothing unusual.

  • Non Blocking Socket ans Session management

    All samples of Non Blocking socket use SelectionKey.attach( Object ob) to attach a partial message if the received data is incomplete. So far so good.
    Are we supposed to use the same approach for session management ( Keeping info on Username, password, timeout values, etc.)
    Thanks

    I disagree with your first statement. The attachment is normally a session object that contains user information, session state, and the ByteBuffer.

  • Easy way to non-blocked sockets

    Use JSSE and NIO for a quick way to implement non-blocking communications
    October 22, 2003
    Although SSL blocking operations -- in which the socket is blocked from access while data is being read from or written to -- provide better I/O-error notification than the non-blocking counterpart, non-blocking operations allow the calling thread to continue. In this article, the author will cover both the client and server side as he describes how to create non-blocking secure connections using the Java Secure Socket Extensions (JSSE) and the Java NIO (new I/O) library, and he will explain the traditional approach to creating a non-blocking socket, as well as an alternative (and necessary) method if you want to use JSSE with NIO.
    http://www-106.ibm.com/developerworks/java/library/j-sslnb.html?ca=dgr-jw03j-sslnb

    MORE IBM SPAM Previous discussion
    I find it interesting spam, but thats a matter of taste. If the OP was truly interested in "trying to get new information out there" he would answer the mulitple questions about NIO and especially NIO mixed with traditional Sockets and NIO vs Secure Sockets. These are all on ALT, NIO is of no interest to New to Java folk.
    Given their budget I think IBM could do a better job of publishing their research.

  • UTL_TCP (blocking or non-blocking sockets mode)

    Hi for All,
    Please, someone knows if the UTL_TCP using blocking or non-blocking sockets mode? I did a search but can not find this information.
    Regards,

    Blocking only occurs when you attempt to read from the socket and there's no data to read. (in which case, the time out setting applies if specified)
    This is however not that robust in my experience. UTL_TCP provides a peek method (returns byte size of socket buffer) that tells you whether or not there is data for that socket. This enables you to verify that you read on that socket will not be a blocking call.
    I prefer using this method, as dealing with a timeout approach results in run-time behaviour issues (either a call waiting too long, or a call timing out too quickly).

  • HT204144 File transfer using Airdrop from iphone to Macbook Pro

    File transfer using airdrop form Macbook Pro to iphone is working...but from iphone to Macbook Pro is not working, Why?

    Hi Brok25;
    Thanks for the question.  The resource below explains the specs and settings that are needed for AirDrop.  Check the settings and look to see if your MacBook Pro is listed.
    Mac Basics: AirDrop lets you send files from your Mac to nearby Macs and iOS devices - Apple Support
    http://support.apple.com/en-us/HT203106
    Sending files to and from an older Mac
    If a Mac you're using with AirDrop was manufactured before 2012, you can send and receive files with other Mac computers.
    On the sending Mac, click "Don't see who you're looking for" in the AirDrop window.
    Select the option to "Search for an Older Mac."
    On the receiving Mac, open a new Finder window and click AirDrop in the sidebar.
    Tips for sending files
    Make sure Wi-Fi and Bluetooth are enabled on your Mac and your iOS device. Although you don't have to connect to a specific network, Wi-Fi needs to be on to send and receive files using AirDrop.
    Move your devices closer together. AirDrop is designed to work within a range of approximately 30 feet (9 meters). If you need to send a file to someone farther away, consider using File Sharing, iCloud, or email instead.
    If you're using a firewall on your Mac, you won't be able to receive AirDrop files if you have enabled "Block all incoming connections" in the Security & Privacy pane of System Preferences.
    Make sure your devices meet system requirements for AirDrop.
    System Requirements
    To see if your Mac works with AirDrop, make sure you’re in the Finder by clicking the desktop (the background area of your screen), or by clicking the Finder icon in the Dock. Then, check to see if AirDrop is listed as an option in the Go menu. If you don't see AirDrop listed, your Mac doesn't support this feature.
    In order to transfer files between a Mac and and an iPhone, iPad or iPod touch
    your iOS device needs to include a lightning connector 
    your iOS device needs iOS 7 or later installed
    your Mac needs to be a 2012 or later model with OS X Yosemite installed
    Your Mac and iOS device both need bluetooth and Wi-Fi turned on. You do not have to be connected to a specific Wi-Fi network. 
    To transfer files between two Mac computers, you need the Mac models listed below with Wi-Fi turned on and OS X Lion or later installed.
    MacBook Pro (Late 2008 or newer)*
    MacBook Air (Late 2010 or newer)
    MacBook (Late 2008 or newer)*
    iMac (Early 2009 or newer)
    Mac Mini (Mid 2010 or newer)
    Mac Pro (Early 2009 with AirPort Extreme card, or Mid 2010)
    *The MacBook Pro (17-Inch Late 2008) and the white MacBook (Late 2008) do not support AirDrop.
    For help identifying your Mac, choose About This Mac from the Apple menu. You can refer to the Apple Support website to find out if your iPhone, iPad or iPod Touch includes a lightning connector. 
    Cheers,
    - Judy

  • Broken Pipe with Non-blocking Socket

    Hello,
    I write a Unix Agent who connect on a Windows Server with socket...
    Working well on Linux but on Solaris my problem is:
    -When my agent is running before server at connection all seems OK: Connect, Select and Getsockopt but when I try to send data I have always EPIPE Signal but I can receive datas from server !
    - When my agent is strarting after the server all it's Ok
    I don't unserstand this appears on Solaris SPARC 8 and Solaris 9 Intel ...
    Please Help is there something special with non-blocking sockets on Solaris ?
    Thanks

    Can't help you much but what I would recommend is that you
    insure that your pipes are opened for both read/write, even
    though you are only going to read or write from it. This insures
    that the pipe does not close down when you hit EOF.

  • Non blocking sockets

    Hi All,
    Anybody have some idea about how to implement non blocking sockets using two threads/Can u help me with some sites where i can get more information in this topic.
    Regards
    Priya

    hi,
    you could have a look at the nonblocking io (nio) api's present in jdk1.4, that should do the trick. this link ought to get u started i suppose..
    http://developer.java.sun.com/developer/technicalArticles/releases/nio/
    hope this helps.
    cheerz
    ynkrish

  • Read Timeout on non-blocking sockets

    Hi,
    I was wondering if there is a way to specify a read timeout (like setSoTimeout for synchronous sockets) when using a non-blocking socket.
    I'd like to have the select() method return is a sockets timeout expires, puting in the selected key set the timedout socket and have it's read operation return -1, something like what happens when a socket is closed by the other side.
    The thing is I need this to be a timeout specific to each socket, thus the select(millis) isn't apropriate.
    Anyone knows of something like this?
    Thanks....

    Yeah, select() is the only thing built in for that, and you have to do the bookkeeping yourself. You would start something like forming the disjunction of the ready keys and the registered keys after each select, to get the unready keys, and then looking at their history to see how long they have been unready via a Map{key,Long(time)).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

  • Detecting When a Non-Blocking Socket Is Closed by the Remote Host

    Hi,
    Using NIO non blocked sockets how do I detect when a Non-Blocking Socket Is Closed by the Remote Host?
    What I have read is:
    The only way to detect that the remote host has closed the connection is to attempt to read or write from the connection. If the remote host properly closed the connection, read() will return -1. If the connection was not terminated normally, read() and write() will throw an exception.
    I have written a server test program using NIO and an applet connecting to the server program via sockets.
    When I after a successful connection shuts down the browser following happens: The code below comes in an endless loop though mySelector.select returns 0 every time. (The selector is registered for OP_READ). size = 1.
    while (true) {
    int n = mySelector.select();
    int size = mySelector.keys().size();
    if (n == 0) continue;
    Is this an expected result?
    How do I get to know what client has lost connection?
    My environment:
    W2000
    java 1.4.1 build 1.4.1_01-b01
    Browser used: IE 5.0
    Many thanks for your help on this matter!
    Regards Magnus Wistr�m

    What you're doing looks OK to me.
    I wonder whether your thread is being interrupted by Thread.intterupt() somewhere. Try putting a Thread.interrupted() before the select call.
    Sylvia.

  • I woke up at 3am to find my MacBook Pro in the middle of a file transfer using AirDrop.

         I woke up at 3am to find my MacBook Pro in the middle of a file transfer using AirDrop. I had not accepted any file transfers via AirDrop as I was asleep so I am a bit confused by all the posts that say that the only way it will work is by the end user accepting a request to transfer files. I am on a home network which has both a soft and hard firewall. I checked my firewall logs and have no signs of intrusion or intrusion attempts. I checked my network map to see see if someone had brute forced my router and was using it but the only assets listed were mine. My router is set up to not be accessable from wireless computers, and is filtered to only allow use by a assets in the MAC Address list. I am an IT by trade but this is my first mac so I am not completely savy in the ways of the ways of macdom. I have found several posts with suggestions on how to turn off and came up with the following terminal command "defaults write com.apple.NetworkBrowser DisableAirDrop -boolean YES". My question is this, how is it possible that my AirDrop was activated and in the middle of a file tranfer if I did not initiate it? I do have a MacMini on my network but its WiFi is turned off so the transfer was not with it. I have read on different posts that you cannot AirDrop if the computer is not on the same network but there were no foreign assets on my network. So my question is this
    1. If AirDrop can not be used with another computer if it is not on the same network, how was it being used?
    2. How can AirDrop be used to xfer files if I did not accept or initate it?
         It seems to be a pretty big security hole to me. Any suggestions or help would be greatly appreciated.
    Ethan

    It could just be a bad disc - I use Verbatim and have only had one fail in a ten-year time period. Try getting a batch of Verbatims and see if you have any problems. I didn't even know that there were Kodak branded discs...
    Clinton

  • File transfer using tcp that  implements in swing

    Can anybody send me the file transfer using tcp that implements in swing codes

    I'm assuming that you're inputing a plain ASCII text SQL file. It's easier to use Readers if you're dealing with plain text, the Output and Input Streams are for Byte input and output. So:
    BufferedReader myReader = new BufferedReader(new FileReader("myFile.sql"));
    BufferedWriter myWriter = new BufferedWriter(new InputStreamWriter(mySocket.getInputStream()));
    String inString;
    while((inString = myReader.readLine()) != null)
    myServerWriter.write(inString);
    myServerWriter.writeLine();
    myServerWriter.flush();
    Then, in the server you can use the same method that I'm using for the Buffered Reader to read in the file, and use a BufferedWriter wraped around a FileWriter to output the text to that file. Bravo.
    -Jason Thomas.

  • Using non blocking connect() call for SCTP sockets in Solaris10

    Hi,
    I have a problem with non blocking connect call on SCTP socket.
    I am using the sctp stack support in Solaris10.
    When the connect is successful, I can get the pollout event on the socket.
    But there is no event observed when the peer does not exist. In other words, I could not get the pollout event on connection failure. This logic works fine with TCP sockets on both Solaris and Suse10.
    I am working with SCTP one-to-one style sockets.
    Is there any way to handle this issue?
    Do I need to load any patch to resolve this issue?
    It will be great if I get a solution in this regard.
    Thanks in advance.
    Best Regards,
    Bipin.

    There are at least two problems here.
    A. In the receiver you should test for -1 from the read() immediately, rather than continue with the loop and try to write -1 bytes to the file.
    B. In the sender you are ignoring the return value of client.write(), which can be anything from 0 to the buffer length. If you get 0 you should wait for another OP_WRITE to trigger; if you get a 'short write' you need to retry it until you've got nothing left to write from the current buffer, before you read any more data. This is where the data is vanishing.

Maybe you are looking for