java nio 服务端给客户端发消息
时间: 2024-01-01 09:02:32 浏览: 259
Java NIO(New I/O)是Java提供的一种新的输入/输出处理方式,它提供了非阻塞的I/O操作,使得网络编程更加高效和灵活。在Java NIO中,服务端可以通过Selector轮询所有已经准备好的连接,然后向客户端发送消息。
首先,服务端需要创建一个ServerSocketChannel,并将其注册到一个Selector中,然后监听指定的端口等待客户端连接。当有客户端连接时,服务端会通过ServerSocketChannel的accept方法获取SocketChannel,并将其注册到Selector中。
接下来,服务端可以通过Selector不断地轮询获取已经准备好的连接,并且向这些连接发送消息。这可以通过向对应的SocketChannel中写入数据实现。首先需要将消息转换成ByteBuffer,然后通过SocketChannel的write方法向客户端发送消息。
当消息发送完成后,可以通过SocketChannel的close方法关闭连接,并在Selector中取消对应的注册,释放资源。同时,服务端可以继续监听新的连接,或者做其他的处理。
总而言之,通过Java NIO的非阻塞I/O操作,服务端可以更加高效地处理多个连接,灵活地向客户端发送消息,并且可以优雅地处理连接的建立和释放。这使得服务端的网络编程更加稳健和高效。
相关问题
tcp nio服务端和客户端例子
以下是一个使用Java NIO实现的TCP Server和Client的示例代码:
TCP Server:
```java
import java.io.IOException;
import java.net.InetSocketAddress;
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.util.Iterator;
public class TCPServer {
private Selector selector;
private ByteBuffer buffer = ByteBuffer.allocate(1024);
public TCPServer(int port) throws IOException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(new InetSocketAddress(port));
selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("Server started on port " + port);
}
private void start() throws IOException {
while (true) {
selector.select();
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = keys.next();
keys.remove();
if (!key.isValid()) {
continue;
}
if (key.isAcceptable()) {
accept(key);
} else if (key.isReadable()) {
read(key);
} else if (key.isWritable()) {
write(key);
}
}
}
}
private void accept(SelectionKey key) throws IOException {
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
System.out.println("Accepted connection from " + socketChannel.getRemoteAddress());
}
private void read(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
buffer.clear();
int bytesRead = socketChannel.read(buffer);
if (bytesRead == -1) {
socketChannel.close();
System.out.println("Connection closed by " + socketChannel.getRemoteAddress());
return;
}
buffer.flip();
byte[] data = new byte[buffer.limit()];
buffer.get(data);
System.out.println("Received data from " + socketChannel.getRemoteAddress() + ": " + new String(data));
socketChannel.register(selector, SelectionKey.OP_WRITE, data);
}
private void write(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
byte[] data = (byte[]) key.attachment();
ByteBuffer byteBuffer = ByteBuffer.wrap(data);
socketChannel.write(byteBuffer);
System.out.println("Sent data to " + socketChannel.getRemoteAddress() + ": " + new String(data));
socketChannel.register(selector, SelectionKey.OP_READ);
}
public static void main(String[] args) throws IOException {
TCPServer server = new TCPServer(8080);
server.start();
}
}
```
TCP Client:
```java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
public class TCPClient {
private SocketChannel socketChannel;
private ByteBuffer buffer = ByteBuffer.allocate(1024);
public TCPClient(String host, int port) throws IOException {
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress(host, port));
}
private void start() throws IOException {
while (!socketChannel.finishConnect()) {
// Wait for connection to be established
}
System.out.println("Connected to server " + socketChannel.getRemoteAddress());
String message = "Hello, server!";
buffer.put(message.getBytes());
buffer.flip();
socketChannel.write(buffer);
System.out.println("Sent data to server: " + message);
buffer.clear();
int bytesRead = socketChannel.read(buffer);
if (bytesRead == -1) {
socketChannel.close();
System.out.println("Connection closed by server");
return;
}
buffer.flip();
byte[] data = new byte[buffer.limit()];
buffer.get(data);
System.out.println("Received data from server: " + new String(data));
socketChannel.close();
}
public static void main(String[] args) throws IOException {
TCPClient client = new TCPClient("localhost", 8080);
client.start();
}
}
```
用Nio实现java的客户端和服务端
使用 NIO(Non-blocking I/O)实现 Java 的客户端和服务端可以提高网络通信的效率。下面是一个简单的示例,演示了如何使用 NIO 实现一个简单的客户端和服务端。
首先是服务端代码:
```java
import java.io.IOException;
import java.net.InetSocketAddress;
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.util.Iterator;
import java.util.Set;
public class NioServer {
private static int BUF_SIZE = 1024;
private static int PORT = 8080;
private static int TIMEOUT = 3000;
public static void main(String[] args) {
selector();
}
public static void handleAccept(SelectionKey key) throws IOException {
ServerSocketChannel ssChannel = (ServerSocketChannel) key.channel();
SocketChannel sc = ssChannel.accept();
sc.configureBlocking(false);
sc.register(key.selector(), SelectionKey.OP_READ, ByteBuffer.allocateDirect(BUF_SIZE));
}
public static void handleRead(SelectionKey key) throws IOException {
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer buf = (ByteBuffer) key.attachment();
int bytesRead = sc.read(buf);
while (bytesRead > 0) {
buf.flip();
while (buf.hasRemaining()) {
System.out.print((char) buf.get());
}
System.out.println();
buf.clear();
bytesRead = sc.read(buf);
}
if (bytesRead == -1) {
sc.close();
}
}
public static void handleWrite(SelectionKey key) throws IOException {
ByteBuffer buf = (ByteBuffer) key.attachment();
buf.flip();
SocketChannel sc = (SocketChannel) key.channel();
while (buf.hasRemaining()) {
sc.write(buf);
}
buf.compact();
}
public static void selector() {
Selector selector = null;
ServerSocketChannel ssc = null;
try {
selector = Selector.open();
ssc = ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress(PORT));
ssc.configureBlocking(false);
ssc.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
if (selector.select(TIMEOUT) == 0) {
System.out.println("==");
continue;
}
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> iterator = keys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isAcceptable()) {
handleAccept(key);
}
if (key.isReadable()) {
handleRead(key);
}
if (key.isWritable() && key.isValid()) {
handleWrite(key);
}
if (key.isConnectable()) {
System.out.println("isConnectable = true");
}
iterator.remove();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (selector != null) {
selector.close();
}
if (ssc != null) {
ssc.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
```
然后是客户端代码:
```java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
public class NioClient {
private static int BUF_SIZE = 1024;
private static int PORT = 8080;
private static int TIMEOUT = 3000;
public static void main(String[] args) throws IOException {
SocketChannel clientChannel = SocketChannel.open();
clientChannel.configureBlocking(false);
Selector selector = Selector.open();
clientChannel.register(selector, SelectionKey.OP_CONNECT);
clientChannel.connect(new InetSocketAddress(PORT));
while (true) {
if (selector.select(TIMEOUT) == 0) {
System.out.println("==");
continue;
}
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> iterator = keys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isConnectable()) {
SocketChannel channel = (SocketChannel) key.channel();
if (channel.isConnectionPending()) {
channel.finishConnect();
}
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
Scanner scanner = new Scanner(System.in);
String message = scanner.nextLine();
channel.write(ByteBuffer.wrap(message.getBytes()));
} else if (key.isReadable()) {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(BUF_SIZE);
int bytesRead = channel.read(buffer);
while (bytesRead > 0) {
buffer.flip();
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
System.out.println();
buffer.clear();
bytesRead = channel.read(buffer);
}
}
iterator.remove();
}
}
}
}
```
这里的服务端监听端口为 8080,客户端连接的端口也为 8080。客户端首先向服务端发送一条消息,然后等待服务端的响应。当服务端接收到客户端的消息后,就会输出到控制台,并将消息原封不动地返回给客户端。客户端接收到服务端的响应后,也会将其输出到控制台。
注意,这个示例只是一个简单的演示,实际开发中需要考虑更多的因素,例如线程安全、异常处理等等。
阅读全文