# Channels.write() bleibt hängen



## mikachu (21. Jul 2009)

Hi Community, hi Experten,

ich hab da ein kleines Problem, was mich schon mehrere Tage nicht mehr ruhig schlafen lässt ;-).

Immer wenn über einen Socket, den ich von einem ServerSocketChannel.open().socket() erhalten habe, etwas senden will, bleibt mir mein Server bei dem zweiten Senden hängen.

at sun.nio.ch.SocketDispatcher.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:33)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:104)
at sun.nio.ch.IOUtil.write(IOUtil.java:75)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:334)
at java.nio.channels.Channels.write(Channels.java:60)
at java.nio.channels.Channels.access$000(Channels.java:47)
at java.nio.channels.Channels$1.write(Channels.java:134)
at org.dcm4che2.net.PDUEncoder.writePDU(PDUEncoder.java:186)
at org.dcm4che2.net.PDUEncoder.writePDataTF(PDUEncoder.java:141)
at org.dcm4che2.net.Association.writePDataTF(Association.java:951)
at org.dcm4che2.net.State$Sta6.sendPDataTF(State.java:247)
at org.dcm4che2.net.Association.sendPDataTF(Association.java:943)
at org.dcm4che2.net.PDUEncoder.writeDIMSE(PDUEncoder.java:412)
at org.dcm4che2.net.Association.writeDimseRSP(Association.java:723)
at org.dcm4che2.net.Association.writeDimseRSP(Association.java:701)

Gut, das hat eben was mit DICOM zu tun, aber dürfte relativ egal sein...

Hat da jemand ne Idee, was da falsch gelaufen sein könnte?

MfG mikachu

Edit 1:
Gut, die ersten fünf Zeilen des Stacktraces sind daher gekommen, weil ich da eben abgebrochen habe. Aber wenn ich mit dem Debugger hinterherhüpfe hört eben das Bearbeiten bei Zeile sechs auf (Channels.write()).


----------



## SlaterB (21. Jul 2009)

fehlt da nicht die erste Zeile mit der Fehlermeldung?

wenn es beim ersten Mal geht und beim zweiten nicht mehr, dann klingt das allgemein danach, als wäre die Verbindung/ ein Stream geschlossen worden


----------



## mikachu (21. Jul 2009)

Das stimmt, aber bei jeden neuen Connect wird ein neuer Socket mitgegeben, über den dann eben Daten verschickt werden.

Edit 1: Oder kann man auch den Zustand des Channels iwie rauskriegen!?


----------



## mikachu (22. Jul 2009)

Das kuriose ist ja, dass, wenn mehrere Anfragen mit längerer Wartezeit abgesandt werden, auch mehrere (ATM zwei) abgearbeitet werden, bevor die nächste Anfrage dann klemmt...

Edit: Kuriosum Nummero 2 ist, wenn ich die Anfrage über einen normalen ServerSocket.accept()-Socket löse, alles wunderbar klappt!
Doch ich muss auf den ServerSocketChannel zurückgreifen, da die Applikation beim warten auf eine neue Verbindung unterbrochen werden kann und dies mit dem "normalem" Socket nicht möglich ist, da dieser sich nicht unterbrechen lässt. Das geht aber mit einem Socket, der über ServerSocketChannel.open().socket() ermittelt wird.


----------



## sparrow (22. Jul 2009)

mikachu hat gesagt.:


> Doch ich muss auf den ServerSocketChannel zurückgreifen, da die Applikation beim warten auf eine neue Verbindung unterbrochen werden kann und dies mit dem "normalem" Socket nicht möglich ist, da dieser sich nicht unterbrechen lässt.



Öhm... doch? ServerSocket.close()

In folgendem Beispiel wird ein 2. Thread gestartet der nach 2000ms den ServerSockt via close() abschießt.


```
import java.io.IOException;
import java.net.ServerSocket;


public class Main {


    public static void main(String[] args) {
      try {
            ServerSocket socket = new ServerSocket(9999);
            ToeteSocket ts = new ToeteSocket(2000, socket);
            Thread tst = (Thread)ts;
            tst.start();
            System.out.println("Hauptthread: Socket blockiert");
            socket.accept();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
      System.out.println("und Ende");
    }

    static class ToeteSocket extends Thread {
        long ms;
        ServerSocket seso;
        public ToeteSocket(long ms, ServerSocket seso) {
            this.ms = ms;
            this.seso = seso;
        }
        public void run() {
            System.out.println("Thread läuft");
            try {
                Thread.sleep(ms);
                System.out.println("Thread ist aufgewacht");
                seso.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

}
```


----------



## mikachu (23. Jul 2009)

Das wäre eine Möglichkeit, wenn der Socket für den Thread sichtbar wäre.
Aber der Kapselung zufolge wird der "ServerThread" nur interrupted, was ja nicht zu einem Return aus der accept()-Methode führt.

Aber Danke für die Mühen... ich hab das Problem jez doch gefunden, und lag, wie immer, bei meinem Code...


----------

