Java NIO网络通信 AsynchronousServerSocketChannel

原程序见疯狂讲义第4版 第811页至814页 下面贴出源代码

AIOClient.java

package fkJava4.ch17_3;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.util.concurrent.*;
/**
 * Description:
 * 网站: <a href="http://www.crazyit.org">疯狂Java联盟</a><br>
 * Copyright (C), 2001-2018, Yeeku.H.Lee<br>
 * This program is protected by copyright laws.<br>
 * Program Name:<br>
 * Date:<br>
 * @author Yeeku.H.Lee kongyeeku@163.com
 * @version 1.0
 */
public class AIOClient
{
    final static String UTF_8 = "utf-8";
    final static int PORT = 30000;
    // 与服务器端通信的异步Channel
    AsynchronousSocketChannel clientChannel;
    JFrame mainWin = new JFrame("多人聊天");
    JTextArea jta = new JTextArea(16 , 48);
    JTextField jtf = new JTextField(40);
    JButton sendBn = new JButton("发送");
    public void init()
    {
        mainWin.setLayout(new BorderLayout());
        jta.setEditable(false);
        mainWin.add(new JScrollPane(jta), BorderLayout.CENTER);
        JPanel jp = new JPanel();
        jp.add(jtf);
        jp.add(sendBn);
        // 发送消息的Action,Action是ActionListener的子接口
        Action sendAction = new AbstractAction()
        {
            public void actionPerformed(ActionEvent e)
            {
                String content = jtf.getText();
                if (content.trim().length() > 0)
                {
                    try
                    {
                        // 将content内容写入Channel中
                        clientChannel.write(ByteBuffer.wrap(content
                                .trim().getBytes(UTF_8))).get();    //①
                    }
                    catch (Exception ex)
                    {
                        ex.printStackTrace();
                    }
                }
                // 清空输入框
                jtf.setText("");
            }
        };
        sendBn.addActionListener(sendAction);
        // 将Ctrl+Enter键和"send"关联
        jtf.getInputMap().put(KeyStroke.getKeyStroke('\n'
                , InputEvent.CTRL_DOWN_MASK) , "send");
        // 将"send"和sendAction关联
        jtf.getActionMap().put("send", sendAction);
        mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainWin.add(jp , BorderLayout.SOUTH);
        mainWin.pack();
        mainWin.setVisible(true);
    }
    public void connect()
            throws Exception
    {
        // 定义一个ByteBuffer准备读取数据
        final ByteBuffer buff = ByteBuffer.allocate(1024);
        // 创建一个线程池
        ExecutorService executor = Executors.newFixedThreadPool(80);
        // 以指定线程池来创建一个AsynchronousChannelGroup
        AsynchronousChannelGroup channelGroup =
                AsynchronousChannelGroup.withThreadPool(executor);
        // 以channelGroup作为组管理器来创建AsynchronousSocketChannel
        clientChannel = AsynchronousSocketChannel.open(channelGroup);
        // 让AsynchronousSocketChannel连接到指定IP、指定端口
        clientChannel.connect(new InetSocketAddress("127.0.0.1"
                , PORT)).get();
        jta.append("---与服务器连接成功---\n");
        buff.clear();
        clientChannel.read(buff, null
                , new CompletionHandler<Integer,Object>()   //②
                {
                    @Override
                    public void completed(Integer result, Object attachment)
                    {
                        buff.flip();
                        // 将buff中内容转换为字符串
                        String content = StandardCharsets.UTF_8
                                .decode(buff).toString();
                        // 显示从服务器端读取的数据
                        jta.append("某人说:" + content + "\n");
                        buff.clear();
                        clientChannel.read(buff , null , this);
                    }
                    @Override
                    public void failed(Throwable ex, Object attachment)
                    {
                        System.out.println("读取数据失败: " + ex);
                    }
                });
    }
    public static void main(String[] args)
            throws Exception
    {
        AIOClient client = new AIOClient();
        client.init();
        client.connect();
    }
}

上面代码大致意思是使用JavaSwing写一个客户端,使用AsynchronousSocketChannel进行通信,当多个客户端连接到服务端时,任何一个客户端更新消息后,服务端都会把消息传送给多个客户端

服务端更新消息代码

sc.read(buff , null
                , new CompletionHandler<Integer,Object>()  // ②
                {
                    @Override
                    public void completed(Integer result
                            , Object attachment)
                    {
                        buff.flip();
                        // 将buff中内容转换为字符串
                        String content = StandardCharsets.UTF_8
                                .decode(buff).toString();
                        // 遍历每个Channel,将收到的信息写入各Channel中
                        for(AsynchronousSocketChannel c : AIOServer.channelList)
                        {
                            try
                            {
                                c.write(ByteBuffer.wrap(content.getBytes(
                                        AIOServer.UTF_8))).get();
                            }
                            catch (Exception ex)
                            {
                                ex.printStackTrace();
                            }
                        }
                        buff.clear();
                        // 读取下一次数据
                        sc.read(buff , null , this);
                    }

下面是完整服务端代码

AIOServer.java

package fkJava4.ch17_3;


import java.net.*;
import java.io.*;
import java.util.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.util.concurrent.*;
/**
 * Description:
 * 网站: <a href="http://www.crazyit.org">疯狂Java联盟</a><br>
 * Copyright (C), 2001-2018, Yeeku.H.Lee<br>
 * This program is protected by copyright laws.<br>
 * Program Name:<br>
 * Date:<br>
 * @author Yeeku.H.Lee kongyeeku@163.com
 * @version 1.0
 */
public class AIOServer
{
    static final int PORT = 30000;
    final static String UTF_8 = "utf-8";
    static List<AsynchronousSocketChannel> channelList
            = new ArrayList<>();
    public void startListen() throws InterruptedException,
            Exception
    {
        // 创建一个线程池
        ExecutorService executor = Executors.newFixedThreadPool(20);
        // 以指定线程池来创建一个AsynchronousChannelGroup
        AsynchronousChannelGroup channelGroup = AsynchronousChannelGroup
                .withThreadPool(executor);
        // 以指定线程池来创建一个AsynchronousServerSocketChannel
        AsynchronousServerSocketChannel serverChannel
                = AsynchronousServerSocketChannel.open(channelGroup)
                // 指定监听本机的PORT端口
                .bind(new InetSocketAddress(PORT));
        // 使用CompletionHandler接受来自客户端的连接请求
        serverChannel.accept(null, new AcceptHandler(serverChannel));  // ①
        Thread.sleep(100000);
    }
    public static void main(String[] args)
            throws Exception
    {
        AIOServer server = new AIOServer();
        server.startListen();
    }
}
// 实现自己的CompletionHandler类
class AcceptHandler implements
        CompletionHandler<AsynchronousSocketChannel, Object>
{
    private AsynchronousServerSocketChannel serverChannel;
    public AcceptHandler(AsynchronousServerSocketChannel sc)
    {
        this.serverChannel = sc;
    }
    // 定义一个ByteBuffer准备读取数据
    ByteBuffer buff = ByteBuffer.allocate(1024);
    // 当实际IO操作完成时候触发该方法
    @Override
    public void completed(final AsynchronousSocketChannel sc
            , Object attachment)
    {
        // 记录新连接的进来的Channel
        AIOServer.channelList.add(sc);
        // 准备接受客户端的下一次连接
        serverChannel.accept(null , this);
        sc.read(buff , null
                , new CompletionHandler<Integer,Object>()  // ②
                {
                    @Override
                    public void completed(Integer result
                            , Object attachment)
                    {
                        buff.flip();
                        // 将buff中内容转换为字符串
                        String content = StandardCharsets.UTF_8
                                .decode(buff).toString();
                        // 遍历每个Channel,将收到的信息写入各Channel中
                        for(AsynchronousSocketChannel c : AIOServer.channelList)
                        {
                            try
                            {
                                c.write(ByteBuffer.wrap(content.getBytes(
                                        AIOServer.UTF_8))).get();
                            }
                            catch (Exception ex)
                            {
                                ex.printStackTrace();
                            }
                        }
                        buff.clear();
                        // 读取下一次数据
                        sc.read(buff , null , this);
                    }
                    @Override
                    public void failed(Throwable ex, Object attachment)
                    {
                        System.out.println("读取数据失败: " + ex);
                        // 从该Channel读取数据失败,就将该Channel删除
                        AIOServer.channelList.remove(sc);
                    }
                });
    }
    @Override
    public void failed(Throwable ex, Object attachment)
    {
        System.out.println("连接失败: " + ex);
    }
}
由于客户端是使用Swing写的界面,本人自己修改成JavaFx
并把数据收发做了点修改

工程目录

在这里插入图片描述

package sugar.utils.socket;

import com.alibaba.fastjson.JSON;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.io.UnsupportedEncodingException;
import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.ExecutionException;

public class AioClientApp extends Application implements Observer {

    private static TextArea textArea ;
    private boolean isGetData ;
    public static void main(String[] args)
            throws Exception
    {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        VBox vBox = new VBox();
        TextField field = new TextField();
        Button btn = new Button("发送");
        vBox.getChildren().addAll(field,btn);

        Scene scene = new Scene(vBox,650,600);
        Stage stage = new Stage();
        stage.setScene(scene);
        stage.setTitle("客户端");
        stage.show();

        if (stage.isShowing()){

            //当调用start()方法时
            //会发送sugar.utils.socket.SimpleClientData
            //的json数据,包含主机ip等
            //等于第一次连接服务端,服务端会做一些处理
            //服务端连接数据库处理客户端群、联系人等
            //至于客户端需要下载大文件时应该让客户端重新发送请求,使用javaWeb技术作为后端
            AioClientUtils clientUtils =  AioClientUtils.getClient();
            clientUtils.start();
            textArea = clientUtils.getTextArea(); //使用 AioClientUtils的 TextArea
            vBox.getChildren().add(0,textArea);

            btn.setOnAction(event -> {
                try {
                    SimpleClientData clientData = new SimpleClientData();
                    clientData.setInfo(field.getText());
                    String str= JSON.toJSONString(clientData);
                    clientUtils.sendData(str);
                    textArea.setText(field.getText());
                } catch (UnsupportedEncodingException | ExecutionException | InterruptedException e) {
                    e.printStackTrace();
                }

            });
            stage.setOnCloseRequest(event -> {
                clientUtils.getExecutor().shutdown();
            });


        }

        if (textArea.getText().trim()!= ""){
            System.out.println("--------------客户端收到数据---------------");
        }

    }

    @Override
    public void update(Observable o, Object arg) {

    }

    public static TextArea getTextArea() {
        return textArea;
    }
}

在上面代码中实现了Observer接口
本想打算使用观察者模式,当被观察者发送通知,观察者自动更新
即下面代码会重写。但是后面并没有使用此方法。但是这并不影响。

 @Override
    public void update(Observable o, Object arg) {

    }
下面我抽出核心写成一个工具类AioClientUtils
引用了com.alibaba.fastjson.JSON类用于发送和接收Json格式的数据。
package sugar.utils.socket;

import com.alibaba.fastjson.JSON;
import javafx.scene.control.TextArea;
import sugar.utils.obser.BaseObservable;
import sugar.utils.obser.BaseObserver;

import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Observer;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class AioClientUtils
{


    private StringBuilder stringBuilder = OnlyRead.STRING_BUILDER;

    public AioClientUtils() {
    }

    public static AioClientUtils getClient() {
        return new AioClientUtils();
    }
    private final  TextArea textArea = new TextArea();
    private final  BaseObserver observer = new BaseObserver() ;
    private boolean isGetData = false;
    private  StringBuilder builder = new StringBuilder();
    final static String UTF_8 = OnlyRead.UTF_8;
    final static int PORT = OnlyRead.PORT;
    // 创建一个线程池
    private ExecutorService executor = Executors.newFixedThreadPool(10);
    // 与服务器端通信的异步Channel
    private AsynchronousSocketChannel clientChannel;

    private Charset charset = Charset.forName(OnlyRead.UTF_8);
    // 定义一个ByteBuffer准备读取数据
    private final ByteBuffer byteBuffer = ByteBuffer.allocate(OnlyRead.BYTE_Buffer_Size);

    private synchronized ByteBuffer getByteBuffer(){
        return byteBuffer;
    }
    private synchronized AsynchronousSocketChannel getClientChannel(){
        return clientChannel;
    }

    public void start() throws Exception {

        // 以指定线程池来创建一个AsynchronousChannelGroup
        AsynchronousChannelGroup channelGroup =
                AsynchronousChannelGroup.withThreadPool(executor);
        // 以channelGroup作为组管理器来创建AsynchronousSocketChannel
        clientChannel = AsynchronousSocketChannel.open(channelGroup);
        // 让AsynchronousSocketChannel连接到指定IP、指定端口
        clientChannel.connect(new InetSocketAddress(OnlyRead.HOST
                , PORT)).get();//必须调用get方法
        //jta.append("---与服务器连接成功---\n");
        byteBuffer.clear();

        //
        BaseObservable observable = new BaseObservable();
       // BaseObserver observer = new BaseObserver();
        observable.addObserver(observer);//使用全局变量的BaseObserver

        //-----------发送的json数据
        SocketAddress address = clientChannel.getLocalAddress();
        InetAddress addr = InetAddress.getLocalHost();
        System.out.println("Local HostAddress: "+ addr.getHostAddress());
        String hostname = addr.getHostName();
        System.out.println("Local host name: "+hostname);
        SimpleClientData data = new SimpleClientData();
        data.setIp(addr.getHostAddress());
        data.setHostName(addr.getHostName());
        data.setTitle("第一次客户端请求");
        data.setDataType(DataType.Str);
        //data.setId();
        data.setInfo("第一次客户端请求");

        //
        String jsonString= JSON.toJSONString(data);
        sendData(jsonString);

        //----------初始化接收
        getDataInit();
    }

    //发送json数据到服务端    String str= JSON.toJSONString(obj);
    //传入的必须是json
    public void sendData(String jsonString) throws UnsupportedEncodingException, ExecutionException, InterruptedException {
        ByteBuffer byteSend = getByteBuffer();
        getClientChannel()
                .write(ByteBuffer
                .wrap(jsonString.getBytes(OnlyRead.UTF_8)))
                .get();

    }


    //当服务端发送数据就会执行 completed方法
    public void getDataInit(){
        ByteBuffer byteGet = getByteBuffer();
        getClientChannel().read(byteGet, null, new CompletionHandler<Integer,Object>(){
                    @Override
                    public void completed(Integer result, Object attachment) {
//                        builder.delete(0,builder.length());
                        byteGet.flip();
                        // 将buff中内容转换为字符串
//                        builder.append(StandardCharsets.UTF_8
//                                .decode(byteGet).toString());
//                        String serverData = builder.toString();

                        //服务端传来的json转为SimpleServerData
                        SimpleServerData data =
                                JSON.parseObject(StandardCharsets.UTF_8
                                        .decode(byteGet).toString(), SimpleServerData.class);
                        //
                       getServerData(data.toString());
                         byteGet.clear();
                        getClientChannel().read(byteGet, null , this);
                    }
                    @Override
                    public void failed(Throwable ex, Object attachment) {
                        System.out.println("读取数据失败: " + ex);
                    }
                });

    }

    private void getServerData(String str){
        textArea.setText(str);
        stringBuilder.append(str);
    }

    //主动获取数据
    public String getData2() throws ExecutionException, InterruptedException {
        ByteBuffer byteGet = getByteBuffer();
        Future<Integer> future = getClientChannel().read(byteGet);
        future.get(); //必须调用get方法

        byteGet.flip();
        builder.append(charset.decode(byteGet).toString());
        byteGet.clear();

        return builder.toString();
    }
    public ExecutorService getExecutor() {
        return executor;
    }

    public TextArea getTextArea() {
        return textArea;
    }
}
package sugar.utils.socket;

import javafx.scene.control.TextArea;

import java.nio.channels.AsynchronousSocketChannel;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public final class OnlyRead {
    public final static String UTF_8 = "utf-8";
    public final static String HOST = "127.0.0.1";
    public final static int PORT = 9971;
    public final static List<AsynchronousSocketChannel> SOCKET_CHANNEL_LIST
            = new ArrayList<>();
    //使用HashSet
    public final static Set<SocketChannelBean> SOCKET_CHANNEL_SET = new HashSet<>();
    public final static TextArea TEXT_AREA_1 = new TextArea();
    public final static TextArea TEXT_AREA_2 = new TextArea();
    public final static TextArea TEXT_AREA_3 = new TextArea();
    public static StringBuilder STRING_BUILDER = new StringBuilder();
    public final static Integer BYTE_Buffer_Size = 1024*100;

    public static TextArea getTextArea(){
       return new TextArea();
    }
}

package sugar.utils.socket;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

//只作为客户端和服务端轻量级双向通信
public class AioServer extends Application {
    static final int PORT = OnlyRead.PORT;
    final static String UTF_8 = OnlyRead.UTF_8;
//    static List<AsynchronousSocketChannel> channelList
//            = new ArrayList<>();
    public void startListen() throws InterruptedException,
            Exception
    {
        // 创建一个线程池
        ExecutorService executor = Executors.newFixedThreadPool(20);
        // 以指定线程池来创建一个AsynchronousChannelGroup
        AsynchronousChannelGroup channelGroup = AsynchronousChannelGroup
                .withThreadPool(executor);
        // 以指定线程池来创建一个AsynchronousServerSocketChannel
        AsynchronousServerSocketChannel serverChannel
                = AsynchronousServerSocketChannel.open(channelGroup)
                // 指定监听本机的PORT端口
                .bind(new InetSocketAddress(PORT));
        // 使用CompletionHandler接受来自客户端的连接请求
        //后期仍然需要再次调用
        serverChannel.accept(null, new ServerHandler(serverChannel));  //
        Thread.sleep(1000);
    }


    public static void main(String[] args)
            throws Exception
    {
        AioServer server = new AioServer();
        server.startListen();
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        VBox vBox = new VBox();

        //客户端连接数量
        OnlyRead.SOCKET_CHANNEL_SET.size();

        Scene scene = new Scene(vBox,650,600);
        Stage stage = new Stage();
        stage.setScene(scene);
        stage.setTitle("服务端");
        stage.show();
    }
}

package sugar.utils.socket;

import com.alibaba.fastjson.JSON;

import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Iterator;
import java.util.stream.Collectors;

public class ServerHandler implements
        CompletionHandler<AsynchronousSocketChannel, Object> {

    private AsynchronousServerSocketChannel serverChannel;

    public ServerHandler(AsynchronousServerSocketChannel sc) {
        this.serverChannel = sc;
    }

    // 定义一个ByteBuffer准备读取数据
    ByteBuffer buff = ByteBuffer.allocate(OnlyRead.BYTE_Buffer_Size);

    // 当实际IO操作完成时候触发该方法
    @Override
    public void completed(final AsynchronousSocketChannel socketChannel
            , Object attachment) {
        // 记录新连接的进来的Channel
        OnlyRead.SOCKET_CHANNEL_LIST.add(socketChannel);
        //放入set
        SocketChannelBean bean = new SocketChannelBean();
        bean.setSocketChannel(socketChannel);
        OnlyRead.SOCKET_CHANNEL_SET.add(bean);

        // 准备接受客户端的下一次连接
        serverChannel.accept(null, this);
        //
        socketChannel.read(buff, null
                , new CompletionHandler<Integer, Object>()  // ②
                {
                    @Override
                    public void completed(Integer result
                            , Object attachment) {
                        buff.flip();
                        // 将buff中内容转换为字符串
                        String clientData = StandardCharsets.UTF_8
                                .decode(buff).toString();
                        //
                        //String转Object
                        SimpleClientData clientData1= JSON.parseObject(clientData, SimpleClientData.class);

                        System.out.println("客户端传来的数据"+clientData1.toString());

                        //解析 SimpleClientData


                        //删除不符合的
                        if (false) {
                            HashSet<SocketChannelBean> beans = (HashSet<SocketChannelBean>)
                                    OnlyRead.SOCKET_CHANNEL_SET
                                            .stream().filter(bean -> bean.getId().equals(""))
                                            .collect(Collectors.toSet());
                            Iterator iterator = beans.iterator(); //迭代器
                            //迭代器使用方法
                            while (iterator.hasNext()) {
                                SocketChannelBean channelBean = (SocketChannelBean) iterator.next();
                            }
                        }
                        //解析客户端传来的数据

                        if (true) {
                            // 遍历每个Channel,将收到的信息写入各Channel中
                            for (AsynchronousSocketChannel c : OnlyRead.SOCKET_CHANNEL_LIST) {
                                try {
                                    //返回服务端到客户端
                                    SimpleServerData simpleServerData = new SimpleServerData();
                                    simpleServerData.setInfo(clientData1.getInfo());
                                    //转换为json
                                    String serverData = JSON.toJSONString(simpleServerData);
                                    //写入数据到 SocketChannel
                                    c.write(ByteBuffer.wrap(serverData.getBytes(
                                            AioServer.UTF_8))).get();
                                } catch (Exception ex) {
                                    ex.printStackTrace();
                                }
                            }
                        }

                        //

                        buff.clear();
                        // 读取下一次数据
                        socketChannel.read(buff, null, this);
                    }

                    @Override
                    public void failed(Throwable ex, Object attachment) {
                        System.out.println("读取数据失败: " + ex);
                        // 从该Channel读取数据失败,就将该Channel删除
                        OnlyRead.SOCKET_CHANNEL_LIST.remove(socketChannel);
                    }
                });
    }

    @Override
    public void failed(Throwable ex, Object attachment) {
        System.out.println("连接失败: " + ex);
    }
}

完整代码已上传
传送门 https://download.csdn.net/download/pianai_s/12274784

注意客户端(AioClientApp)可以有多个实例,但是不同客户端
引用的 textArea需要注意了。

AioClientUtils clientUtils =  AioClientUtils.getClient();
            clientUtils.start();
            textArea = clientUtils.getTextArea(); //使用 AioClientUtils的 TextArea
            
服务端只有一个。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用 Java NIO(New I/O)进行网络编程的简单示例: ```java import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class NIOExample { public static void main(String[] args) throws IOException { // 创建一个线程池用于处理客户端连接 ExecutorService executor = Executors.newFixedThreadPool(10); // 创建 ServerSocketChannel 并绑定端口 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.bind(new InetSocketAddress("localhost", 8080)); System.out.println("Server started on port 8080"); while (true) { // 接受客户端连接 SocketChannel socketChannel = serverSocketChannel.accept(); // 使用线程池处理客户端连接 executor.execute(() -> handleClient(socketChannel)); } } private static void handleClient(SocketChannel socketChannel) { try { ByteBuffer buffer = ByteBuffer.allocate(1024); // 读取客户端发送的数据 int bytesRead = socketChannel.read(buffer); while (bytesRead != -1) { buffer.flip(); while (buffer.hasRemaining()) { System.out.print((char) buffer.get()); } buffer.clear(); bytesRead = socketChannel.read(buffer); } // 响应客户端 String response = "Hello from server"; ByteBuffer responseBuffer = ByteBuffer.wrap(response.getBytes()); socketChannel.write(responseBuffer); // 关闭连接 socketChannel.close(); } catch (IOException e) { e.printStackTrace(); } } } ``` 这个示例创建了一个简单的服务器,监听本地的 8080 端口。当客户端连接时,会使用线程池处理连接,并读取客户端发送的数据。然后,服务器会向客户端发送 "Hello from server" 的响应,并关闭连接。 请注意,这只是一个简单的示例,实际的网络编程可能涉及更复杂的逻辑和处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值