`

Java Socket学习---nio实现阻塞多线程通信

阅读更多

本次使用nio实现socket客户端和服务端的通信,并且在服务端为每一个新建的连接创建一个线程负责维持和客户端的通信。

使用nio实现的阻塞的socket与普通方式实现的通信相比较仅仅是实现方式不同,其实质的运行原理是一样的。在此仅仅作为一个nio的入门示例。

nio来做socket主要用到两个类ServerSocketChannel(服务器socket)和SocketChannel(客户端socket)。

 

Channel的简单介绍:ServerSocketChannel和SocketChannel。Java NIO的通道类似流,但又有些不同:

 1. 既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。

 2. 通道可以异步地读写。

 3. 通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。

 

Server端程序:

package com.henushang.socket.chapter4nio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.henushang.socket.util.SocketUtils;

public class EchoServer {

	private int port = 8000;
	private ServerSocketChannel serverSocketChannel;
	private ExecutorService executorService;
	private final int POOL_SIZE = 4;

	public EchoServer() throws Exception {
		executorService = Executors.newFixedThreadPool(Runtime.getRuntime()
				.availableProcessors() * POOL_SIZE);
		serverSocketChannel = ServerSocketChannel.open();
		serverSocketChannel.socket().bind(new InetSocketAddress(port));
		System.out.println("等待连接...");
	}

	public void service() {
		SocketChannel socketChannel = null;
		while (true) {
			try {
				System.out.println("waitting for connect...");
				socketChannel = serverSocketChannel.accept();
				System.out.println("get the connect...");
				Thread.sleep(500);
				executorService.execute(new Handler(socketChannel));
			} catch (IOException e) {
				e.printStackTrace();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

		}
	}

	public static void main(String[] args) throws Exception {
		new EchoServer().service();
	}

	class Handler implements Runnable {
		private SocketChannel socketChannel = null;

		public Handler(SocketChannel socketChannel) {
			this.socketChannel = socketChannel;
		}

		@Override
		public void run() {
			handler(socketChannel);
		}

		private void handler(SocketChannel socketChannel) {
			System.out.println("new connection accepted:"
					+ socketChannel.socket().getInetAddress() + ":"
					+ socketChannel.socket().getPort());
			try {
				BufferedReader reader = SocketUtils
						.getReader(this.socketChannel);
				PrintWriter pw = SocketUtils.getWriter(this.socketChannel);
				String msg = null;
				while (true) {
					if ((msg = reader.readLine()) != null) {
						try {
							Thread.sleep(20000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						System.out.println(msg);
//						pw.write(SocketUtils.echo(msg)+"\r\n");
						pw.println(SocketUtils.echo(msg));
						pw.flush();
						if ("bye".equals(msg)) {
							break;
						}
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				SocketUtils.close(socketChannel);
			}
		}
	}
}

 

Client端程序:

package com.henushang.socket.chapter4nio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;

import com.henushang.socket.util.SocketUtils;

public class EchoClient {
	
	private SocketChannel socketChannel;
	private int port = 8000;
	
	public EchoClient() throws Exception {
		socketChannel = SocketChannel.open();
		InetAddress inetAddress = InetAddress.getLocalHost();
		InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, port);
		socketChannel.connect(inetSocketAddress);
		System.out.println("准备连接服务器");
	}
	
	public static void main(String[] args) throws Exception {
		new EchoClient().talk();
	}
	
	public void talk() {
		try {
			BufferedReader reader = SocketUtils.getReader(socketChannel.socket());
			PrintWriter pw = SocketUtils.getWriter(socketChannel.socket());
			BufferedReader localreaderReader = new BufferedReader(new InputStreamReader(System.in));
			String msg = null;
			while ((msg = localreaderReader.readLine()) != null) {
				System.out.println(msg);
				pw.println(msg);
				pw.flush();
				System.out.println(reader.readLine());
				if ("bye".equals(msg)) {
					break;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			SocketUtils.close(socketChannel);
		}
		
	}
}

 

 

SocketUtils:(与以前的一样)

package com.henushang.socket.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.nio.channels.SocketChannel;

public class SocketUtils {
	
	public static PrintWriter getWriter(Socket socket) throws IOException {
		OutputStream os = socket.getOutputStream();
		return new PrintWriter(os);
	}
	
	public static PrintWriter getWriter(SocketChannel socketChannel) throws IOException {
		return getWriter(socketChannel.socket());
	}
	
	public static BufferedReader getReader(Socket socket) throws IOException{
		InputStream is = socket.getInputStream();
		return new BufferedReader(new InputStreamReader(is, "UTF-8"));
	}
	
	public static BufferedReader getReader(SocketChannel socketChannel) throws IOException{
		return getReader(socketChannel.socket());
	}
	
	public static void close(Socket socket) {
		try {
			if (socket != null) {
				socket.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void close(SocketChannel socketChannel) {
		try {
			if (socketChannel != null) {
				socketChannel.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static String echo(String msg) {
		return "echo:" + msg;
	}
}

 

 

 

 

0
1
分享到:
评论

相关推荐

    Java Socket学习---单线程阻塞

    为了提高效率,可以采用多线程或者非阻塞I/O(如NIO,Java的新I/O库)来改进。但是,对于初学者来说,理解单线程阻塞模型是学习网络编程的基础,有助于深入理解Socket通信的工作原理。 此外,源码分析可以帮助我们...

    JavaSocket学习---NIO实现非阻塞的通信

    总结来说,Java NIO为Socket通信提供了一种非阻塞的解决方案,通过`Selector`和`Channel`的组合,可以在单线程中处理多个连接,极大地提高了服务器的并发性能。`EchoServerNoBlock.java`、`EchoClient.java`和`...

    java nio 实现socket

    在探讨如何使用Java NIO实现Socket通信之前,我们需要先理解NIO(Non-blocking I/O,非阻塞I/O)与传统阻塞I/O之间的区别。 **传统阻塞I/O模型**:在传统的Java IO编程中,当我们调用`read()`或`write()`方法时,...

    java socket 多线程 简易实现

    Java Socket多线程简易实现是网络编程中的一个基础概念,主要应用于客户端与服务器之间的通信。在Java中,Socket是基于TCP协议的,提供了一种可靠的、面向连接的字节流通信方式。多线程则是Java并发编程的重要特性,...

    android-socket-nio-master.zip

    "android-socket-nio-master.zip" 是一个关于Android中使用Socket结合NIO实现高效通信的项目,其目标是提高Socket通信的性能和处理大量并发连接的能力。 NIO(非阻塞I/O)是Java提供的一个替代传统I/O的API,主要...

    基于Java的源码-Java Socket通信实现.zip

    Java Socket通信实现是一种在两台计算机之间...以上是对"基于Java的源码-Java Socket通信实现.zip"中涉及的知识点的详细说明。通过学习和实践这些概念,开发者可以更好地理解和掌握Java网络编程,实现各种网络应用。

    java Socket通信实现

    Java Socket通信实现是Java网络编程中的重要组成部分,它允许两台计算机通过TCP/IP协议进行双向通信。在Java中,Socket提供了低级别的、基于连接的、面向数据流的通信API,可以用于实现客户端-服务器架构的应用程序...

    Nio非阻塞socket通信demo

    在这个“Nio非阻塞socket通信demo”中,我们可以深入理解NIO在Socket通信中的应用。 1. **Java NIO基础** - **通道(Channels)**:NIO的核心概念之一,通道是数据读写的目标或来源,如文件通道、套接字通道等。...

    Java-NIO-Netty框架学习

    Java NIO (Non-blocking Input/Output) 是Java平台中用于高效处理I/O操作的一种机制,它与传统的IO模型( Blocking I/O)相比,提供了更高级别的抽象,允许应用程序以非阻塞的方式读写数据,提高了并发性能。...

    java socket 学习资料

    Java Socket是Java编程语言中用于实现网络通信的核心API,它基于TCP/IP协议栈,提供了低级别的网络连接功能。Socket在Java中被广泛用于构建客户端-服务器应用,例如创建Web服务器、聊天应用程序、文件传输等。以下是...

    使用NIO实现非阻塞socket通信

    在Java编程中,NIO(New ...总之,本项目通过Java NIO实现了非阻塞socket通信,有效地解决了高并发场景下的连接管理问题,提高了系统效率。对于学习和理解NIO以及如何构建基于NIO的网络应用,这是一个很好的实践案例。

    Java Socket实例(服务器多线程)

    Java Socket 实例是Java网络编程中的重要组成部分,用于实现客户端与服务器之间的通信。在这个实例中,我们关注的是服务器端的多线程应用,这在处理多个并发连接时尤其有用。多线程允许服务器同时处理多个客户端请求...

    nio.rar_NIO_NIO-socket_java nio_java 实例_java.nio

    NIO套接字是Java NIO库中用于网络通信的关键组件,它们允许程序非阻塞地读写数据,这对于开发高性能的服务器应用尤其有用。 描述中的“java nio 编程一个实例子.服务端程序”提示我们,这个实例是一个服务器端的...

    Java TCP-IP Socket编程-卡尔弗特.pdf

    Java TCP/IP Socket编程是网络通信领域中的核心技术,尤其在Java编程中,Socket是实现客户端与服务器之间通信的基础。本资料“Java TCP-IP Socket编程-卡尔弗特.pdf”旨在深入探讨如何利用Java语言进行TCP/IP套接字...

    Java NIO Socket基本

    Java NIO(New Input/Output)是Java标准库中提供的一种I/O模型,与传统的 Blocking I/O(同步阻塞I/O)相对。NIO在Java 1.4版本引入,其设计目标是提供一种更高效、更灵活的I/O操作方式,特别适合处理大量并发连接...

    java多线程Socket简单实现

    Java多线程Socket实现是网络编程中的重要概念,它结合了Java的并发处理能力和Socket通信技术,用于构建高效、可扩展的网络应用。Socket在计算机网络中起到桥梁的作用,允许两个远程应用程序通过TCP/IP进行数据交换。...

    java socket tcpip多线程网络通信服务器客户端

    在“java socket tcpip多线程网络通信服务器客户端”这个主题中,我们将深入探讨如何使用Java Socket实现基于TCP/IP协议的多线程服务器和客户端通信。 TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的...

    nio.rar_Java socketA_java nio_java socket a

    标题中的“Java socketA_java nio_java socket a”可能是指使用Java NIO实现的Socket通信,这里的"A"可能是表示"Advanced"或"Alternative",意味着比传统的阻塞I/O模型更为高级或替代方案。 在Java Socket API中,...

Global site tag (gtag.js) - Google Analytics