NIO编写Socket服务器

该博客介绍了如何使用Java NIO编写一个简单的Socket服务器,服务器能够接收客户端输入的文本,如果输入以“ ”结束则回显文本,若输入符合"get file:xxxx"模式,服务器会尝试查找并返回指定路径的文件内容,否则提示文件未找到。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面程序接收客户端输入一行文本(以“\r\n”)结束,并向客户端回显输入的文本。如果输入的文本是 “get file:xxxx”模式,则把“xxxx” 解析为服务器class path下的一个文件,如果找到该文件,则回显该文件的内容,如果找不到文件,回显文件不能找到的消息。

[java]  view plain  copy
  1. import java.io.IOException;  
  2. import java.net.InetSocketAddress;  
  3. import java.net.URL;  
  4. import java.nio.ByteBuffer;  
  5. import java.nio.channels.SelectionKey;  
  6. import java.nio.channels.Selector;  
  7. import java.nio.channels.ServerSocketChannel;  
  8. import java.nio.channels.SocketChannel;  
  9. import java.nio.charset.Charset;  
  10. import java.nio.charset.StandardCharsets;  
  11. import java.nio.file.Files;  
  12. import java.nio.file.Path;  
  13. import java.nio.file.Paths;  
  14. import java.util.Iterator;  
  15. import java.util.Set;  
  16.   
  17. public class NIOServer {  
  18.     private static final Charset DEFAULT_CHARSET = StandardCharsets.ISO_8859_1;  
  19.   
  20.     private static final int BUFFER_SIZE = 1024;  
  21.   
  22.     private int port = 8081;  
  23.   
  24.     public NIOServer(int port) {  
  25.         this.port = port;  
  26.     }  
  27.   
  28.     public NIOServer() {  
  29.     }  
  30.   
  31.     public void start() {  
  32.         ServerSocketChannel ssc = null;  
  33.         try {  
  34.             ssc = ServerSocketChannel.open();  
  35.             ssc.configureBlocking(false);  
  36.             ssc.bind(new InetSocketAddress(this.port));  
  37.             Selector sel = Selector.open();  
  38.             ssc.register(sel, SelectionKey.OP_ACCEPT);  
  39.             while (true) {  
  40.                 Set<SelectionKey> keySet = null;  
  41.                 try {  
  42.                     sel.select();  
  43.                     keySet = sel.selectedKeys();  
  44.                 } catch (Exception e) {  
  45.                     e.printStackTrace();  
  46.                     break;  
  47.                 }  
  48.   
  49.                 for (Iterator<SelectionKey> it = keySet.iterator(); it.hasNext();) {  
  50.                     SelectionKey sKey = it.next();  
  51.                     it.remove();  
  52.                     try {  
  53.                         if (sKey.isAcceptable()) {  
  54.                             ServerSocketChannel serChannel = (ServerSocketChannel) sKey.channel();  
  55.                             SocketChannel clientChannel = serChannel.accept();  
  56.                             clientChannel.configureBlocking(false);  
  57.   
  58.                             SelectionKey k2 = clientChannel.register(sel, SelectionKey.OP_READ);  
  59.                             k2.attach(ByteBuffer.allocate(BUFFER_SIZE));  
  60.   
  61.                         } else if (sKey.isWritable()) {  
  62.                             SocketChannel clientChannel = (SocketChannel) sKey.channel();  
  63.                             ByteBuffer[] bfs = (ByteBuffer[]) sKey.attachment();  
  64.                             if (bfs[bfs.length - 1].hasRemaining()) {  
  65.                                 clientChannel.write(bfs);  
  66.                             } else {  
  67.                                 clientChannel.close();  
  68.   
  69.                             }  
  70.   
  71.                         } else if (sKey.isReadable()) {  
  72.                             SocketChannel clientChannel = (SocketChannel) sKey.channel();  
  73.                             ByteBuffer bf = (ByteBuffer) sKey.attachment();  
  74.                             String msg = "";  
  75.                             boolean clientEnd = false;  
  76.                             if (bf.hasRemaining()) {  
  77.                                 int len = clientChannel.read(bf);  
  78.                                 if (len != -1 && bf.position() > 1) {  
  79.                                     char lastChar = (char) bf.get(bf.position() - 1);  
  80.                                     char last2Char = (char) bf.get(bf.position() - 2);  
  81.                                     if (String.valueOf(new char[] { last2Char, lastChar }).equals("\r\n")) {  
  82.                                         System.out.println("client inupt end.");  
  83.                                         clientEnd = true;  
  84.                                     }  
  85.                                 }  
  86.   
  87.                                 if (len == -1) {  
  88.                                     System.out.println("client closed.");  
  89.                                     clientEnd = true;  
  90.                                 }  
  91.   
  92.                             } else {  
  93.                                 System.out.println("buff is full.");  
  94.                                 msg = "You can only enter " + BUFFER_SIZE + " chars\r\n";  
  95.                                 clientEnd = true;  
  96.                             }  
  97.   
  98.                             if (clientEnd) {  
  99.                                 ByteBuffer[] att = processInput(bf, msg);  
  100.                                 clientChannel.register(sel, SelectionKey.OP_WRITE, att);  
  101.                             }  
  102.                         }  
  103.                     } catch (Exception e) {  
  104.                         sKey.cancel();  
  105.                         e.printStackTrace();  
  106.                     }  
  107.                 }  
  108.   
  109.             }  
  110.   
  111.         } catch (IOException e) {  
  112.             e.printStackTrace();  
  113.         } finally {  
  114.             if (ssc != null) {  
  115.                 try {  
  116.                     ssc.close();  
  117.                 } catch (IOException e) {  
  118.                     e.printStackTrace();  
  119.                 }  
  120.             }  
  121.         }  
  122.   
  123.     }  
  124.   
  125.     private ByteBuffer[] processInput(ByteBuffer bf, String msg) throws Exception {  
  126.         bf.flip();  
  127.         ByteBuffer promptMsg = ByteBuffer.wrap((msg + "You just input:\r\n").getBytes(DEFAULT_CHARSET));  
  128.   
  129.         String inputMsg = new String(bf.array(), bf.position(), bf.limit(), DEFAULT_CHARSET).trim();  
  130.   
  131.         ByteBuffer[] att = new ByteBuffer[] { promptMsg, bf };  
  132.   
  133.         if (inputMsg.indexOf("get file:") >= 0) {  
  134.             String fileName = inputMsg.substring("get file:".length()).trim();  
  135.             System.out.println("fileName=" + fileName);  
  136.             URL fileURL = this.getClass().getClassLoader().getResource(fileName);  
  137.             if (fileURL != null) {  
  138.                 Path path = Paths.get(fileURL.toURI());  
  139.                 System.out.println(path);  
  140.   
  141.                 ByteBuffer fileData = ByteBuffer.wrap(Files.readAllBytes(path));  
  142.                 ByteBuffer info = ByteBuffer  
  143.                         .wrap(("The content of file " + fileName + ":\r\n").getBytes(DEFAULT_CHARSET));  
  144.                 att = new ByteBuffer[] { promptMsg, bf, info, fileData };  
  145.   
  146.             } else {  
  147.                 String errMsg = "fileName: " + fileName + " not found in the classpath.";  
  148.                 System.out.println(errMsg);  
  149.   
  150.                 att = new ByteBuffer[] { promptMsg, bf, ByteBuffer.wrap(errMsg.getBytes(DEFAULT_CHARSET)) };  
  151.   
  152.             }  
  153.   
  154.         }  
  155.         return att;  
  156.     }  
  157.   
  158.     public static void main(String[] args) {  
  159.         new NIOServer().start();  
  160.     }  
  161.   
  162. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值