2017-02-09 3 views
0

아래 코드는 서버를 성공적으로 만들고 들어오는 클라이언트를 수락합니다.NIO 서버에서 메시지 보내기

package socket; 

import java.nio.*; 
import java.nio.channels.*; 
import java.net.*; 
import java.util.*; 
import java.io.IOException; 

public class NonBlockingServer { 

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

     // Create a new Thread 
     Server s = new Server(); 
     new Thread(s).start(); 

     // Give 10 seconds for client to connect 
     Thread.sleep(10000); 

// This Doesn't work? 

     s.Write("Hello, Client!"); 

     System.out.println("Done"); 
    } 
} 

//A class which implements Runnable Interface 
class Server implements Runnable { 

    SocketChannel AcceptedClient; 
    ServerSocketChannel serverChannel; 
    Selector selector; 

    void Write(String s) throws IOException { 
     ByteBuffer buffer = ByteBuffer.allocate(s.length()); 
     buffer.put(s.getBytes()); 

     int numWrite = -1; 
     numWrite = AcceptedClient.write(buffer); 

     while (buffer.hasRemaining()) 
     { 
      numWrite += AcceptedClient.write(buffer); 
     } 

     System.out.println(numWrite); 
    } 

    @Override 
    public void run() 
    { 

     int port = 4041; 

     System.out.println("Listening for connections on port " + port); 

     try { 
      // Bind the port 
      serverChannel = ServerSocketChannel.open(); 
      ServerSocket ss = serverChannel.socket(); 
      InetSocketAddress address = new InetSocketAddress(port); 
      ss.bind(address); 

      // Non-blocking Server 
      serverChannel.configureBlocking(false); 

      // Register with Selector 
      selector = Selector.open(); 
      serverChannel.register(selector, SelectionKey.OP_ACCEPT); 

     } catch (IOException ex) { 
      ex.printStackTrace(); 
      return; 
     } 

     while (true) { 

      try { 

       // Blocks until a 'socket' is ready registered with selector is ready. 
       selector.select(); 

      } catch (IOException ex) { 
       ex.printStackTrace(); 
       break; 
      } 

      Set<SelectionKey> readyKeys = selector.selectedKeys(); 
      Iterator<SelectionKey> iterator = readyKeys.iterator(); 

      while (iterator.hasNext()) { 

       SelectionKey key = iterator.next(); 
       iterator.remove(); 

       try { 

        if (key.isAcceptable()) { 

         ServerSocketChannel server = (ServerSocketChannel) key.channel(); 
         SocketChannel client = server.accept(); 
         System.out.println("Accepted connection from " + client); 
         client.configureBlocking(false); 

         // Client accepted by server can read. 
         SelectionKey key2 = client.register(selector, SelectionKey.OP_READ); 

         AcceptedClient = (SocketChannel) key2.channel(); 

        } 

       } catch (IOException ex) { 
        key.cancel(); 
        try { 
         key.channel().close(); 
        } catch (IOException cex) { 
        } 
       } 
      } 
     } 
    } 
} 

하지만이 서버에 연결 한 후 클라이언트에 메시지를 보내려고 할 때, 그것은 즉 메시지가 클라이언트에 의해 수신되지 작동하지 않습니다.

서버에서 특정 클라이언트로 메시지를 보내는 올바른 방법은 무엇입니까?

인터넷을 살펴본 결과 서버가 클라이언트에게 메시지를 보내는 예제를 찾지 못했습니다.

+0

매우 열심히 보지 않았습니다. 인터넷은 NIO로 가득차 있으며 예제를 보내고받습니다. 자바 튜토리얼은 처음에는이 사이트는 말할 것도없고. 나는 그것에 관해 수백 가지의 질문에 답했다. – EJP

답변

1

write() 전에 버퍼를 flip()으로 지정해야합니다. 계속 유지하려면 compact()이 필요합니다.

NB 채널을 닫으면 키가 취소됩니다.

+0

뒤집은 후에 작동했습니다. EJP 감사합니다! 내가 알고 싶은 경우 서버가 모든 연결된 클라이언트에게 메시지를 브로드 캐스팅하도록하려면 OP_WRITE를 사용합니까? – user963241

+0

더 중요한 질문은 이제 ServerSocketChannel을 닫는 것입니다. 스레드, 클라이언트와 서버, 선택기 및 서버 자체가 연결되어 있습니다. 물건을 닫으라고 주문 하시겠습니까? – user963241

+0

Err,'ServerSocketChannel.close()','SocketChannel.close()','Selector.close()'? 새로운 질문이 있으면 새로운 질문으로 질문하십시오. 이것은 포럼이 아닙니다. – EJP

관련 문제