簡體   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