2011-03-28 3 views
0

이 코드를 적용하면 How to send and receive serialized object in socket channel 개체를 보내는 실시간 시뮬레이션이 가능하지만이 코드가 자연스럽게 블로킹되므로이 코드가 어떻게 변환 될 수 있는지에 따라 예외가 발생합니다. 지속적으로javanio로 블로킹에서 비 블로킹 I/O로 전환

import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.net.InetSocketAddress; 
import java.nio.channels.SocketChannel; 

public class CleanReceiver implements Runnable { 

    private SocketChannel sChannel; 
    private Thread receiverThread = new Thread(this, "receiverThread"); 


    private synchronized void startServer() throws IOException { 
     sChannel = SocketChannel.open(); 
     sChannel.configureBlocking(true); 
     if (sChannel.connect(new InetSocketAddress("localhost", 2345))) { 
      receiverThread.start(); 
     } 
    } 
public void run() { 

    while (true) { 
     try { 
      ObjectInputStream ois = new ObjectInputStream(sChannel.socket() 
        .getInputStream()); 

      BallState s = (BallState) ois.readObject(); 
      System.out.println("String is: '" + s.X + "'" + s.Y); 
      ois.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 

     System.out.println("End Receiver"); 
    } 
} 


     public static void main(String[] args) 
     throws IOException, ClassNotFoundException { 

      CleanReceiver rc=new CleanReceiver(); 
      rc.startServer(); 

      System.out.println("End Receiver"); 
     } 
} 

서버가이 시나리오에서이 디자인 작업은 연결 유지하는 것입니다 서버에서 응답을 찾고있다 : javanio

/* 
    * Writer 
    */ 
    import java.io.IOException; 
    import java.io.ObjectOutputStream; 
    import java.net.InetSocketAddress; 
    import java.nio.channels.ServerSocketChannel; 
    import java.nio.channels.SocketChannel; 

    public class CleanSender implements Runnable { 

     private SimManager SM; 
     private BallState ballState = new BallState(10, 5); 
     private ServerSocketChannel ssChannel; 

     private Thread tRunSer = new Thread(this, "ServerSelectThread"); 

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

     CleanSender server = new CleanSender(); 
     server.startServer(); 

    } 

    private void startServer() throws IOException { 
     ssChannel = ServerSocketChannel.open(); 
     ssChannel.configureBlocking(true); 
     int port = 2345; 
     ssChannel.socket().bind(new InetSocketAddress(port)); 
     // SM = new SimManager(this, BS); 
     // SM.start(); // GameEngine thread starting here 
     tRunSer.start(); 
    } 

    public void run() { 
     try { 
      SocketChannel sChannel = ssChannel.accept(); 

      while (true) { 

       ObjectOutputStream oos = new ObjectOutputStream(sChannel 
         .socket().getOutputStream()); 
       oos.writeObject(ballState); 
       System.out.println("Sending String is: '" + ballState.X + "'" + ballState.Y); 
       oos.close(); 
       System.out.println("Sender Start"); 
       System.out.println("Connection ended"); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

클라이언트 비 차단에의 클라이언트와 시뮬레이션 상태를 이미 연결된 클라이언트에게 동시에 보냅니 까?, 전문가들의 눈길을 사로 잡습니다.

덕분에,

jibbylala는

답변

0

귀하의 코드가 두 가지 주요 문제 : 연관된의 폐쇄 원인 모든 단일 개체를 처리 한 후

  • 닫고 스트림 소켓이므로 더 이상 유효하지 않으므로 다음 객체를 처리하는 데 사용할 수 없습니다. 수신 측에서는 루프 내부에 close()이 필요하지 않습니다. 송신 측에서는 close() 대신 flush()을 사용하여 버퍼가 플러시되도록하십시오.

  • 차단 IO를 구현할 때 (일반적으로) 각 클라이언트의 서버에서 새 스레드를 시작해야합니다. 여러 클라이언트와 동시에 통신 할 수 있습니다. 이 경우 스레드 동기화 문제에주의하십시오! 클라이언트 당 쓰레드를 갖는 것은 당신을 위해 허용하지 않은 경우

, 당신은 비 차단 방식으로 서버를 구현할 수 있지만, 이미 피터 Lawrey가 말했듯이, 더 복잡, 그래서 나는 당신이 그것을 얻을하는 것이 좋습니다 IO를 먼저 차단하는 작업.

1

당신의 ObjectInputStream 또는 ObjectOutputStream에를 사용하는 경우 당신이 IO를 차단 고수 좋습니다. 이러한 라이브러리에 비 차단 IO를 사용하면 실제 이점이없는 경우 10 배 더 어려워집니다.

NIO 대신 ServerSocketSocket을 사용 해본 적이 있습니까? 다음은 사용하기 쉽고 어떤 객체 스트림 originall의 사용하도록 설계 한 것입니다

+0

나는 자연을 차단했기 때문에 내가 겪고있는 문제가 있다고 생각 했는가? –

관련 문제