2017-02-09 201 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发送和接收的例子。 Java教程,一开始,更不用说这个网站了。我已经回答了数百个问题。 – EJP

回答

1

您需要flip()之前的缓冲区write(),如果你打算保留它,你需要compact()它之后。

注意关闭通道会取消密钥。

+0

它翻转后工作。谢谢你,EJP!我想知道如果我希望服务器将消息广播给所有连接的客户端,那么我会使用OP_WRITE吗? – user963241

+0

我现在更重要的问题是关闭ServerSocketChannel。它有一个线程,将客户端连接到服务器,选择器和服务器本身。你能帮我开始关闭东西吗? – user963241

+0

Err,'ServerSocketChannel.close()','SocketChannel.close()'和'Selector.close()'?如果您有新问题,请将其作为新问题。这不是一个论坛。 – EJP

相关问题