package com.test.example.chat;
import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.*;
import java.nio.charset.*;
import java.util.*;
public class ChatServer {
public static void main(String[] args) {
// 客户端列表
Hashtable<String, SocketChannel> clientlist = new Hashtable<String, SocketChannel>();
Selector selector = null;
ServerSocketChannel server = null;
try {
// 创建一个Selector
selector = Selector.open();
// 创建Socket并注册
server = ServerSocketChannel.open();
server.configureBlocking(false);
server.register(selector, SelectionKey.OP_ACCEPT);
// 启动端口监听
InetSocketAddress ip = new InetSocketAddress(12345);
server.socket().bind(ip) ;
// 监听事件
while (true) {
// 监听事件
selector.select();
// 事件来源列表
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
// 删除当前事件
it.remove();
// 判断事件类型
if (key.isAcceptable()) {
// 连接事件
ServerSocketChannel server2 = (ServerSocketChannel) key
.channel();
SocketChannel channel = server2.accept();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
System.out.println("客户端连接:"
+ channel.socket().getInetAddress()
.getHostName() + ":"
+ channel.socket().getPort());
} else if (key.isReadable()) {
// 读取数据事件
SocketChannel channel = (SocketChannel) key.channel();
// 读取数据
CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
ByteBuffer buffer = ByteBuffer.allocate(50);
channel.read(buffer);
buffer.flip();
String msg = decoder.decode(buffer).toString();
System.out.println("收到:" + msg);
if (msg.startsWith("username=")) {
String username = msg.replaceAll("username=", "");
clientlist.put(username, channel);
} else {
// 转发消息给客户端
String[] arr = msg.split(":");
if (arr.length == 3) {
String from = arr[0];//发送者
String to = arr[1];//接收者
String content = arr[2];//发送内容
if (clientlist.containsKey(to)) {
CharsetEncoder encoder = Charset.forName(
"UTF-8").newEncoder();
// 给接收者发送消息
clientlist.get(to).write(
encoder.encode(CharBuffer.wrap(from
+ ":" + content)));
}
}
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭
try {
selector.close();
server.close();
} catch (IOException e) {
}
}
}
}
package com.test.example.chat;
import java.io.*;
public class ChatClient {
public static void main(String[] args) {
String username = args[0];
ClientThread client = new ClientThread(username);
client.start();
// 输入输出流
BufferedReader sin = new BufferedReader(
new InputStreamReader(System.in));
try {
// 循环读取键盘输入
String readline;
while ((readline = sin.readLine()) != null) {
if (readline.equals("bye")) {
client.close();
System.exit(0);
}
client.send(username + ":" + readline);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.test.example.chat;
import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.*;
import java.nio.charset.*;
import java.util.*;
public class ClientThread extends Thread {
private CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
private CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
private Selector selector = null;
private SocketChannel socket = null;
private SelectionKey clientKey = null;
private String username;
// 启动客户端
public ClientThread(String username) {
try {
// 创建一个Selector
selector = Selector.open();
// 创建Socket并注册
socket = SocketChannel.open();
socket.configureBlocking(false);
clientKey = socket.register(selector, SelectionKey.OP_CONNECT);
// 连接到远程地址
InetSocketAddress ip = new InetSocketAddress("localhost", 12345);
socket.connect(ip);
this.username = username;
} catch (IOException e) {
e.printStackTrace();
}
}
// 读取事件
public void run() {
try {
// 监听事件
while (true) {
// 监听事件
selector.select();
// 事件来源列表
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
// 删除当前事件
it.remove();
// 判断事件类型
if (key.isConnectable()) {
// 连接事件
SocketChannel channel = (SocketChannel) key.channel();
if (channel.isConnectionPending())
channel.finishConnect();
channel.register(selector, SelectionKey.OP_READ);
System.out.println("连接服务器端成功!");
// 发送用户名
send("username=" + this.username);
} else if (key.isReadable()) {
// 读取数据事件
SocketChannel channel = (SocketChannel) key.channel();
// 读取数据
ByteBuffer buffer = ByteBuffer.allocate(50);
channel.read(buffer);
buffer.flip();
String msg = decoder.decode(buffer).toString();
System.out.println("收到:" + msg);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭
try {
selector.close();
socket.close();
} catch (IOException e) {
}
}
}
// 发送消息
public void send(String msg) {
try {
SocketChannel client = (SocketChannel) clientKey.channel();
client.write(encoder.encode(CharBuffer.wrap(msg)));
} catch (Exception e) {
e.printStackTrace();
}
}
// 关闭客户端
public void close() {
try {
selector.close();
socket.close();
} catch (IOException e) {
}
}
}
分享到:
相关推荐
- 多线程Client/Server程序可能涉及工厂模式(用于创建线程)、单例模式(用于服务器实例)、观察者模式(用于广播消息)等设计模式。 通过上述知识点,我们可以理解`ChatServer.java` 和 `ChatClient.java` 文件...
NioSocket是一个基于Java NIO(非阻塞I/O)技术实现的网络通信框架,它包含服务器端(Server)和客户端(Client)两部分。在Java编程中,NIO(New Input/Output)提供了一种不同于传统IO模型的I/O操作方式,其核心...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,相对于传统的BIO( Blocking I/O)模型,NIO在处理高并发、大数据量的网络应用时表现出更高的效率和...
Mina Client则是客户端部分,用于连接到Mina Server并发送请求。客户端同样基于NIO,可以实现非阻塞的I/O操作,这意味着即使在等待服务器响应时,客户端也可以执行其他任务,从而提高整体性能。在设置Mina Client时...
而"TestNIO_client"和"TestNIO_server"这两个文件名很可能分别对应的是NIO客户端和服务器的源代码文件,用户可以通过这些源代码了解如何在J2ME和Java NIO之间建立有效的通信。 在实际应用中,J2ME客户端可能使用...
- Client类(可能在C++代码中):实现客户端的逻辑,包括连接服务器、发送消息和接收消息。 在实际开发中,Java NIO的使用需要对多线程、网络编程以及NIO API有深入的理解。通过这种方式构建的系统可以高效地处理...
【Java 多线程Client/Server聊天程序:ServerQQ详解】 在Java编程中,多线程技术是构建高效并发应用程序的基础。在这个名为"ServerQQ"的项目中,开发者利用Java的多线程特性实现了客户端(Client)与服务器端...
在这个“server/client 多用户通信”项目中,我们将深入探讨如何使用Socket来构建异步式、消息驱动的系统,以支持多个客户端同时与服务器进行交互。 首先,让我们从基础概念开始。`ServerSocket`是Java提供的一个类...
public class NIOClient { public static void main(String[] args) { try (SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("localhost", 8888))) { socketChannel.configureBlocking...
`NIOServer.java`和`NIOClient.java`这两个文件很可能是用于演示Java NIO服务器端和客户端的基本操作。下面将详细介绍Java NIO的主要组件和工作原理,并结合这两个文件名推测它们可能包含的内容。 1. **Selector...
在`NioClient.java`中,客户端同样使用NIO进行通信。客户端首先创建一个`SocketChannel`,然后向服务器的`ServerSocketChannel`发起连接请求。接着,客户端可以设置自己的`Charset`来确保数据在传输过程中不出现乱码...
在IT行业中,客户端-服务器(Client-Server)应用程序是一种常见的架构模式,特别是在Java开发中。这个"client_server_app.rar_APP_in"的标题和描述暗示了我们正在探讨一个使用Java实现的客户端-服务器应用。让我们...
课程中的视频文件"Java基础第27天-04.NIO-Selector-Server-Client.avi"很可能包含了实际的代码演示和讲解,帮助学习者直观理解Selector的工作原理以及如何在Java中实现NIO服务器和客户端的交互。通过观看视频和动手...
本示例将详细解析如何使用Java的非阻塞I/O(NIO)实现Socket通信,包括客户端发送消息和服务器端接收消息的过程。 首先,理解NIO(Non-blocking Input/Output)的概念至关重要。NIO与传统的IO模型不同,它提供了对...
在IT行业中,网络通信是至关重要的一个领域,而客户端-服务器模型(Client-Server Model)则是其中的基础架构。本文将详细解析"client-server-socket.rar_Server"中的核心知识点,包括服务器端如何为客户端提供数学...
总的来说,Netty 4.0的Server与Client通讯涉及到NIO、事件驱动模型、线程模型、Channel、ChannelHandler、ChannelPipeline、ByteBuf等多个核心概念。通过理解和掌握这些知识点,我们可以构建出高效、可靠的网络应用...
public class NIOServer { public static void main(String[] args) throws IOException { ServerSocketChannel serverSocket = ServerSocketChannel.open(); serverSocket.bind(new InetSocketAddress(8080)); ...
在IT领域,客户端-服务器(Client-Server)架构是一种常见的应用程序设计模式,它涉及两个主要组件:客户端和服务器。在这个"Client-Server-App.zip_between_client"中,我们看到的是一段实现客户端与服务器间握手...
BIO 的工作机制是基于 Client/Server 模型的,服务器端负责绑定 IP 地址,启动监听端口;客户端负责发起连接操作。连接成功后,双方通过网络套接字(Socket)进行通信。在 BIO 模式下,客户端和服务端是完全同步的,...
而在 "netty-http-client" 文件中,包含了一个简单的 HTTP 客户端示例,演示了如何向服务器发送请求并接收响应。 总的来说,Netty 提供了强大而灵活的工具来构建 HTTP 客户端和服务器,无论是对于学习网络编程,...