![](/img/trans.png)
[英]Why doesnt java tcp socket send all data when called repeatetly in a while-loop?
[英]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.