アプリケーションで TCP を使用しています。ソケットを正常に閉じても、データ損失の問題に直面しています。シナリオを複製する 2 つのサンプル プログラムを次に示します。
//TCP Sender プログラムは継続的にデータを送信します
public class TCPClient {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket soc = new Socket("xx.xx.xx.xx",9999);
OutputStream stream = soc.getOutputStream();
int i=1 ;
while(true) {
System.out.println("Writing "+ i);
stream.write(i++);
stream.flush();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
}
// TCP サーバー/レシーバー
public class TCPServer2 {
public static void main(String[] args) throws IOException {
System.out.println("program started");
ServerSocket serverSock = new ServerSocket(9999);
Socket socket =serverSock.accept();
System.out.println("client connected");
InputStream stream = socket.getInputStream();
InputStreamReader reader = null;
reader = new InputStreamReader(stream);
socket.setTcpNoDelay(true);
int n=0;
int i=1;
while (true) {
try {
n = reader.read();
System.out.println("Msg No.: "+n);
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
break;
}
if(i==5) {
System.out.println("closing socket");
socket.close();
//client should get exception while sending 6th msg
break;
}i++;
}
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
br.readLine();
}
}
理想的には、TCPClient プログラムは 6 番目のメッセージの送信中に例外を取得する必要がありますが、7 番目のメッセージの送信中に例外を取得します。高レベルのプロトコルと SO_LINGER を使用する以外に、このデータ損失の問題を回避する方法はありますか?
注意:このメッセージ損失の問題は、2 つの異なる Windows マシンを使用している場合に発生します。同じマシンでは正常に動作します。