2017-02-09 218 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

相關問題