Java Socket编程实例(四)- NIO TCP实践_java

一、回传协议接口和TCP方式实现:

1.接口:

import java.nio.channels.SelectionKey;
import java.io.IOException; 

public interface EchoProtocol {
 void handleAccept(SelectionKey key) throws IOException;
 void handleRead(SelectionKey key) throws IOException;
 void handleWrite(SelectionKey key) throws IOException;
} 

2.实现:

import java.nio.channels.*;
import java.nio.ByteBuffer;
import java.io.IOException; 

public class TCPEchoSelectorProtocol implements EchoProtocol{
  private int bufSize; // Size of I/O buffer 

  public EchoSelectorProtocol(int bufSize) {
    this.bufSize = bufSize;
  } 

  public void handleAccept(SelectionKey key) throws IOException {
    SocketChannel clntChan = ((ServerSocketChannel) key.channel()).accept();
    clntChan.configureBlocking(false); // Must be nonblocking to register
    // Register the selector with new channel for read and attach byte buffer
    clntChan.register(key.selector(), SelectionKey.OP_READ, ByteBuffer.allocate(bufSize)); 

  } 

  public void handleRead(SelectionKey key) throws IOException {
    // Client socket channel has pending data
    SocketChannel clntChan = (SocketChannel) key.channel();
    ByteBuffer buf = (ByteBuffer) key.attachment();
    long bytesRead = clntChan.read(buf);
    if (bytesRead == -1) { // Did the other end close?
      clntChan.close();
    } else if (bytesRead > 0) {
      // Indicate via key that reading/writing are both of interest now.
      key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
    }
  } 

  public void handleWrite(SelectionKey key) throws IOException {
    /*
     * Channel is available for writing, and key is valid (i.e., client channel
     * not closed).
     */
    // Retrieve data read earlier
    ByteBuffer buf = (ByteBuffer) key.attachment();
    buf.flip(); // Prepare buffer for writing
    SocketChannel clntChan = (SocketChannel) key.channel();
    clntChan.write(buf);
    if (!buf.hasRemaining()) { // Buffer completely written?
      //Nothing left, so no longer interested in writes
      key.interestOps(SelectionKey.OP_READ);
    }
    buf.compact(); // Make room for more data to be read in
  } 

} 

二、NIO TCP客户端:

import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel; 

public class TCPEchoClientNonblocking { 

  public static void main(String args[]) throws Exception {
    String server = "127.0.0.1"; // Server name or IP address
    // Convert input String to bytes using the default charset
    byte[] argument = "0123456789abcdefghijklmnopqrstuvwxyz".getBytes(); 

    int servPort = 5500; 

    // Create channel and set to nonblocking
    SocketChannel clntChan = SocketChannel.open();
    clntChan.configureBlocking(false); 

    // Initiate connection to server and repeatedly poll until complete
    if (!clntChan.connect(new InetSocketAddress(server, servPort))) {
      while (!clntChan.finishConnect()) {
        System.out.print("."); // Do something else
      }
    }
    ByteBuffer writeBuf = ByteBuffer.wrap(argument);
    ByteBuffer readBuf = ByteBuffer.allocate(argument.length);
    int totalBytesRcvd = 0; // Total bytes received so far
    int bytesRcvd; // Bytes received in last read
    while (totalBytesRcvd < argument.length) {
      if (writeBuf.hasRemaining()) {
        clntChan.write(writeBuf);
      }
      if ((bytesRcvd = clntChan.read(readBuf)) == -1) {
        throw new SocketException("Connection closed prematurely");
      }
      totalBytesRcvd += bytesRcvd;
      System.out.print("."); // Do something else
    } 

    System.out.println("Received: " + // convert to String per default charset
        new String(readBuf.array(), 0, totalBytesRcvd).length());
    clntChan.close();
  }
} 

三、NIO TCP服务端:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.*;
import java.util.Iterator; 

public class TCPServerSelector {
  private static final int BUFSIZE = 256; // Buffer size (bytes)
  private static final int TIMEOUT = 3000; // Wait timeout (milliseconds) 

  public static void main(String[] args) throws IOException {
    int[] ports = {5500};
    // Create a selector to multiplex listening sockets and connections
    Selector selector = Selector.open(); 

    // Create listening socket channel for each port and register selector
    for (int port : ports) {
      ServerSocketChannel listnChannel = ServerSocketChannel.open();
      listnChannel.socket().bind(new InetSocketAddress(port));
      listnChannel.configureBlocking(false); // must be nonblocking to register
      // Register selector with channel. The returned key is ignored
      listnChannel.register(selector, SelectionKey.OP_ACCEPT);
    } 

    // Create a handler that will implement the protocol
    TCPProtocol protocol = new TCPEchoSelectorProtocol(BUFSIZE); 

    while (true) { // Run forever, processing available I/O operations
      // Wait for some channel to be ready (or timeout)
      if (selector.select(TIMEOUT) == 0) { // returns # of ready chans
        System.out.print(".");
        continue;
      } 

      // Get iterator on set of keys with I/O to process
      Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();
      while (keyIter.hasNext()) {
        SelectionKey key = keyIter.next(); // Key is bit mask
        // Server socket channel has pending connection requests?
        if (key.isAcceptable()) {
          System.out.println("----accept-----");
          protocol.handleAccept(key);
        }
        // Client socket channel has pending data?
        if (key.isReadable()) {
          System.out.println("----read-----");
          protocol.handleRead(key);
        }
        // Client socket channel is available for writing and
        // key is valid (i.e., channel not closed)?
        if (key.isValid() && key.isWritable()) {
          System.out.println("----write-----");
          protocol.handleWrite(key);
        }
        keyIter.remove(); // remove from set of selected keys
      }
    }
  } 

} 

以上就是本文的全部内容,查看更多Java的语法,大家可以关注:《Thinking in Java 中文手册》、《JDK 1.7 参考手册官方英文版》、《JDK 1.6 API java 中文参考手册》、《JDK 1.5 API java 中文参考手册》,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
, 客户端
, tcp
, socket
, 接口
, nio
服务端
java socket nio 编程、java nio socket 实例、java tcp socket编程、tcp socket编程、linux tcp socket编程,以便于您获取更多的相关知识。

时间: 2024-07-28 16:58:31

Java Socket编程实例(四)- NIO TCP实践_java的相关文章

Java Socket编程实现简单的问候服务_java

本文实例讲解了Java Socket编程实现简单的问候服务的详细代码,供大家参考,具体内容如下 服务器端: 实现一个最简单的Hello服务,打印输出客户端IP地址到控制台,对任何连接的客户端都会发送一串字符(Hello, Java Socket)然后关闭与客户端连接.等待下一个客户端的连接请求到来. 客户端: 实现一个最简单的Socket连接到Hello服务器端,接受服务器端发送过来的字节数据打印并输出内容到控制台. 关键技巧: 由于JAVA中提供非常多的输入与输出流API,导致很多初学者接触J

Java Socket编程实例(五)- NIO UDP实践_java

一.回传协议接口和UDP方式实现: 1.接口: import java.nio.channels.SelectionKey; import java.io.IOException; public interface EchoProtocol { void handleAccept(SelectionKey key) throws IOException; void handleRead(SelectionKey key) throws IOException; void handleWrite(

Java Socket编程实例(一)- TCP基本使用_java

一.服务端代码: import java.net.*; // for Socket, ServerSocket, and InetAddress import java.io.*; // for IOException and Input/OutputStream public class TCPEchoServer { private static final int BUFSIZE = 32; // Size of receive buffer public static void main

java socket编程实例代码讲解_java

1.所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 操作java socket时用到的最多的三个方法为: accept():主要用于服务器端产生"阻塞",等待客户端的链接请求,并且返回一个客户端的Socket实例: getInputStream():方法主要用来获得网络连接输入,同时返回一个InputStream对象实例: getOutputStream

Java Socket编程实例(二)- UDP基本使用_java

一.服务端代码: import java.io.*; import java.net.*; public class UDPEchoServer { private static final int ECHOMAX = 255; // Maximum size of echo datagram public static void main(String[] args) throws IOException { int servPort = 5500; // Server port Datagr

Java Socket编程(四)

编程 重复和并发服务器 所有的这些调用都可以掷出一个UnknownHostException违例.如果一台计算机没有连接上DNS服务器,或者主机的确没有找到,这个违例就会被掷出.如果一台计算机没有一个激活的TCP/IP配置,getLocalHost()也为失败并掷出一个违例. 一旦一个地址被确定了,数据报就可以被送出了.下面的程序传输了一个字符串给目的socket: String toSend = "This is the data to send!"); byte[] sendbuf

Java Socket编程(四) 重复和并发服务器_Java编程

文章来源:aspcn 作者:孙雯 重复和并发服务器 这个应用程序被当作一个重复的服务器.因为它只有在处理完一个进程以后才会接受另一个连接.更多的复杂服务器是并发的.它为每一个请求分配一个线程,而不是来一个处理一个.所以看起来它在同时处理多人请求.所有的商业的服务器都是并发的服务器. Java数据报类 不像面向连接的类,数据报的客户端和服务器端的类在表面上是一样的.下面的程序建立了一个客户和服务器商的数据报sockets: DatagramSocket serverSocket = new Dat

java socket编程如何测量文件传输速度?

问题描述 java socket编程如何测量文件传输速度? 作业需要,分别写了一个基于tcp和udp的传输文件的程序,想测试两者同时传输时各自的传输速度 请问有什么方法可以实现? 解决方案 发送时发送一个记录客户端时间的包,同时记录好这个包的大小 .服务端在收到这个包后,拆包.取出客户端时间和自己的服务端时间时行差值计算. 然后,接下去就好做了 解决方案二: 类似问题的,http://bbs.csdn.net/topics/391036058,建议参考一下看看 解决方案三: 在发送数据的时候获取

java socket 编程遇到的问题

问题描述 最近初步学习java socket 编程的时候遇到一个问题就是,当客户端向服务端发送数据时,会出现不能输入也不能,程序卡住的现象,尤其是中文,最多输入两行,控制台就不能再输入数据(客户端输入是用system.in来从键盘获取数据).英文字符还好一些,但也会出现此种状况,百思不得其解!代码如下:server:package dragon.socket;import java.io.BufferedReader;import java.io.IOException;import java.