`
pan_java
  • 浏览: 285558 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

TCP/IP 无阻塞 Socket

    博客分类:
  • java
阅读更多
package com.io;

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;

public class NewSocketServer {
	public static void main(String[] args) throws Exception {
		int port = 9527;
		//打开选择器
		Selector selector = Selector.open();
		//打开服务器套接字通道
		ServerSocketChannel ssc = ServerSocketChannel.open();
		//检索与此通道关联的服务器套接字。
		ServerSocket serverSocket = ssc.socket();
		//将 ServerSocket 绑定到特定地址(IP 地址和端口号)
		serverSocket.bind(new InetSocketAddress(port));
		System.out.println("Server listen on port: " + port);
		//调整此通道的阻塞模式。
		ssc.configureBlocking(false);
		//向给定的选择器注册此通道,返回一个选择键。SelectionKey.OP_ACCEPT--用于套接字接受操作的操作集位
		ssc.register(selector, SelectionKey.OP_ACCEPT);
		while (true) {
			//timeout - 如果为正,则在等待某个通道准备就绪时最多阻塞 timeout 毫秒;如果为零,则无限期地阻塞;必须为非负数 
			int nKeys = selector.select(1000);
			if (nKeys > 0) {
				for (SelectionKey key : selector.selectedKeys()) {
					//测试此键的通道是否已准备好接受新的套接字连接--如果此键的通道不支持套接字接受操作,则此方法始终返回 false。
					if (key.isAcceptable()) {
						ServerSocketChannel server = (ServerSocketChannel) key
								.channel();
						SocketChannel sc = server.accept();
						if (sc == null) {
							continue;
						}
						sc.configureBlocking(false);
						sc.register(selector, SelectionKey.OP_READ);
					} else if (key.isReadable()) {
						//分配一个新的字节缓冲区。
						ByteBuffer buffer = ByteBuffer.allocate(1024);
						SocketChannel sc = (SocketChannel) key.channel();
						int readBytes = 0;
						String message = null;
						try {
							int ret;
							try {
								while ((ret = sc.read(buffer)) > 0) {
									readBytes += ret;
								}
							} catch (Exception e) {
								readBytes = 0;
								// IGNORE
							} finally {
								//反转此缓冲区。首先对当前位置设置限制,然后将该位置设置为零
								buffer.flip();
							}
							if (readBytes > 0) {
								message = Charset.forName("UTF-8").decode(
										buffer).toString();
								buffer = null;
							}
						} finally {
							if (buffer != null) {
								buffer.clear();
							}
						}
						if (readBytes > 0) {
							System.out.println("Message from client: "
									+ message);
							if ("quit".equalsIgnoreCase(message.trim())) {
								sc.close();
								selector.close();
								System.out.println("Server has been shutdown!");
								System.exit(0);
							}
							String outMessage = "Server response:" + message;
							sc.write(Charset.forName("UTF-8")
									.encode(outMessage));
						}
					}
				}
				selector.selectedKeys().clear();
			}
		}
	}

}



package com.io;

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

public class NewSokectClient {
	public static void main(String[] args) throws Exception {
		int port = 9527;
		SocketChannel channel = SocketChannel.open();
		channel.configureBlocking(false);
		SocketAddress target = new InetSocketAddress("127.0.0.1", port);
		channel.connect(target);
		Selector selector = Selector.open();
		//用于套接字连接操作的操作集位。
		channel.register(selector, SelectionKey.OP_CONNECT);
		BufferedReader systemIn = new BufferedReader(new InputStreamReader(
				System.in));
		while (true) {
			if (channel.isConnected()) {
				String command = systemIn.readLine();
				channel.write(Charset.forName("UTF-8").encode(command));
				if (command == null || "quit".equalsIgnoreCase(command.trim())) {
					systemIn.close();
					channel.close();
					selector.close();
					System.out.println("Client quit!");
					System.exit(0);
				}
			}
			int nKeys = selector.select(1000);
			if (nKeys > 0) {
				for (SelectionKey key : selector.selectedKeys()) {
					if (key.isConnectable()) {
						SocketChannel sc = (SocketChannel) key.channel();
						sc.configureBlocking(false);
						sc.register(selector, SelectionKey.OP_READ);
						sc.finishConnect();
					} else if (key.isReadable()) {
						ByteBuffer buffer = ByteBuffer.allocate(1024);
						SocketChannel sc = (SocketChannel) key.channel();
						int readBytes = 0;
						try {
							int ret = 0;
							try {
								while ((ret = sc.read(buffer)) > 0) {
									readBytes += ret;
								}
							} finally {
								buffer.flip();
							}
							if (readBytes > 0) {
								System.out.println(Charset.forName("UTF-8")
										.decode(buffer).toString());
								buffer = null;
							}
						} finally {
							if (buffer != null) {
								buffer.clear();
							}
						}
					}
				}
				selector.selectedKeys().clear();
			}
		}

	}
}
分享到:
评论

相关推荐

    Java+TCP/IP+Socket编程++原书第2版.pdf

    TCP/IP(Transmission Control Protocol/Internet Protocol)协议栈是互联网通信的基础,而Socket是Java中实现TCP/IP通信的关键组件。本篇将深入探讨Java如何利用TCP/IP协议通过Socket进行网络编程。 TCP/IP协议族...

    C# TCP/IP通信小例子

    在C#中,我们通常使用System.Net命名空间下的Socket类来处理TCP/IP通信。 首先,让我们来看看服务端的实现。服务端需要监听特定的端口,等待客户端的连接请求。在C#中,可以创建一个Socket实例,并调用Bind方法绑定...

    基于TCP/IP的Socket多线程通信(服务器和客户端)

    在计算机网络编程中,TCP/IP协议族是连接网络应用的核心,而Socket是其接口,它提供了应用程序与网络通信的能力。本主题将深入探讨基于TCP/IP的Socket如何实现多线程通信,包括服务器端和客户端的设计与实现。 1. *...

    java TCP/IP socket 编程(原书第2版)pdf+源码

    Java TCP/IP Socket编程是Java网络通信的核心技术,广泛应用于服务器端和客户端之间的数据传输。这本书的第二版深入探讨了如何使用Java实现TCP/IP协议栈的socket接口,为开发者提供了全面的理论知识和实践指导。 ...

    TCP/IP通信c#例程

    通过实践这个C# TCP/IP通信的例子,你可以深入理解TCP/IP协议的工作原理,学习如何在C#中使用Socket类进行网络编程,这对于开发涉及网络通信的软件至关重要。无论是创建简单的聊天应用,还是复杂的分布式系统,TCP/...

    c++ TCP/IP服务器程序

    在C++中实现TCP/IP服务器,我们需要理解套接字(socket)编程,它是网络编程的核心。 1. **套接字创建**:在C++中,我们需要包含`<sys/socket.h>`和`<netinet/in.h>`等头文件,使用`socket()`函数创建一个套接字。...

    Socket Tcp/IP

    Socket和TCP/IP是网络通信中的基础概念,它们在互联网中起着至关重要的作用。Socket可以理解为应用程序与网络协议交互的接口,而TCP/IP则是一组通信协议的集合,包括了传输控制协议TCP和网际协议IP,是互联网通信的...

    TCP/IP实例精心制作

    "阻塞式TCP/IP"是指当一个进程在执行socket操作(如read或write)时,如果没有数据可读或没有足够的缓冲空间可写,该进程将会被阻塞,直到条件满足才会继续执行。这种方式简单易用,但效率较低,因为它可能导致进程...

    基于TCP/IP协议的网络编程

    在C++中进行TCP/IP编程,首先需要理解套接字(socket)的概念。套接字是进程间通信的一种接口,允许应用程序通过网络发送和接收数据。Windows API提供了丰富的函数用于创建、配置和操作套接字,如`socket()`用于创建...

    Java TCP/IP Socket编程

    Java TCP/IP Socket编程是Java网络编程中的重要组成部分,它提供了在网络间进行数据传输的基础机制。TCP(Transmission Control Protocol)和IP(Internet Protocol)是互联网上最基础的通信协议,而Socket则是TCP/...

    TCP/IP和SOCKET基本原理

    TCP/IP的核心协议包括IP、TCP、UDP等,其中IP负责数据在网络中的路由,TCP提供可靠的面向连接的数据传输,而UDP则是一种无连接的服务,注重效率但不保证数据可靠性。 TCP/IP的特点之一是其分层结构,使得不同层次的...

    TCP/IP Sockets in C

    除了基础内容外,《TCP/IP Sockets in C》还涉及了一些高级主题,如非阻塞I/O模型、异步I/O操作、信号处理等。这些主题对于进一步提高网络应用程序的性能至关重要。书中不仅对这些概念进行了详细的解释,还提供了...

    TCP/IP 通信客户端端

    TCP/IP通信客户端是网络编程中的一个关键组成部分,它允许设备或软件通过TCP/IP协议栈与服务器进行交互。在C++环境中开发TCP/IP客户端通常涉及到以下几个关键知识点: 1. **TCP/IP协议栈**:TCP(传输控制协议)和...

    基于TCP/IP的java聊天程序

    TCP提供连接导向服务,确保数据包按顺序到达且无丢失,而IP则负责将数据包路由到目标地址。在Java中,我们通常使用Socket类来处理TCP连接,它为应用程序提供了网络通信的能力。 在Java聊天程序中,`Socket` 和 `...

    TCP/IPsocket长连接

    在IT行业中,TCP/IP Socket长连接是网络编程中一个重要的概念,特别是在移动设备如安卓手机与服务器进行实时通信时。TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,而Socket是TCP/IP...

    C#服务器对多客服端TCP/IP多线程源码

    在IT领域,网络编程是构建分布式系统的基础,而TCP/IP协议是互联网通信的核心。本示例中的"C#服务器对多客服端TCP/IP多线程源码"是一个典型的网络编程应用场景,它展示了如何使用C#语言设计一个能同时处理多个客户端...

    TCP/IP编程

    Windows环境下的TCP/IP编程主要依赖于Windows Socket API,简称Winsock,它为开发者提供了与平台无关的接口来实现TCP通信。本篇文章将深入探讨Windows下利用Winsock进行TCP/IP编程的关键知识点。 首先,我们来看`...

    基于C#的TCP/IP协议客户端和服务器的代码实现

    在C#中,我们可以利用System.Net命名空间中的Socket类来操作TCP/IP协议。 创建TCP/IP服务器端: 1. 初始化Socket对象:首先,创建一个新的Socket实例,指定其地址族(通常为InterNetwork)、套接字类型(Stream...

    安卓版TCP/IP

    - 在Android中,Socket是实现TCP/IP通信的主要工具,它封装了底层的网络协议细节。 - 客户端创建Socket实例,指定服务器的IP地址和端口号,然后调用connect()方法建立连接。 - 服务器端通过ServerSocket监听特定...

Global site tag (gtag.js) - Google Analytics