繁体   English   中英

Java TCP Socket While循环和计数器接收数据X次

[英]Java TCP Socket While loop and counter to receive data X times

我是一名业余程序员,正在编写 Java TCP 套接字客户端程序,它从服务器 (plc) 接收 Integer 和字符串类型的消息。 目前,如果使用没有任何循环的基本 try catch 来保持程序运行,它可以正常工作并返回正确的值。

但是......我一直在尝试添加 while 循环,计数器为 5 个接收时间,之后程序结束,但它在一次读取时返回:

Int: 705 //correct value that it should receive every time
String: testi3 //correct value that it should receive every time



Int: 0 // prints also this duplicate value
String:  // prints also this duplicate value

在这种情况下我应该如何使用 while 循环以便它返回正确的值 5 次然后正确结束程序?

我的程序看起来像这样:

import java.io.*;
import java.net.Socket;
import java.util.Arrays;

public class GetData2 {

    private static int counter =0;
    private Socket clientSocket;
    //private PrintWriter out;
    private String host = "192.168.0.1";
    private int port2 = 2000;
    private DataInputStream inFromServer;




    public void start() throws IOException{
        System.out.println("Client started");
        clientSocket = new Socket(host, port2);
    }




    public void run() throws IOException {

        while (counter <= 5) {

            inFromServer = new DataInputStream(clientSocket.getInputStream());
            //BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

            int length = 100; // read length of incoming message
            byte[] messageFromServer = new byte[length];


                for (int i = 0; i < messageFromServer.length; i++) {
                    messageFromServer[i] = (byte) inFromServer.read();             //read message from the server
                }
                System.out.println("\n");

                //System.out.println(Arrays.toString(messageFromServer));
                byte[] copyOfData = Arrays.copyOf(messageFromServer, messageFromServer.length); //copies byte array from messageFromServer[] to copyOfData[]



                System.out.println("\n");
                //Integer
                short value = 0;
                                                                                            // reads bytes 0-1
                value = (short) (copyOfData[0] * 256 + (short) copyOfData[1]);              // moves received bytes
                                                                                          // shows the order of received byes

                System.out.println("Int: " + value);                                     // return bytes as an Integer

                //String
                System.out.print("String: ");
                for (int i = 4; i < copyOfData.length && i < 10; i++) {            // reads bytes 4-10 from array

                    System.out.printf("%c", copyOfData[i]);                   // returns String testi2 from pythondemo 2 plc application
                }
                counter++;
            System.out.println(counter);



        }


    }
    public void stop() throws IOException{

        //out.close();

        System.out.println("Application stopped");
        clientSocket.close();
        inFromServer.close();

    }




    public static void main(String[] args) throws IOException {
        GetData2 getData2 =new GetData2();
        getData2.start();
        getData2.run();


        if(counter == 5){
            getData2.stop();
        }


    }

}

编辑:

似乎如果我将接收到的字节数组长度从 [100] 更改为 [10],程序将执行并打印它;

Client started




Int: 705
String: testi3
counter: 1




Int: 0
String:       
counter: 2




Int: 0
String:       
counter: 3




Int: 0
String:       
counter: 4




Int: 0
String:       
counter: 5
Application stopped

编辑#2

因此,我制作了在 localhost 中运行并发送 byte[100] 的服务器程序,它工作正常。 似乎问题最有可能出现在我的 PLC 程序中,而不是 Java 中。

服务器 Class:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class GetData2_Server {
    public static void main(String[] args) throws IOException {
        System.out.println("server started");
        Scanner scan = new Scanner(System.in);
        ServerSocket server = new ServerSocket(8080);
        Socket socket = server.accept();
        System.out.println("server accepted");
        System.out.println("1 == out n flush, 0 == close program");
        int value = scan.nextInt();
        byte[] bytesOut = new byte[100];
        bytesOut[0]=0;
        bytesOut[1]=3;

        DataOutputStream out = new DataOutputStream(socket.getOutputStream());

        while (value == 1)
            {
                out.write(bytesOut);
                out.flush();
                value = scan.nextInt();
                if(value == 0){
                    out.close();
                    socket.close();
                }
            }
    }
}

在你的 while 循环中,你从 0 循环到 5,这意味着 6 次。 你可能想改变这个:

while (counter <= 5)

为此,它只循环 5 次:

while (counter < 5)

您没有考虑到发送数据的设备(我将简称为“服务器”)可能会在其末端关闭stream。 发生这种情况时, inFromServer.read()将返回 -1。 您没有检查此值,因此您最终将使用 -1 值填充messageFromServer数组。

如果您知道消息应为 100 字节,则可以通过单个DataInputStream方法调用读取消息,而无需 for 循环。 将您的for (int i = 0; i < messageFromServer.length; i++)替换为:

byte[] messageFromServer = new byte[length];
inFromServer.readFully(messageFromServer);

如果服务器 stream 在读取完整消息之前关闭,则此方法将抛出异常 (EOFException)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM