Java TCP Socket Пока l oop и счетчик для приема данных X раз - PullRequest
0 голосов
/ 04 августа 2020

Я программист-любитель и пишу клиентскую программу Java TCP-сокета, которая принимает сообщения типа Integer и String от сервера (pl c). В настоящее время он работает нормально и возвращает правильные значения при использовании basi c попробуйте catch без каких-либо циклов, чтобы программа работала.

Но ... Я пытался добавить while l oop со счетчиком 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 l oop в этом случае, чтобы он возвращал правильные значения 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

EDIT # 2

Итак, я сделал серверную программу, которая работает на localhost и отправляет байт [100], и она работает правильно. Похоже, проблема скорее всего в моей программе PL C, а не в Java.

Класс сервера:

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();
                }
            }
    }
}

Ответы [ 2 ]

0 голосов
/ 04 августа 2020

Вы не учитываете, что устройство, отправляющее данные (я буду называть его для краткости «сервером»), может закрыть поток на своем конце. Когда это произойдет, inFromServer.read() вернет -1. Вы не проверяете это значение, поэтому в конечном итоге вы заполните массив messageFromServer значениями -1.

Если вы знаете, что сообщения должны быть 100 байт, вы можете прочитать сообщение с помощью один вызов метода DataInputStream без for l oop. Замените свой for (int i = 0; i < messageFromServer.length; i++) на:

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

Если поток сервера закрыт до того, как будет прочитано полное сообщение, этот метод вызовет исключение (EOFException).

0 голосов
/ 04 августа 2020

в вашем while l oop, вы l oop от 0 до 5, что означает 6 раз. вы можете изменить это:

while (counter <= 5)

на это, чтобы он выполнялся только 5 раз:

while (counter < 5)
...