Archived

This forum has been archived. Please start a new discussion on GitHub.

java.net.SocketException: Broken pipe

Hello,
Basically, I made three java classes as you can see below.

1. Ice Client (extends Ice.Application)
2. Ice Server (extends Ice.Application)
- This class uses below MySocketI (Ice.Object object = new MySocketI();)
3. MySocketI (extends _MySocketDisp)
- start method
- send byte data method
- stop method

In MySocketI class, there is a socket class sending the byte data to some server.
But I met an error like below.

java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:132)
at java.io.DataOutputStream.writeByte(DataOutputStream.java:153)
...

Actually, I made the main method in MySocketI class and it works fine.
If I use MySocketI through Ice Client, then it doesn't work.
I think that there is broken socket connection between MySocketI and SocketServer because of some logic from ice grid behavior.

Any help would be appreciated.

Thanks in advance.
Kane

Comments

  • benoit
    benoit Rennes, France
    Hi,

    If I understand it correctly, the MySocketI servant uses Java sockets to send data to a server directly (without using Ice). Ice shouldn't affect socket connections form your servant. I'm afraid it's hard to say what could be the problem without more information, can you perhaps post a small self-contained example demonstrating the problem?

    This exception typically occurs if the receiver forcefully closes the connection while the sender is writing data.

    Cheers,
    Benoit.
  • Sorry for my insufficient explanation.
    Communication between modules is like below.

    IceClient --(using IceGrid)--> IceServer --> MySocketI --> SocketServer

    If I use IceClient sending the binary data to SocketServer via MySocketI, "Broken pip" error is occured. However, if I use MySocketI class directly to send the binary data through main function, then it's perfectly working fine.

    Here is an small pseudo sample code that I made briefly.

    1. IceClient

    public class Client extends Application {
    public int run(String[] args) {
    int status = 0;
    Ice.Communicator _communicator = null;
    _communicator = Ice.Util.initialize(args);
    IceGrid.RegistryPrx registry = IceGrid.RegistryPrxHelper.checkedCast(_communicator.stringToProxy("IceGrid/Registry"));

    IceGrid.SessionPrx session = null;
    session = registry.createSession("foo", "bar");

    MySocketPrx mysoc = null;

    ObjectPrx prx = session.allocateObjectByType("::Demo::MySocket-type");
    mysoc = MySocketPrxHelper.checkedCast(prx);

    String file = "somedata.dat";
    BufferedReader br = new BufferedReader(new FileReader(audioList));
    FileInputStream audio = new FileInputStream(file);

    mysoc.start();

    byte[] buf = new byte[256];
    while (file.available() != 0) {
    file.read(buf);
    mysoc.sendData(buf); // error occurs this step in the server side !!!
    }

    mysoc.stop();
    return status;
    }

    public static void main(String[] args) {
    IceClient app = new IceClient();
    int status = app.run(args);
    }
    }

    2. IceServer
    public class IceServer extends Application {
    public int run(String[] args) {
    int status = 0;
    Ice.Communicator ic = null;
    Ice.ObjectAdapter adapter = null;
    ic = Ice.Util.initialize(args);
    Properties properties = ic.getProperties();
    adapter = ic.createObjectAdapter("MySocketAdapter");

    Ice.Object object = new MySocketI();

    Identity id = ic.stringToIdentity(properties.getProperty("Identity"));
    adapter.add(object, id);
    adapter.activate();
    ic.waitForShutdown();
    return status;
    }
    public static void main(String[] args) {
    IceServer proxy = new IceServer();
    int status = proxy.run(args);
    }
    }

    3. MySocketI
    public class MySocketI extends _MySocketDisp {
    Socket mySocket = null;
    Socket DataInputStream myIn = null;
    Socket DataOutputStream myOut = null;

    public void start(Current __current) {
    mySocket = new Socket("111.11.11.11", 1234);
    myIn = new DataInputStream(mySocket.getInputStream());
    myOut = new DataOutptStream(mySocket.getOutputStream());
    }

    public void sendData(byte[] data, Current __current) {
    myOut.write(data, 0, data.length);
    myOut.flush();
    }

    public void stop(Current __current) {
    ...
    }

    public static void main(String args[]) throws IOException {
    // main
    }
    }

    4. SocketServer
    SocketServer is somewhere...
  • kanisuka wrote: »
    If I use IceClient sending the binary data to SocketServer via MySocketI, "Broken pip" error is occured.

    A "Broken pipe" error occurred in SocketI class.
  • benoit
    benoit Rennes, France
    Hi,

    The only explanation I have so far is that 2 clients end-up using the same MySocketI servant to send data. This could possibly cause some bad things if one client decides to call stop() while the other is sending data. Could you add some tracing to your code to see if this could be the cause?

    Note that the IceGrid allocation mechanism to allocate the object to your client is a "cooperative" allocation system: you have to play by the rules if you want to ensure no other clients "steals" the object. There's one thing which is missing in your client and which could cause the object to be re-used by another client: the session keep alive mechanism.

    If the session of your client expires, IceGrid will allocate the object to another client. You need to add a session keep alive thread to maintain the session alive until the client exits or decides it no longer needs the session. See the C++ demo/IceGrid/allocate client code for an example (for a Java example, you could also check and adapt the keep alive thread from demo/Ice/session/Client.java).

    Cheers,
    Benoit.