博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
笔记:Java Socket
阅读量:4660 次
发布时间:2019-06-09

本文共 4114 字,大约阅读时间需要 13 分钟。

1.阻塞式
服务器端:
   
    ServerSocketserverSocket = new ServerSocket(8888,10);
    while(true)
    {
       Socket socket= serverSocket.
accept();
       Inpustream inpustream =socket.getInpustream();
      Outpustream outpustream = socket.getOutpustream();
       。。。。。
       socket.close();
   } 
客户端:
    Sockt socket = newSocket("10.1.2.11",8888);
    Inpustream inpustream =socket.getInpustream();
   Outpustream outpustream = socket.getOutpustream();
   。。。。。
   socket.close();
发生阻塞的地方:
客户端:
(1)请求与服务器建立连接时,执行connect方法,进入阻塞状态,直到连接成功
(2)从输入流读入数据,若无足够数据,进入阻塞,直到读到足够数据或到达末尾
(3)向输出流写数据,直到写完
(4)设置了关闭延迟时间,关闭后阻塞
服务器端:
(1)执行accept方法,等待客户端连接,进入阻塞,直到收到连接
(2)输入流读取数据,若没有足够数据,阻塞
(3)输出流写数据,进入阻塞,直到写完
多线程处理阻塞的局限
(1)线程多,开销大,增加JVM调度线程的负担,增加死锁可能性
(2)线程许多时间浪费在I/O上
2.非阻塞
服务器端:
Selector selector = Selector
.open();
ServerSocketChannel serverSocketChannel =ServerSocketChannel.
open();
serverSocketChannel.
socket().setReuseAddress(true);
serverSocketChannel.
configureBlocking(false);
serverSocketChannel.
socket().
bind(newInetSocketAddress(8888));
serverSocketChannel.
register(selector,SelectionKey.
OP_ACCEPT);
while (selector.
select() > 0) {
    Set<<b>SelectionKey>selectedKeys = selector.
selectedKeys();
    Iterator iterator =selectedKeys.iterator();
     while(iterator.hasNext()) {
         SelectionKey key =null;
         try {
            key = iterator.next();
            if (key.
isAcceptable()) {
               accept(key, selector);
            } else if (key.
isReadable()) {
              receive(key);
            } else if (key.
isWritable()) {
               
send(key);
            }
            iterator.remove();
          } catch(Exception ex) {
             if (key != null) {
                try{
                   key.cancel();
                   key.channel().close();
                } catch (Exception ex2) {}
               }
           }
         }
       }
  protected void accept(SelectionKey
key, Selector selector) throws IOException {
      ServerSocketChannel serverSocketChannel =(ServerSocketChannel) key.
channel();
      SocketChannel socketChannel =serverSocketChannel.
accept();
      socketChannel.
configureBlocking(false);
      ByteBuffer buffer =ByteBuffer.
allocate(1024);
      socketChannel.
register(selector,SelectionKey.
OP_READ | SelectionKey.
OP_WRITE,
buffer);
    }
   protected voidreceive(SelectionKey
key) throws IOException {
       ByteBuffer buffer = (ByteBuffer)key.
attachment();
       SocketChannel channel = (SocketChannel)key.
channel();
       ByteBuffer readBuffer =ByteBuffer.allocate(32);
       channel.
read(readBuffer);
       readBuffer.flip();
       buffer.limit(buffer.capacity());
      
buffer.put(readBuffer);//
      System.out.println(Charset.forName("UTF-8").
decode(readBuffer).toString());
    }
protected void send(SelectionKey key) throws IOException{
       ByteBuffer buffer = (ByteBuffer)key.
attachment();
       SocketChannel channel = (SocketChannel)key.
channel();
       buffer.flip();
       String data =Charset.forName("UTF-8").decode(buffer).toString();
       if (data.indexOf("\r\n") == -1) {
          return;
       }
       String str = data.substring(0,data.indexOf("\n") + 1);
       ByteBuffer outBuffer =Charset.forName("UTF-8").
encode(" encode: " + str);
       while (outBuffer.
hasRemaining()) {
          channel.
write(outBuffer);
       }
      buffer.position(Charset.forName("UTF-8").encode(str).limit());
       buffer.compact();
       if ("bye\r\n".equals(str)) {
          key.
cancel();
          key.channel().
close();
          System.out.println(" close connection ");
       }
    }
客户端:
Selector selector= Selector
.open();
SocketChannel socketChannel= SocketChannel.
open();
InetSocketAddress address = newInetSocketAddress(InetAddress.getLocalHost(), 8888);
socketChannel.
connect(address);
socketChannel.
configureBlocking(false);
socketChannel.
register(selector, 
SelectionKey.
OP_READ 
|SelectionKey.
OP_WRITE);
while (selector.
select() > 0) {
    Set<<b>SelectionKey>selectedKeys = selector.
selectedKeys();
    Iterator iterator =selectedKeys.iterator();
     while(iterator.hasNext()) {
         SelectionKey key =null;
         try {
            key = iterator.next();
            if (key.
isReadable()) {
               receive(key);
            } else if (key.
isWritable()) {
              
 send(key);
            }
            iterator.remove();
          } catch(Exception ex) {
             if (key != null) {
                try{
                   key.cancel();
                   key.channel().close();
                } catch (Exception ex2) {}
               }
           }
         }
       }
3.非阻塞方式提升性能方式
java.nio.Buffer 缓冲区提升I/O
(1)减少实际物理读写次数
(2)缓冲区内存复用,减少动态分配与回收次数
主要方法:
clear()  将极限设置为容量,位置置0
flip()   将极限设置为位置,位置置0
rewind() 极限不变,位置置0
(也就是说,改变的都是极限,位置都置0)
Selector 轮询方式:
(1)线程接收客户连接时,若无连接,则立即返回
(2)线程从输入流读取数据时,若无足够数据,读取现有数据,立即返回
(3)输出类似
混用非阻塞和多线程:一个线程用于接收连接,另一个线程用于读取数据和发送数据

转载于:https://www.cnblogs.com/leeeee/p/7276574.html

你可能感兴趣的文章
NTP工作机制及时间同步的方法
查看>>
近段时间学习html和CSS的一些细碎总结
查看>>
第三章 栈和队列
查看>>
「Vue」v-html生成的图片大小无法调整的解决办法
查看>>
【BZOJ 4665】 4665: 小w的喜糖 (DP+容斥)
查看>>
Git 的 .gitignore 配置
查看>>
Language Integrated Query ----序
查看>>
【HDU】1542 Atlantis
查看>>
解决Android SDK Manager更新时出现问题
查看>>
Android Studio下“Error:Could not find com.android.tools.build:gradle:2.2.1”的解决方法
查看>>
第二章 第四节 添加SWT库
查看>>
docker file
查看>>
总结一些常见的国际标准化组织
查看>>
使用mybatis进行多条件的模糊查询的方式
查看>>
SqlServer 垂直分表
查看>>
BZOJ 1677: [Usaco2005 Jan]Sumsets 求和
查看>>
缓冲流
查看>>
DIV不用图片做可变可到处用的圆角
查看>>
luogu3899谈笑风生
查看>>
博客推荐
查看>>