`
pan_java
  • 浏览: 280052 次
  • 性别: 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();
			}
		}

	}
}
分享到:
评论

相关推荐

    基于底层TCP/IP UDP通讯的函数库

    基于TCP/IP UDP Socket通讯的函数库,包括客户端及服务端的链接控制,多线程机制,通讯包的格式可以由用户自由设定。非阻塞式和阻塞式收发数据。接受发送数据保存在一定的队列中,起到缓存机制。

    VC TCP/IP客户服务端整合一体源码

    工业级远程以太网通信测试使用...程序包括TCPSocket封装类,阻塞式,多线程、事件消息驱动,及时快速状态显示,可支持300用户!类有2、10、16进制转换和通信报文解析和产生等功能。适合有一定通讯基础人使用。绝对超值!

    《对话框》之《SOCKET类的设计和实现》

    Socket接口是网络编程(通常是TCP/IP协议,也可以是其他协议)的API。最早的Socket接口是Berkeley接口,在Unxi操作系统中实现。WinSock也是一个基于Socket模型的API,在Microsoft Windows操作系统类中使用。它在...

    精通Windows Sockets网络开发:基于Visual C++实现-带源码

    1.2.2tcp/ip是否工作正常 1.2.3系统与网络适配器间的通信 1.2.4默认网关 1.2.5ping其他计算机ip地址 1.3创建应用程序 1.3.1控制台程序 1.3.2mfc应用程序 1.4调试两个应用程序 1.4.1启动两个工程 1.4.2将一个工程加入...

    TCPSocket编程.zip

    Socket简介 Windows Socket Linux Socket Socket常用函数介绍 TCP/IP网络程序框架与实例 通信方式 阻塞 非阻塞

    Java TCPIP Socket编程 源码

    现在TCP/IP协议族中的主要socket类型为流套接字(使用TCP协议)和数据报套接字(使用UDP协议)。 TCP协议提供面向连接的服务,通过它建立的是可靠地连接。Java为TCP协议提供了两个类:Socket类和ServerSocket类。一...

    TCPSocket编程

    Socket简介 Windows Socket Linux Socket Socket常用函数介绍 TCP/IP网络程序框架与实例 通信方式 阻塞 非阻塞

    Java CP/IP Socket编程

    JAVA SOCKET 编程的经典之书,(中文版)里面的代码可直接复制使用! 目录: 第1章简介..........3 1.1 计算机网络,分组报文和协议..........3 1.2 关于地址..........6 1.3 关于名字..........8 1.4 客户端...

    Python做的TCP聊天查询,用的GUI窗体实现

    socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。 本...

    C++开发基于TCPsocket实现的web服务器源码.zip

    服务器实现及其功能: 1、读取配置文件,为服务器自身设置IP地址、端口号、阻塞模式、最大连接数目并设置提取文件的根目录; 2、根据上述IP地址、端口号通过socket、bind函数建立套接字,并利用listen对套接字进行...

    基于java实现Socket套接字一对一聊天系统源码+项目说明.zip

    Socket,又称套接字,在TCP/IP协议分层架构中,属应用层和传输层之间的一个抽象层(也有的说是属于传输层),它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信。 ![在这里插入图片描述...

    CocoaAsyncSocket-7.1

    AsyncSocket是封装了CFSocket和CFSteam的TCP/IP socket网络库。它提供了异步操作,本地cocoa类的基于delegate的完整支持。主要有以下特性: 队列的非阻塞的读和写,而且可选超时。你可以调用它读取和写入,它会当...

    socket编程 linux socket

    socket编程 linux socket 阻塞 tcp udp ip

    cocoaasyncsocket

    AsyncSocket是封装了CFSocket和CFSteam的TCP/IP socket网络库。它提供了异步操作,本地cocoa类的基于delegate的完整支持。主要有以下特性: 队列的非阻塞的读和写,而且可选超时。你可以调用它读取和写入,它会当...

    CocoaAsyncSocket

    AsyncSocket是封装了CFSocket和CFSteam的TCP/IP socket网络库。它提供了异步操作,本地cocoa类的基于delegate的完整支持。主要有以下特性: 队列的非阻塞的读和写,而且可选超时。你可以调用它读取和写入,它会当...

    Linux高性能服务器编程

    5.1.4 IP地址转换函数 5.2 创建socket 5.3 命名socket 5.4 监听socket 5.5 接受连接 5.6 发起连接 5.7 关闭连接 5.8 数据读写 5.8.1 TCP数据读写 5.8.2 UDP数据读写 5.8.3 通用数据读写函数 5.9 带外...

    Windows Sockets网络编程 可能是最清晰版本(Windows Sockets 2规范解释小组负责人亲自执笔。)总共4个包,part1

    借助于此框架,读者可理解WinSock的具体细节,包括WindowsSockets概述、OSI网络参考模型、TCP/IP协议簇中的协议和可用的服务、WinSock网络应用程序的框架及其工作机制、WinSock的三种操作模式、socket通信机制等;...

    Windows Sockets网络编程 总计4个包,part2

    借助于此框架,读者可理解WinSock的具体细节,包括WindowsSockets概述、OSI网络参考模型、TCP/IP协议簇中的协议和可用的服务、WinSock网络应用程序的框架及其工作机制、WinSock的三种操作模式、socket通信机制等;...

    python网络编程

    ⽹络通信概述 tcp/ip简介 端⼝ ip地址 ⼦⽹掩码 socket简介 udp介绍 udp⽹络程序-发送数据 udp⽹络程序-发送、接收数据 udp⽹络程序-端⼝问题 udp绑定信息 udp⽹络通信过程 udp应⽤:echo服务器 udp应⽤:聊天室 udp...

    Linux网络编程超级详细笔记

    Socket编程:Socket是用于实现网络通信的编程接口,支持基于TCP/IP协议的传输,包括TCP和UDP。在Linux下,使用Socket编程可以实现网络通信,包括客户端和服务器端。 IP地址和端口:IP地址是用于标识网络上的设备的...

Global site tag (gtag.js) - Google Analytics