EchoServer采用阻塞模式,用线程池中的工作线程处理每个客户连接。
EchoClient也采用阻塞模式,单线程。
package com.test.socket.nio.blocked;
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.InetSocketAddress;
import java.net.Socket;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 使用阻塞模式的SocketChannel,ServerSocketChannel.
* 为了同时连接多个客户端,需要使用多线程
*/
public class EchoServer {
private int port = 8000;
private ServerSocketChannel serverSocketChannel = null;
private ExecutorService executorService;
private static final int POOL_MULTIPLE = 4;
public EchoServer() throws IOException {
executorService = Executors.newFixedThreadPool(Runtime.getRuntime()
.availableProcessors() * POOL_MULTIPLE);
//创建一个serverSocketChannel对象
serverSocketChannel = ServerSocketChannel.open();
//使得在同一个主机上关闭了服务器程序,紧接着再启动该服务器程序时,
//可以顺利绑定相同的端口
serverSocketChannel.socket().setReuseAddress(true);
//与一个本地端口绑定
serverSocketChannel.socket().bind(new InetSocketAddress(port));
System.out.println("服务器启动...");
}
public void service(){
while(true){
SocketChannel socketChannel = null;
try{
socketChannel = serverSocketChannel.accept();
//将每个客户连接都使用线程池中的一个线程来处理
executorService.execute(new Handler(socketChannel));
}catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
new EchoServer().service();
}
}
class Handler implements Runnable{
private SocketChannel socketChannel;
public Handler(SocketChannel socketChannel) {
this.socketChannel = socketChannel;
}
public void run() {
handler(socketChannel);
}
public void handler(SocketChannel socketChannel){
try{
Socket socket = socketChannel.socket();
System.out.println("接收到客户连接,来自:"+socket.getInetAddress()+":"+socket.getPort());
BufferedReader br = getReader(socket);
PrintWriter pw = getWriter(socket);
String msg = null;
while((msg = br.readLine()) != null){
System.out.println(msg);
pw.println(echo(msg));
if(msg.equals("bye")){
break;
}
}
}catch (Exception e) {
e.printStackTrace();
}finally{
try{
if(socketChannel != null){
socketChannel.close();
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
private PrintWriter getWriter(Socket socket)throws IOException{
OutputStream socketOut = socket.getOutputStream();
return new PrintWriter(socketOut,true);
}
private BufferedReader getReader(Socket socket)throws IOException{
InputStream socketIn = socket.getInputStream();
return new BufferedReader(new InputStreamReader(socketIn));
}
public String echo(String msg){
return "echo:"+msg;
}
}
package com.test.socket.nio.blocked;
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.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.channels.SocketChannel;
public class EchoClient {
private SocketChannel socketChannel = null;
public EchoClient() throws IOException {
socketChannel = SocketChannel.open();
InetAddress ia = InetAddress.getLocalHost();
InetSocketAddress isa = new InetSocketAddress(ia,8000);
socketChannel.connect(isa);
System.out.println("与服务器的连接建立成功");
}
public static void main(String[] args) throws IOException {
new EchoClient().talk();
}
public void talk()throws IOException{
try{
BufferedReader br = getReader(socketChannel.socket());
PrintWriter pw = getWriter(socketChannel.socket());
BufferedReader localReader = new BufferedReader(new InputStreamReader(System.in));
String msg = null;
while((msg = localReader.readLine()) != null){
pw.println(msg);
System.out.println(br.readLine());//接收服务器返回的消息
//当输出的字符串为"bye"时停止
if(msg.equals("bye")){
break;
}
}
}catch (IOException e) {
e.printStackTrace();
}finally{
try{
socketChannel.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}
private PrintWriter getWriter(Socket socket)throws IOException{
OutputStream socketOut = socket.getOutputStream();
return new PrintWriter(socketOut,true);
}
private BufferedReader getReader(Socket socket)throws IOException{
InputStream socketIn = socket.getInputStream();
return new BufferedReader(new InputStreamReader(socketIn));
}
}
分享到:
相关推荐
我们将会分析`EchoServer.java`、`EchoClient.java`和`SocketUtils.java`这三个文件中的关键知识点。 首先,让我们从`EchoServer.java`开始。这是一个典型的回显服务器,它的主要任务是接收客户端发送的数据并...
本示例通过两个类——EchoServer和EchoClient,展示了如何使用NIO实现基于TCP/IP协议的网络通信。 首先,我们来看`EchoServer`。这个类通常扮演服务端的角色,监听指定端口并接收客户端连接。在Java NIO中,服务器...
5. **性能优化**:DotNetty通过使用异步非阻塞I/O模型(NIO),实现了高度并发和低延迟。此外,它的内存管理机制(如ByteBuf)减少了不必要的对象创建和复制,提高了效率。开发者可以通过理解这些机制,进一步优化...
- EchoServer和EchoClient类是核心类,负责服务器端和客户端的主要逻辑。 - 使用Java NIO的`ServerSocketChannel`和`SocketChannel`来处理服务器和客户端的连接,`Selector`和`SelectionKey`用于实现非阻塞特性,...
Java进程间的网络通信是计算机编程中的一个重要概念,它允许运行在不同或相同计算机上的多个...通过学习和理解EchoServer和EchoClient的实现,我们可以深入理解网络通信的基本原理,并在此基础上构建更复杂的网络应用。
在实际应用中,你可以进一步扩展它,例如添加错误处理、多线程支持,或者使用NIO(非阻塞I/O)以提高性能。此外,由于UDP的特性,你可能还需要考虑数据包丢失和乱序的问题,尤其是在构建可靠通信系统时。
Netty还提供了很多开箱即用的组件,如EchoServer和EchoClient。EchoServer是一个回显服务器,它将收到的每个消息直接返回给发送方,用于测试网络连接和消息的完整性。EchoClient则是一个回显客户端,它向服务器发送...
Java Netty 是一个高性能、异步事件驱动的网络应用程序...通过阅读和理解"JavaNetty.rar"中的代码,特别是EchoClient和EchoServer的实现,你可以深入学习Netty的工作原理,以及如何利用它来构建高效的消息通信系统。
首先,我们来看`EchoServer.java`。Echo服务器是一种简单的网络服务,它接收到客户端发送的数据后,原样返回。在Java中,我们可以使用`ServerSocket`类创建服务器端的套接字,并监听特定端口。当有客户端连接时,`...
1. **EchoClient.java** 和 **EchoServer.java**:这两个文件可能涉及到TCP/IP协议中的回显服务。回显服务是一种常见的网络通信示例,其中客户端发送数据到服务器,服务器接收到数据后无修改地将其返回给客户端。在...
- **EchoClient**:对应于 EchoServer,是一个客户端,向服务器发送数据并接收回显。 - **ProtobufCodec**:展示了如何使用 Google 的 Protocol Buffers(protobuf)进行序列化和反序列化,以便在 Netty 中传输结构...
可能涉及的文件包括配置文件(如`applicationContext.xml`),MINA的服务类(如`EchoServer`),客户端类(如`EchoClient`),以及相关的过滤器和协议处理器。 6. **配置示例**:在`applicationContext.xml`中,...