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

客户端无法接收服务器消息的原因(java)

邹星火
2023-03-14

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

这是我的代码。有谁能帮我弄明白吗?谢谢

package clientnio;

import java.net.*; 
import java.nio.*; 
import java.io.*;
import java.nio.channels.*; 
import java.util.Scanner; 

public class ClientNIO {
public static int bufferLen = 50;
public static SocketChannel client;
public static ByteBuffer writeBuffer;
public static ByteBuffer readBuffer;

public static void main(String[] args) { 
    writeBuffer = ByteBuffer.allocate(bufferLen);
    readBuffer = ByteBuffer.allocate(bufferLen);

    try { 
        SocketAddress address = new InetSocketAddress("localhost",5505); 
        System.out.println("Local address: "+ address);
        client=SocketChannel.open(address);
        client.configureBlocking(false); 

        //readBuffer.flip();
        new inputThread(readBuffer);

        /*
        String a="asdasdasdasddffasfas"; 
        writeBuffer.put(a.getBytes()); 
        writeBuffer.clear();  
        int d=client.write(writeBuffer);
        writeBuffer.flip();
        */

        while (true) {
            InputStream inStream = System.in;
            Scanner scan = new Scanner(inStream);
            if (scan.hasNext()==true) {
                String inputLine = scan.nextLine();
                writeBuffer.put(inputLine.getBytes()); 
                //writeBuffer.clear();
                System.out.println(writeBuffer.remaining());
                client.write(writeBuffer);
                System.out.println("Sending data: "+new String(writeBuffer.array()));
                writeBuffer.flip(); 
                Thread.sleep(300);
            }
        }                 
    } 
    catch(Exception e) { 
        System.out.println(e);
    } 

}
}

class inputThread extends Thread {
private ByteBuffer readBuffer;
public inputThread(ByteBuffer readBuffer1) {  
    System.out.println("Receiving thread starts.");
    this.readBuffer = readBuffer1;
    start();
}

@Override
public void run() {
    try {
        while (true) {
            readBuffer.flip();
            int i=ClientNIO.client.read(readBuffer); 
            if(i>0) { 
                byte[] b=readBuffer.array(); 
                System.out.println("Receiving data: "+new String(b)); 
                    //client.close(); 
                    //System.out.println("Connection closed."); 
                    //break; 
            }
            Thread.sleep(100); 
        }
    }
    catch (Exception e) {
       System.out.println(e);
    }
  }
}

共有1个答案

牛迪
2023-03-14

免责声明:我不是Java的活跃用户。(我只在学校用过。)

建议:我认为,如果您使用阻塞模式,将大大简化调试过程,至少在您的代码示例正常工作之前是这样。(当前您的代码似乎没有从非阻塞模式中受益。)

我已经确定了两个问题,最后归纳为四行可能需要更改的代码:

  • bytebuffer分配它的备份数组时,它通过将position设置为零,并将limit设置为该数组的容量,从而将自己设置为准备写入。您对bytebuffer.flip()的两种用法(分别在写入循环和读取循环中)似乎与惯例背道而驰。
  • 调用byteBuffer.array()方法总是返回整个备份数组,因此它的大小总是BufferLen。因此,由全尺寸数组构造的string可能包含以前传输的垃圾。
    • 通常,需要将数组修剪到传输大小,并且字符串和字节数组之间的转换必须使用与服务器相同的编码。

    我对第一个问题的建议更改:
    (注意:我不知道如何修复数组修剪和编码问题。)

    writeBuffer.put(inputLine.getBytes()); 
    writeBuffer.flip();                       // <--here
    client.write(writeBuffer);
    ...
    writeBuffer.clear();                      // <-- should be clear() instead of flip()
    Thread.sleep(300);
    
    // readBuffer.flip();                      // <-- remove this line
    int i=ClientNIO.client.read(readBuffer); 
    if(i>0) { 
        readBuffer.flip();                     // <-- move it here
        byte[] b=readBuffer.array(); 
        System.out.println("Receiving data: "+new String(b)); 
        ...
    }
    

    参考文献

    • http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/bytebuffer.html
    • http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/channels/socketchannel.html
    • SocketChannel始终为空
    • http://www.exampledepot.com/egs/java.nio.charset/convertchar.html

 类似资料:
  • 问题内容: 我要进行最简单的解释。我的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的消息,并将另一条消息发送到另

  • 问题内容: 我正在尝试用两个客户端实现一个系统,其中一个客户端发送一条消息,而另一个客户端将接收该消息。下图将以更直观的方式对其进行解释: 因此,客户端1将消息发送到服务器(此工作正常),服务器接收到“推送”消息并发出应由客户端2接收的“弹出”消息。这里的问题是客户端2从未收到“流行”消息。:( 这是所有代码。 SERVER.JS 客户1(aka mobile.html) 客户2(aka web.

  • 我在远程机器上设置了Kafka和动物园管理员。在那台机器上,我可以看到下面使用官方网站上的测试方法工作。 但是当我使用本地消费者脚本时,它就不起作用了: 我试着把它改成: 然后运行客户端使用者脚本,它会给出错误: [2017-08-11 15:49:01,591]获取相关id为3的元数据时警告错误:{listings-incoming=leader_not_available}(org.apach

  • 我是一个使用python进行套接字编程的初学者。我正在做我的课程项目。我的项目的一部分需要用不同的端口发送和接收UDP消息。提供了名为robot的服务器程序,我需要编写名为student的客户端程序,它可以与机器人进行交互。因此,我不能显示服务器程序中的所有源代码。 这是服务器程序中与UDP套接字相关的部分 这是我的客户端程序。s3 是 UDP 套接字。我可以成功地向服务器程序发送消息,但无法从中

  • 服务器: 客户: 但最终,客户端阻塞了read(buffer)语句。