以前一直採用.Net編寫服務端程序,最近須要切換到Linux平臺下,因而嘗試採用Java編寫數據服務器。TCP異步鏈接在C#中很容易實現,網上也有不少可供參考的代碼。但Java異步TCP的參考資料較少,網上例程可能是阻塞多線程方法,因爲線程的開銷較大,當客戶端較多時系統資源的消耗也較大。java
綜合網上和書本的相關知識,本文給出一個Java TCP異步接收數據的代碼示例,並給出相關的註釋。服務器
/** * TcpAsyncServer.java */ import java.nio.ByteBuffer; import java.nio.channels.*; import java.net.*; import java.util.Iterator; public class TcpAsyncServer { /*監聽端口*/ int port = 6000; /*緩衝區大小*/ ByteBuffer buffer = ByteBuffer.allocate(1024); /*其它相關定義*/ Selector selector; ServerSocketChannel channel; ServerSocket socket; /*啓動*/ public void Start() throws Exception { /*初始化一個Selector*/ selector = Selector.open(); /*打開通道*/ channel = ServerSocketChannel.open(); /*非阻塞模式*/ channel.configureBlocking(false); /*本機IP*/ //InetAddress ip = InetAddress.getByName("127.0.0.1"); InetAddress ip = InetAddress.getLocalHost(); System.out.println(ip.toString()); /*綁定IP和端口*/ InetSocketAddress address = new InetSocketAddress(ip,port); socket = channel.socket(); socket.bind(address); /*啓動監聽*/ System.out.println("TCP服務器開始監聽..."); Listen(); } /*中止*/ public void Stop() throws Exception { channel.close(); selector.close(); } /*監聽*/ public void Listen() throws Exception { /*註冊接收事件*/ channel.register(selector,SelectionKey.OP_ACCEPT); /*無限循環*/ while (true) { selector.select(); /*輪詢事件*/ Iterator iter = selector.selectedKeys().iterator(); while (iter.hasNext()) { SelectionKey key = (SelectionKey)iter.next(); iter.remove(); /*事件分類處理*/ if (key.isAcceptable()) { ServerSocketChannel ssc = (ServerSocketChannel)key.channel(); SocketChannel sc = ssc.accept(); sc.configureBlocking(false); sc.register(selector, SelectionKey.OP_READ); System.out.println("新終端已鏈接:"+ sc.getRemoteAddress()); } else if (key.isReadable()) { SocketChannel sc = (SocketChannel)key.channel(); int recvCount = sc.read(buffer); if (recvCount > 0) { byte[] arr = buffer.array(); System.out.println(sc.getRemoteAddress() + "發來數據: "+ new String(arr)); buffer.flip(); } else { sc.close(); } buffer.clear(); } else { } } } } }
/** * server.java */ public class server { public static void main(String[] args) throws Exception { TcpAsyncServer tcpServer = new TcpAsyncServer(); tcpServer.Start(); } }
效果演示:多線程
1. 利用TCP工具發送數據異步
3. 接收數據socket