Java 从套接字读取消息未发送完整消息

标签 java sockets

你好,我正在使用此方法来读取消息:

public String readMessage() {
    int read = -1;
    byte[] buffer = new byte[5*1024];
    byte[] redData;
    try {
        while ((read = this.session.getInputStream().read(buffer)) > -1) {
            redData = new byte[read];
            System.arraycopy(buffer, 0, redData, 0, read);
            return new String(redData,"UTF-8");

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

当我写“你好,你今天好吗?”之类的话时

响应(精确格式,包括这些新行):

[/127.0.0.1:54930]:     
[/127.0.0.1:54930]: are

[/127.0.0.1:54930]: you

[/127.0.0.1:54930]: today?

这就是我读取聊天消息的方式,首先我检查请求了哪个数据包,如果数据包类型为0,那么我获取数据包处理程序的实例,并将客户端对象传递给聊天处理数据包,该数据包将在此处读取消息,例如这个:

public void startClientService() throws IOException {
    while(true) {
        int packetType = this.in.read();
        packets.getPacket(packetType);
    }
}
public void getPacket(int packetType) {
    switch (packetType) {
    case 0:
        chat.processPacket(this.client);
        break;
    }
}

以及聊天数据包:

@Override
public void processPacket(Session c) {
    String clientMessage = c.readMessage();
    System.out.println("[" + c.getStream().getRemoteSocketAddress() + "]: " + clientMessage.toString());
}

然后打印消息发生。

为什么它要换行打印部分消息?甚至没有完整的消息。

这是我的客户:

public static void main(String[] args) throws UnknownHostException, IOException {
    Socket socket = new Socket("127.0.0.1", 43594);
    Scanner r = new Scanner(System.in);
    PrintWriter out = new PrintWriter(socket.getOutputStream());
    String input;
    while(true) {
        input = r.next();
        if (input != null) {
            sendMessage(input, out);
        }
    }

}

public static void sendMessage(String message, PrintWriter out) {
    out.write(0);
    out.flush();
    out.write(message + "\n");
    out.flush();
}

谢谢。

session :

public class Session extends Thread implements Runnable {

    private Socket session;
    private Client client;
    private PrintWriter out;
    private BufferedReader in;  
    private PacketHandler packets;

    public Session(Socket session) {
        this.session = session;
        this.client = new Client(this);
        try {
            this.setStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.packets = new PacketHandler(this);
        System.out.println("[New session created]: " + session.getRemoteSocketAddress());
    }   

    public void run() {
        try {
            this.startClientService();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Socket getStream() {
        return this.session;
    }

    public void setStream() throws IOException {
        this.out = new PrintWriter(this.session.getOutputStream());
        this.in = new BufferedReader(new InputStreamReader(this.session.getInputStream()));
    }

    public Client getClient() {
        return this.client;
    }

    public String readMessage() {
        int read = -1;
        byte[] buffer = new byte[5*1024];
        byte[] redData;
        try {
            while ((read = this.session.getInputStream().read(buffer)) > -1) {
                redData = new byte[read];
                System.arraycopy(buffer, 0, redData, 0, read);
                return new String(redData,"UTF-8");

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

    public void startClientService() throws IOException {
        while(true) {
            int packetType = this.in.read();
            packets.getPacket(packetType);
        }
    }

    public void destruct() throws IOException {
        this.session.close();
        System.out.println("Session killed");
    }

}

最佳答案

看起来您一从流中获取一些数据就返回。

  while ((read = this.session.getInputStream().read(buffer)) > -1) {
            redData = new byte[read];
            System.arraycopy(buffer, 0, redData, 0, read);
            return new String(redData,"UTF-8");

        }

完整读取数据并从中创建一个字符串对象并返回

    BufferedReader br = new BufferedReader(new InputStreamReader(this.session.getInputStream()));
String msg = br.readLine();
br.close();
    return msg;

试试这个方法。这将为您提供整个数据到缓冲区,并可以作为字符串行返回。不需要循环

关于Java 从套接字读取消息未发送完整消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21683191/

相关文章:

java - 通过套接字从 Android 客户端向 Java 服务器发送图像时数据丢失

客户端不会多次发送数据

ios - 对象 0x7c15bad4 : incorrect checksum for freed object - object was probably modified after being freed 错误

c - 为什么在我的 UDP 服务器上尝试使用 sendto() 时会收到错误的地址错误?

java - Micronaut 数据原生图像 : No bean of type [io. micronaut.data.operations.PrimaryRepositoryOperations] 存在

java - Maven 和 play framework 2 - 未知包装 : play2

java - BeanUtils.copyProperties 产生 java.lang.VerifyError :

java - 在java中将一个小程序作为一个大程序的一部分。多线程?菜鸟

Java 彩票数组程序

java - 编辑 JTable 行