当前位置: 首页 > 知识库问答 >
问题:

为什么我的客户端无法接收来自服务器的消息

邵逸明
2023-03-14

服务器:

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.Arrays;
import java.util.Iterator;
public class TrainAgain {

private int port;
private Selector selector;

public TrainAgain(int port) {
    this.port = port;
}

public void startServer() {
    try {
        //open serversocketchannel, bind to port,config non-blocking and register on selector .
        selector = Selector.open();
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress("localhost",port));
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println("listen on port " + port);

        while (true) {
            //blocking here listening to channel that connected
            int r = selector.select();
            if (r == 0) {
                continue;
            }
            //after connected, use iterator to scan them all
            Iterator<SelectionKey> itr = selector.selectedKeys().iterator();
            while (itr.hasNext()) {
                SelectionKey key = itr.next();
                itr.remove();
                if (key.isAcceptable()) {
                    //channel is ready to accept a new socket channel
                    ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                    ssc.configureBlocking(false);
                    //get the socket channel and registed it to selector;
                    SocketChannel sc = ssc.accept();
                    sc.configureBlocking(false);
                    if (sc == null) {
                        continue;
                    }
                    sc.register(selector, SelectionKey.OP_READ);
                    System.out.println("connected to a new socket channel :" + sc);
                }else if(key.isConnectable()){
                    ((SocketChannel)key.channel()).finishConnect();
                } else if (key.isReadable()) {
                    //channel is ready for reading
                    SocketChannel sc = (SocketChannel) key.channel();
                    sc.configureBlocking(false);
                    ByteBuffer buffer = ByteBuffer.allocate(48);
                    while (true) {
                        buffer.clear();
                        int n = sc.read(buffer);
                        if (n <= 0) {
                            break;
                        }
                        System.out.println("receive data :" + Arrays.toString(buffer.array())+" from "+sc);
                    }
                    buffer = ByteBuffer.wrap("welcome!".getBytes());
                    buffer.flip();
                    //I write buffer here
                    sc.write(buffer);
                    System.out.println("write data :" + Arrays.toString(buffer.array())+" to "+sc);
                }


            }

        }

    } catch (IOException e) {
        e.printStackTrace();
    }


}

public static void main(String[] args) {
    TrainAgain again = new TrainAgain(8000);
    again.startServer();
}

}

客户:

import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;

public class Client {

private void startClient(int port) {
    try {
        //get socketchannel and connect to server
        SocketChannel sc = SocketChannel.open();
        sc.connect(new InetSocketAddress("localhost",port));
        System.out.println("connect to server from "+sc);
        sc.configureBlocking(false);
        RandomAccessFile randomAccessFile = new RandomAccessFile("D:\\nio-data.txt","rw");
        FileChannel fc = randomAccessFile.getChannel();
        //transfer data from filechannel to socketchannel
        fc.transferTo(0, randomAccessFile.length(), sc);

        ByteBuffer buffer = ByteBuffer.allocate(48);
        if(sc.isConnectionPending()){
            sc.finishConnect();
        }
        System.out.println("connect to server from "+sc);
        while(true){
            buffer.clear();
            System.out.println("read data from "+sc);
            //blocking here, why can't I read buffer
            int r = sc.read(buffer);
            if(r <= 0){
                break;
            }
            System.out.println(Arrays.toString(buffer.array()));
        }

    } catch (IOException e) {
        e.printStackTrace();
    }

}


public static void main(String[] args) {
    Client client = new Client();
    client.startClient(8000);
}
}

但最终,客户端阻塞了read(buffer)语句。

共有1个答案

井疏珂
2023-03-14

我搞定了!经过仔细调试,我发现在功能为将零设置为缓冲区的位置的wrap(字节)之后,我使用了另一种功能为将现在为零的位置设置为限制的filp方法。所以缓冲区实际上并没有发送到客户端。

 类似资料:
  • 我在Android上制作了一个客户端-服务器应用程序的简单原型 我设法将两个客户端连接到服务器上,服务器可以接收它们的消息。现在的问题是,我似乎无法向其他客户端广播/接收消息。 下面是Server类的完整代码 下面是Client类的完整代码

  • 我刚刚开始学习Java。我修改了服务器/客户端通信程序的客户端代码,为客户端创建了两个线程,一个是用于接收用户输入的主线程,另一个是用于接收服务器响应的inputThread。我确信服务器已经向客户机发送了响应,但是,在客户机上没有获得响应消息。 这是我的代码。有谁能帮我弄明白吗?谢谢

  • 我有一个Python服务器使用unix数据报套接字连接与一个C客户端通信。下面的代码设置一个套接字,然后从客户端发送和接收一条消息。这个脚本在python 2.7中工作,但是,当在python 3中测试它时,对recv()的调用会超时等待来自客户端的消息。然而,客户端确实从服务器接收消息而没有问题。我已经用3.5.2和3.7.1在两台不同的机器上测试过了,结果相同。 更新:我添加了一个ioloop

  • 问题内容: 我要进行最简单的解释。我的Java TCP项目有一个服务器和三个客户端。 服务器具有一个ClientThread。每个客户端都有一个ServerThread和一个UserThread。 工作流程为: 1.客户端(例如,client_0)的UserThread获取用户输入,然后将消息发送到服务器。 2.服务器的ClientThread捕获来自client_0的消息,并将另一条消息发送到另

  • 问题内容: 我要进行最简单的解释。我的Java TCP项目有一个服务器和三个客户端。 服务器具有一个ClientThread。每个客户端都有一个ServerThread和一个UserThread。 工作流程为: 1.客户端(例如,client_0)的UserThread获取用户输入,然后将消息发送到服务器。 2.服务器的ClientThread捕获来自client_0的消息,并将另一条消息发送到另

  • 我有一个客户端和一个服务器试图相互验证对方并启动TLS连接。我现在使用的证书是自签名的。 在服务器代码中,我设置了