Java NIO提供了一套网络api,可以用来处理连接数很多的情况。他的基本思想就是用一个线程来处理多个channel。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package geym.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class MyServer {
    public static void main(String args[]) throws Exception  
    {  
        MyServer server = new MyServer(8080);  
        server.listen();  
    }  
  
    // 接受和发送数据缓冲区  
    private ByteBuffer send = ByteBuffer.allocate(1024);  
    private ByteBuffer receive = ByteBuffer.allocate(1024);  
  
    public int port = 0;  
  
    ServerSocketChannel ssc = null;  
  
    Selector selector = null;  
  
    public MyServer(int port) throws Exception  
    {  
        // 打开服务器套接字通道  
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();  
        // 服务器配置为非阻塞  
        serverSocketChannel.configureBlocking(false);  
        // 检索与此通道关联的服务器套接字  
        ServerSocket serverSocket = serverSocketChannel.socket();  
        // 套接字的地址端口绑定
        serverSocket.bind(new InetSocketAddress(port));  
        // 通过open()方法找到Selector  
        selector = Selector.open();  
  
        // 注册到selector,等待连接  
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);  
        System.out.println("Server Start----8888:");  
          
        // 向发送缓冲区加入数据  
        send.put("data come from server".getBytes());  
    }  
  
    // 监听  
    private void listen() throws IOException  
    {  
        while (true)  
        {  
            // 等待一个连接,可能会返回多个key
            int count=selector.select();
            System.out.println("count="+count);
            // 返回此选择器的已选择键集。  
            Set<SelectionKey> selectionKeys = selector.selectedKeys();  
            Iterator<SelectionKey> iterator = selectionKeys.iterator();  
            while (iterator.hasNext())  
            {  
                SelectionKey selectionKey = iterator.next();  
  
                // 这里记得手动的把他remove掉,不然selector中的selectedKeys集合不会自动去除  
                iterator.remove();  
                handle(selectionKey);  
            }  
        }  
    }  
  
    // 处理请求  
    private void handle(SelectionKey selectionKey) throws IOException  
    {  
  
        ServerSocketChannel server = null;  
        SocketChannel client = null;  
        String receiveText;  
        String sendText;  
        int count = 0;  
  
        // 测试此键的通道是否已准备好接受新的套接字连接。  
        if (selectionKey.isAcceptable())  
        {  
            System.out.println("selectionKey.isAcceptable()");
            // 返回为之创建此键的通道。  
            server = (ServerSocketChannel) selectionKey.channel();  
  
            // 此方法返回的套接字通道(如果有)将处于阻塞模式。  
            client = server.accept();  
            // 配置为非阻塞  
            client.configureBlocking(false);  
            // 注册到selector,等待连接  
            client.register(selector, SelectionKey.OP_READ  
                    | SelectionKey.OP_WRITE);  
        }  
        else  
            if (selectionKey.isReadable())  
            {  
                System.out.println("selectionKey.isReadable()");
                // 返回为之创建此键的通道。  
                client = (SocketChannel) selectionKey.channel();  
                // 将缓冲区清空以备下次读取  
                receive.clear();  
                // 读取服务器发送来的数据到缓冲区中  
                client.read(receive);  
  
//                System.out.println(new String(receive.array()));  
                  
                selectionKey.interestOps(SelectionKey.OP_WRITE);  
            }  
            else  
                if (selectionKey.isWritable())  
                {  
                    System.out.println("selectionKey.isWritable()");
                    // 将缓冲区清空以备下次写入  
                    send.flip();  
                    // 返回为之创建此键的通道。  
                    client = (SocketChannel) selectionKey.channel();  
  
                    // 输出到通道  
                    client.write(send);  
                      
//                    selectionKey.interestOps(SelectionKey.OP_READ);  
                }  
    } 
}

客户端代码如下:

Java NIO 网络编程基础的更多相关文章

  1. Netty | 第1章 Java NIO 网络编程《Netty In Action》

    目录 前言 1. Java 网络编程 1.1 Javs NIO 基本介绍 1.2 缓冲区 Buffer 1.2 通道 Channel 1.3 选择器 Selector 1.4 NIO 非阻塞网络编程原 ...

  2. Java NIO网络编程demo

    使用Java NIO进行网络编程,看下服务端的例子 import java.io.IOException; import java.net.InetAddress; import java.net.I ...

  3. JAVA的网络编程基础概念

    网络编程的目的就是指直接或间接地通过网络协议与其他计算机进行通讯.网络编程中有两个主要的问题,一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输.在TCP/IP协 ...

  4. Java 之 网络编程基础

    一.软件结构 C/S 结构:全称为 Client/Server 结构,是指客户端和服务器结构.常见的程序有微信,QQ,迅雷等软件. B/S 结构:全称 Brower/Server 结构,是指浏览器和服 ...

  5. Java网络编程和NIO详解开篇:Java网络编程基础

    Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为 ...

  6. Java网络编程基础(Netty预备知识)

    今天在家休息,闲来无事,写篇博客,陶冶下情操~~~ =================我是分割线================ 最近在重新学习Java网络编程基础,以便后续进行Netty的学习. 整 ...

  7. 【Java基础】Java网络编程基础知识

    什么是网络编程 网络编程是通过使用套接字来达到进程间通信目的,那什么是套接字呢?其实套接字是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的 ...

  8. 大数据学习笔记——Java篇之网络编程基础

    Java网络编程学习笔记 1. 网络编程基础知识 1.1 网络分层图 网络分层分为两种模型:OSI模型以及TCP/IP网络模型,前者模型分为7层,是一个理论的,参考的模型:后者为实际应用的模型,具体对 ...

  9. java网络编程基础——网络基础

    java网络编程 网络编程基础 1.常用的网络拓扑结构: 星型网络.总线网络.环线网络.树形网络.星型环线网络 2.通信协议的组成 通信协议通常由3部分组成: 语义部分:用于决定通信双方对话类型 语法 ...

随机推荐

  1. Codeforces Round #354 (Div. 2)-A

    A. Nicholas and Permutation 题目链接:http://codeforces.com/contest/676/problem/A Nicholas has an array a ...

  2. mvc-9测试和调试

    单元测试 单元测试是比集成测试更底层的测试,用于确保特定的后台代码片段能正常运行; 前端单元测试更多是为了发现浏览器兼容性的bug; 断言 断言是测试的核心,是一些表述代码期望执行结果的语句 //正确 ...

  3. js中各种宽高

    各种宽高 Javascript: IE中:document.body.clientWidth ==> BODY对象宽度document.body.clientHeight ==> BODY ...

  4. Eclipse 的 Debug 介绍与技巧【转载】

    没有任何程序员能够一气呵成的写出没有任何 Bug 的代码,所以很多程序员有相当一部分时间是花费在 Debug 上的,程序调试是每个程序员必须面对的工作.如何使用 Eclipse 进行有效的.尤其是高效 ...

  5. node express新项目默认主文件app.js

    var express = require('express'); var path = require('path'); var favicon = require('serve-favicon') ...

  6. SQL 最基本使用

    --创建表 CREATE TABLE TreeData (id INT IDENTITY(1,1) PRIMARY KEY , pid INT ) --为表添加列 ALTER TABLE treeda ...

  7. 简单的jQuery扩展函数-让函数缓冲执行

    $.fn.retarder = function(delay, method) { var node = this; if (node.length) { if (node[0]._timer_) c ...

  8. 后缀数组 POJ 3581 Sequence

    题目链接 题意:把n个数字(A1比其他数字都大)的序列分成三段,每段分别反转,问字典序最小的序列. 分析:因为A1比其他数字都大,所以反转后第一段结尾是很大的数,相当是天然的分割线,第一段可以单独考虑 ...

  9. MFC 启动其他程序 变相跳转

    尝试了多种方式之后都无法成功地在对话框程序中弹出一个单文档程序,然后我想到了这个办法. 如果直接在代码中实现某些窗口的弹出比较麻烦,可以采用这个方式来弹出这种窗口. 如果需要传递参数,只需将数据写入文 ...

  10. Git pull 强制覆盖本地文件

    git fetch --all git reset --hard origin/master git pull