170407、java基于nio工作方式的socket通信

客户端代码:

/**
 *
 */
package com.bobohe.nio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;

/**
 * 实现TCP/IP+NIO 方式的系统间通讯的代码,客户端:
 *
 * @author solo
 */
public class NioClient {

    /**
     * create solo
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        String host = "127.0.0.1";
        int port = 9527;

        Selector selector = Selector.open();

        SocketChannel clientChannel = SocketChannel.open();
        clientChannel.configureBlocking(false);
        clientChannel.connect(new InetSocketAddress(host, port));

        clientChannel.register(selector, SelectionKey.OP_CONNECT);

        BufferedReader systemIn = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            if (clientChannel.isConnected()) {
                String command = systemIn.readLine();
                clientChannel.write(Charset.forName("UTF-8").encode(command));

                if (command == null || "quit".equalsIgnoreCase(command)) {
                    System.out.println("Client quit!");

                    systemIn.close();
                    clientChannel.close();
                    selector.close();
                    System.exit(0);
                }

            }

            //最长阻塞10s
            int nKeys = selector.select(10 * 1000);
            if (nKeys > 0) {
                for (SelectionKey selectionKey : selector.selectedKeys()) {
                    if (selectionKey.isConnectable()) {
                        SocketChannel socketChannel = (SocketChannel)selectionKey.channel();
                        socketChannel.configureBlocking(false);
                        socketChannel.register(selector, SelectionKey.OP_READ);
                        socketChannel.finishConnect();
                    } else if (selectionKey.isReadable()) {
                        SocketChannel socketChannel = (SocketChannel)selectionKey.channel();
                        StringBuilder sb = new StringBuilder();

                        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                        try {
                            int readBytes = 0;
                            int ret = 0;
                            while ((ret = socketChannel.read(byteBuffer)) > 0) {
                                readBytes += ret;
                                byteBuffer.flip();

                                sb.append(Charset.forName("UTF-8").decode(byteBuffer).toString());

                                byteBuffer.clear();
                            }

                            if (readBytes == 0) {
                                /*
                                 * handle Exception
                                 */
                                System.err.println("handle opposite close Exception");
                                socketChannel.close();
                            }
                        } catch (IOException e) {
                            /*
                             * handle Exception
                             */
                            System.err.println("handle read Exception");
                            socketChannel.close();
                        } finally {
                            byteBuffer.clear();
                        }

                        String message = sb.toString();
                        System.out.println(message);
                    }
                }
                selector.selectedKeys().clear();

            } else {
                /*
                 * handle Exception
                 * 三秒没有响应则打印错误信息
                 */
                System.err.println("handle select timeout Exception");
                clientChannel.close();
            }

        }
    }

}

服务端代码:

/**
 *
 */

package com.bobohe.nio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
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.nio.charset.Charset;

/**
 * 实现TCP/IP+NIO 方式的系统间通讯的代码,服务器端: SocketChannel和ServerSocketChannel两个关键的类,网络IO
 * 的操作则改为通过ByteBuffer来实现。
 *
 * @author solo
 */
public class NioServer {

    /**
     * create by solo
     *
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        int port = 9527;
        System.out.println("Server listen on port: " + port);

        Selector selector = Selector.open();

        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        ServerSocket serverSocket = serverChannel.socket();
        serverSocket.bind(new InetSocketAddress(port));
        serverChannel.configureBlocking(false);

        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        while (true) {
            int nKeys = selector.select();
            if (nKeys > 0) {
                for (SelectionKey selectionKey : selector.selectedKeys()) {
                    if (selectionKey.isAcceptable()) {
                        ServerSocketChannel tempServerChannel = (ServerSocketChannel) selectionKey
                                .channel();
                        SocketChannel socketChannel = tempServerChannel
                                .accept();
                        if (socketChannel == null) {
                            continue;
                        }

                        socketChannel.configureBlocking(false);
                        socketChannel.register(selector, SelectionKey.OP_READ);
                    } else if (selectionKey.isReadable()) {
                        // try { Thread.sleep(5000); } catch
                        // (InterruptedException e) { e.printStackTrace(); }
                        SocketChannel socketChannel = (SocketChannel) selectionKey
                                .channel();

                        StringBuilder sb = new StringBuilder();
                        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                        try {
                            int readBytes = 0;
                            int ret = 0;
                            while ((ret = socketChannel.read(byteBuffer)) > 0) {
                                readBytes += ret;
                                byteBuffer.flip();

                                sb.append(Charset.forName("UTF-8")
                                        .decode(byteBuffer).toString());

                                byteBuffer.clear();
                            }

                            if (readBytes == 0) {
                                /*
                                 * handle Exception
                                 */
                                System.err
                                        .println("handle opposite close Exception");
                                socketChannel.close();
                            }

                            String message = sb.toString();
                            System.out.println("client: "
                                    + message);
                            if ("quit".equalsIgnoreCase(message.toString()
                                    .trim())) {
                                System.out.println("Client has been quit!");

                                socketChannel.close();
                            } else if ("serverquit".equalsIgnoreCase(message
                                    .trim())) {
                                System.out.println("Server has been shutdown!");

                                socketChannel.close();
                                serverChannel.close();
                                selector.close();
                                System.exit(0);
                            } else {
                                socketChannel.write(Charset.forName("UTF-8").encode("Server Handler Done!"));
                            }
                        } catch (IOException e) {
                            /*
                             * handle Exception
                             */
                            System.err.println("handle read Exception");
                            socketChannel.close();
                        } finally {
                            byteBuffer.clear();
                        }

                    }
                }
                selector.selectedKeys().clear();

            }
        }
    }

}
时间: 2024-12-25 20:51:04

170407、java基于nio工作方式的socket通信的相关文章

JAVA基础知识之网络编程——-基于NIO的非阻塞Socket通信

阻塞IO与非阻塞IO 通常情况下的Socket都是阻塞式的, 程序的输入输出都会让当前线程进入阻塞状态, 因此服务器需要为每一个客户端都创建一个线程. 从JAVA1.4开始引入了NIO API, NIO可以实现非阻塞IO, 这样就可以使用一个线程处理所有的客户请求. 基于NIO的非阻塞Socket通信 服务器将用来监听客户端请求的channel注册到selector上,启动一个线程,使用selector的select()获取求情的客户端的channel数量, 当监听到有客户端请求时,就通过Sel

基于TCP协议的简单Socket通信笔记(JAVA)

好久没写博客了,前段时间忙于做项目,耽误了些时间,今天开始继续写起~ 今天来讲下关于Socket通信的简单应用,关于什么是Socket以及一些网络编程的基础,这里就不提了,只记录最简单易懂实用的东西. 1.首先先来看下基于TCP协议Socket服务端和客户端的通信模型: Socket通信步骤:(简单分为4步) 1.建立服务端ServerSocket和客户端Socket 2.打开连接到Socket的输出输入流 3.按照协议进行读写操作 4.关闭相对应的资源 2.相关联的API: 1.首先先来看下S

多线程方式实现Socket通信

一.首先,介绍下两类传输协议:TCP:UDP TCP是Tranfer Control Protocol的 简称,是一种面向连接的保证可靠传输的协议.通过TCP协议传输,得到的是一个顺序的无差错的数据流.发送方和接收方的成对的两个socket之间必须建 立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送 或接收操作. UD

java学习小笔记(三.socket通信)【转】

三,socket通信1.http://blog.csdn.net/kongxx/article/details/7288896这个人写的关于socket通信不错,循序渐进式的讲解,用代码示例说明,运用流和socket进行远程通讯 2.最简单的socket是一个服务端对应一个客户端 server的写法 ServerSocket server = new ServerSocket(10000); Socket socket = server.accept(); BufferedReader in =

java基于NIO的分散读取文件,然后统一聚合后写入文件

分散读取:对于一个文件,可以分散的读取数据,可以快速的读取,好比多个线程在分段同时读取: 聚合写入:为了提高效率,一般读取到的数据都是分散的,要快速写入,就需要把分散的数据聚集在一起,然后一块写入到文件: 具体代码如下: //首先创建一个随机访问文件 RandomAccessFile raf= new RandomAccessFile("test.txt", "rw"); //根据随机获取通道 FileChannel channel = raf.getChannel

【转】在Java与C程序间进行socket通信的讨论

1. 背景 使用socket在Java程序与C程序间进行进程间通信.本文主要描述了在同C程序进行通信的Client端的Java实现功能. 1.1. 使用的语言 Client端:Java,JVM(JDK1.3) Server端:C,UNIX(Sun Solaris) 1.2. 讨论范围 数据发送:只涉及到Java中int整型系列的讨论,包括byte,short,int. 数据接受:涉及到byte,short,int,long,float,double,char. 1.3.Java与C的数据类型的比

Java网络编程之tcp的socket通信

1.客户端MyClient.java 1 import java.io.*; 2 import java.net.*; 3 4 public class MyClient 5 { 6 public static void main(String[] args)throws Exception 7 { 8 Socket s = new Socket("192.168.1.1" , 30000); 9 // 客户端启动ClientThread线程不断读取来自服务器的数据 10 new Th

C++基于TCP和UDP的socket通信

以下是关于socket编程的一个非常经典的例子: 服务端: #include <stdio.h> #include <Winsock2.h> //windows socket的头文件 #pragma comment( lib, "ws2_32.lib" )// 链接Winsock2.h的静态库文件 void main() { //初始化winsocket WORD wVersionRequested; WSADATA wsaData; int err; wVer

Java:Socket通信

Socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求.ServerSocket用于服务器端,Socket是建立网络连接时使用的.在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话.对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别.套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认. 实例一: