2012-10-09 181 views
0

編輯:在服務器端,如果我從ServerWriter類的run方法中刪除代碼並將其放入發送順序方法,刪除線程的代碼,它開始正常工作,套接字doesnt關。但我需要它是多線程的,我不明白爲什麼插槽與線程關閉。示出下面的代碼套接字不斷關閉

public void sendOrder(Order o){ 
//  ServerWriter sw=new ServerWriter(serversocket,o); 
//  Thread t=new Thread(sw); 
//  t.start(); 
     ObjectOutputStream out=null; 
     if(serversocket.isClosed()){ 
      System.out.println("closed"); 
     } 
     else{ 
      System.out.println("notclosed"); 
     } 
     try { 
      out=new ObjectOutputStream(serversocket.getOutputStream()); 
      out.writeObject(o); 
      out.reset(); 

     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 

編輯:我認爲插座正在關閉在服務器側而不是客戶端側,從服務器的輸出,其中將其打印在檢查isclosed)閉合(,其中爲對推斷這客戶端它說不封閉

我有一個套接字程序。我有兩個方法在客戶端1打開套接字和另一個讀取數據。每次我嘗試運行此代碼時,我都會收到eofexception,這意味着套接字已關閉。

我有這個錯誤,最後一次我在這個代碼幾天前的工作,所以我只是從閱讀中刪除所有的代碼,並將其粘貼在打開的方法,它開始工作(我真的不明白爲什麼)。

今天我恢復了原狀,只是將代碼移回了讀取方法,一切開始正常工作,連接並沒有自動關閉。然後我使讀部分線程,仍然一切工作正常,我正在編寫代碼的部分,現在當我運行它我再次得到相同的eofexception,我沒有改變任何東西在讀取代碼,所以我有不知道爲什麼會發生這種情況。在服務器端我做了一個類似的事情,我接受方法中的套接字並通過線程發送數據。在服務器端,我得到一個SocketException。

我真的可以使用一些幫助來闡明我在做錯什麼。

以下是客戶端代碼

public void open(){ 
    try 
    { 
     s=new Socket(InetAddress.getLocalHost(),12345); 

     s.setKeepAlive(true); 

    } 

    catch(UnknownHostException u) 
    { 
     System.err.println("I don't know host"); 

    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 


} 



public void read(){ 
    ClientReader cr=new ClientReader(s); 
    Thread t=new Thread(cr); 
    t.start(); 
} 


class ClientReader implements Runnable{ 
    Socket s; 
    ClientReader(Socket s){ 
     this.s=s; 
    } 
    public void run(){ 
     InputStream is; 
     ObjectInputStream ois=null; 
     try { 
      is = s.getInputStream(); 
        if(!(s==null)){ 
       System.out.println("not null"); 
      } 
        **//outputs NotClosed here** 
     if(s.isClosed()){ 
      System.out.println("CLOSED"); 
     } 
        else system.out.println("Not Closed") 

       //Throws EOFException here 
     ois= new ObjectInputStream(is); 
     } catch (IOException e2) { 
      // TODO Auto-generated catch block 
      e2.printStackTrace(); 
     } 
     Order order; 
     while(true){ 
      try{ 
      order=(Order)ois.readObject(); 
      Client_Socket.ll.add(order); 
      System.out.println(order); 
      System.out.println(order.getTotal()); 

      } 
      catch(EOFException e){ 

       try{ 
       ois.close(); 
       s.close(); 
       break; 

      } catch (IOException e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 
      } catch (ClassNotFoundException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

主要方法用於調用客戶機

public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    Client_Socket cs=new Client_Socket(); 
    cs.open(); 
    cs.read(); 

} 

例外客戶端

not null 
Not Closed 

java.io.EOFException 
    at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source) 
    at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source) 
    at java.io.ObjectInputStream.readStreamHeader(Unknown Source) 
    at java.io.ObjectInputStream.<init>(Unknown Source) 
    at ClientReader.run(Client_Socket.java:82) 
    at java.lang.Thread.run(Unknown Source) 
Exception in thread "Thread-0" java.lang.NullPointerException 
    at ClientReader.run(Client_Socket.java:91) 
    at java.lang.Thread.run(Unknown Source) 

例外在服務器側

Connection from Socket[addr=/192.168.0.108,port=50380,localport=12345] 
closed 

java.net.SocketException: Socket is closed 
    at java.net.Socket.getOutputStream(Unknown Source) 
    at ServerWriter.run(Server_Socket.java:123) 
    at java.lang.Thread.run(Unknown Source) 

服務器端的代碼片斷

public void openSocket(){ 
    try 
    { 
     service=new ServerSocket(12345); 

     serversocket=service.accept(); 
     serversocket.setKeepAlive(true); 
     System.out.println("Connection from "+serversocket); 



    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     System.out.println("output stream error"); 
     System.out.println(e); 
    } 

} 


public void sendOrder(Order o){ 
    ServerWriter sw=new ServerWriter(serversocket,o); 
    Thread t=new Thread(sw); 
    t.start(); 

} 


class ServerWriter implements Runnable{ 
Socket serversocket; 
Order o; 
ServerWriter(Socket s,Order o){ 
    this.serversocket=s; 
    this.o=o; 
} 

public void run() { 
    ObjectOutputStream out=null; 
    if(serversocket.isClosed()){ 
     System.out.println("closed"); 
    } 
    else{ 
     System.out.println("notclosed"); 
    } 
    try { 
       //SocketException here 
     out=new ObjectOutputStream(serversocket.getOutputStream()); 
     out.writeObject(o); 
     out.reset(); 

    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

}

方法片段調用服務器

public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    Order o=new Order(); 
    Server_Socket ss=new Server_Socket(); 
    ss.openSocket(); 
    ss.sendOrder(o); 

      ss.close(); 

} 
+0

你應該發佈異常和堆棧跟蹤,因爲它不清楚你描述的是什麼。 –

+0

您應該檢查「is」是否爲空,而不是s是否關閉。他們是不同的對象,你不知道底層結構。 –

+0

@Greg Giacovelli我已添加例外 – yahh

回答

3

這異常意味着關閉套接字,然後繼續使用它。與同伴無關。

可能您不知道關閉輸入流或套接字的輸出流會關閉另一個流和套接字。

+0

我還沒有關閉流,你可以看看我最近的編輯。我剛剛刪除了線程並將相同的代碼複製到sendorder()中並開始工作,但我需要線程。 – yahh

+1

@yahh你肯定已經關閉了一些東西。例外情況如此。在你的代碼中,有很多絨毛:s.getInputStream()永遠不能爲null;在你調用s.getInputStream()的同一個塊中s.isClosed()永遠不會是真的;除SocketTimeoutException之外的任何IOException都是致命的,並且必須導致您關閉併產生'break';內部的try/catch塊太多了;並且您應該在套接字的生命週期中使用相同的流,而不是爲每條消息創建新的流。最後一個是問題的原因,因爲您釋放的流將被GC關閉,這會關閉套接字。 – EJP