Я пытаюсь выяснить, нормально ли это.Потому что без ошибок соединение должно быть разорвано:
FIN ->
<- ACK
<- FIN
ACK ->
Я получаю это в конце TCP-соединения (через SSL, но я также получаю его с незашифрованным):
From To
1494 server client TCP search-agent > 59185 [PSH, ACK] Seq=25974 Ack=49460 Win=63784 Len=50
1495 client server TCP 59185 > search-agent [ACK] Seq=49460 Ack=26024 Win=63565 Len=0
1496 client server TCP 59185 > search-agent [PSH, ACK] Seq=49460 Ack=26024 Win=63565 Len=23
1497 client server TCP 59185 > search-agent [FIN, ACK] Seq=49483 Ack=26024 Win=63565 Len=0
1498 server client TCP search-agent > 59185 [PSH, ACK] Seq=26024 Ack=49484 Win=63784 Len=23
1499 client server TCP 59185 > search-agent [RST, ACK] Seq=49484 Ack=26047 Win=0 Len=0
Клиент нормально выходит и достигает socket.close , не следует ли затем нормально завершить соединение без сброса?
Я не могу найти ничего о TCPпотоки Java на Google ...
Вот мой код:
Сервер:
package Security;
import java.io.*;
import java.net.*;
import javax.net.ServerSocketFactory;
import javax.net.ssl.*;
import java.util.*;
public class SSLDemoServer
{
private static ServerSocket serverSocket;
private static final int PORT = 1234;
public static void main(String[] args) throws IOException
{
int received = 0;
String returned;
ObjectInputStream input = null;
PrintWriter output = null;
Socket client;
System.setProperty("javax.net.ssl.keyStore", "key.keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "vwpolo");
System.setProperty("javax.net.ssl.trustStore", "key.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "vwpolo");
try
{
System.out.println("Trying to set up server ...");
ServerSocketFactory factory = SSLServerSocketFactory.getDefault();
serverSocket = factory.createServerSocket(PORT);
System.out.println("Server started!\n");
}
catch (IOException ioEx)
{
System.out.println("Unable to set up port!");
ioEx.printStackTrace();
System.exit(1);
}
while(true)
{
client = serverSocket.accept();
System.out.println("Client trying to connect...");
try
{
System.out.println("Trying to create inputstream...");
input = new ObjectInputStream(client.getInputStream());
System.out.println("Trying to create outputstream...");
output = new PrintWriter(client.getOutputStream(), true);
System.out.println("Client successfully connected!");
while( true )
{
received = input.readInt();
returned = Integer.toHexString(received);
System.out.print(" " + received);
output.println(returned.toUpperCase());
}
}
catch(SSLException sslEx)
{
System.out.println("Connection failed! (non-SSL connection?)\n");
client.close();
continue;
}
catch(EOFException eofEx)
{
System.out.println("\nEnd of client data.\n");
}
catch(IOException ioEx)
{
System.out.println("I/O problem! (correct inputstream?)");
}
try {
input.close();
output.close();
}
catch (Exception e) {
}
client.close();
System.out.println("Client closed.\n");
}
}
}
Клиент:
package Security;
import java.io.*;
import java.net.*;
import javax.net.ssl.*;
import java.util.*;
public class SSLDemoClient
{
private static InetAddress host;
private static final int PORT = 1234;
public static void main(String[] args)
{
System.setProperty("javax.net.ssl.keyStore", "key.keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "vwpolo");
System.setProperty("javax.net.ssl.trustStore", "key.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "vwpolo");
System.out.println("\nCreating SSL socket ...");
SSLSocket socket = null;
try
{
host = InetAddress.getByName("192.168.56.101");
SSLSocketFactory factory = (SSLSocketFactory)
SSLSocketFactory.getDefault();
socket = (SSLSocket) factory.createSocket(host, PORT);
socket.startHandshake();
}
catch(UnknownHostException uhEx)
{
System.out.println("\nHost ID not found!\n");
System.exit(1);
}
catch(SSLException sslEx)
{
System.out.println("\nHandshaking unsuccessful ...");
System.exit(1);
}
catch (IOException e) {
e.printStackTrace();
}
System.out.println("\nHandshaking succeeded ...\n");
SSLClientThread client = new SSLClientThread(socket);
SSLReceiverThread receiver = new SSLReceiverThread(socket);
client.start();
receiver.start();
try
{
client.join();
receiver.join();
System.out.println("Trying to close...");
socket.close();
}
catch(InterruptedException iEx)
{
iEx.printStackTrace();
}
catch(IOException ioEx)
{
ioEx.printStackTrace();
}
System.out.println("\nClient finished.");
}
}
class SSLClientThread extends Thread
{
private SSLSocket socket;
public SSLClientThread(SSLSocket s)
{
socket = s;
}
public void run()
{
try
{
ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
for( int i = 1; i < 1025; i++)
{
output.writeInt(i);
sleep(10);
output.flush();
}
output.flush();
sleep(1000);
output.close();
}
catch(IOException ioEx)
{
System.out.println("Socket closed or unable to open socket.");
}
catch(InterruptedException iEx)
{
iEx.printStackTrace();
}
}
}
class SSLReceiverThread extends Thread
{
private SSLSocket socket;
public SSLReceiverThread(SSLSocket s)
{
socket = s;
}
public void run()
{
String response = null;
BufferedReader input = null;
try
{
input = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
try
{
response = input.readLine();
while(!response.equals(null))
{
System.out.print(response + " ");
response = input.readLine();
}
}
catch(Exception e)
{
System.out.println("\nEnd of server data.\n");
}
input.close();
}
catch(IOException ioEx)
{
ioEx.printStackTrace();
}
}
}
Большое спасибо, при не-SSL соединении, теперь я получаю хорошее упорядоченное завершение соединения без сброса.
НО, очевидно, этот метод не поддерживается SSLSocket
?Когда я пробую это в своем клиенте SSL, я получаю следующее исключение:
Exception in thread "Thread-0" java.lang.UnsupportedOperationException: The method shutdownOutput() is not supported in SSLSocket
at com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.shutdownOutput(Unknown Source)
at Security.SSLClientThread.run(SSLDemoClient.java:99)
Мой новый код выглядит так:
package Security;
import java.io.*;
import java.net.*;
import javax.net.SocketFactory;
import javax.net.ssl.*;
public class SSLDemoClient
{
private static InetAddress host;
private static Socket socket;
private static final int PORT = 1234;
public static void main(String[] args)
{
System.setProperty("javax.net.ssl.keyStore", "key.keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "vwpolo");
System.setProperty("javax.net.ssl.trustStore", "key.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "vwpolo");
System.out.println("\nCreating SSL socket ...");
try
{
host = InetAddress.getByName("192.168.56.101");
SocketFactory socketFactory = SSLSocketFactory.getDefault();
socket = socketFactory.createSocket(host, PORT);
}
catch(UnknownHostException uhEx)
{
System.out.println("\nHost ID not found!\n");
System.exit(1);
}
catch(SSLException sslEx)
{
System.out.println("\nHandshaking unsuccessful ...");
System.exit(1);
}
catch (IOException e) {
e.printStackTrace();
}
System.out.println("\nHandshaking succeeded ...\n");
SSLClientThread client = new SSLClientThread(socket);
SSLReceiverThread receiver = new SSLReceiverThread(socket);
client.start();
receiver.start();
try
{
client.join();
receiver.join();
System.out.println("Trying to close...");
socket.close();
}
catch(InterruptedException iEx)
{
iEx.printStackTrace();
}
catch(IOException ioEx)
{
ioEx.printStackTrace();
}
System.out.println("\nClient finished.");
}
}
class SSLClientThread extends Thread
{
private Socket socket;
public SSLClientThread(Socket s)
{
socket = s;
}
public void run()
{
try
{
ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
for( int i = 1; i < 1025; i++)
{
output.writeInt(i);
sleep(10);
output.flush();
}
output.flush();
sleep(1000);
socket.shutdownOutput();
}
catch(IOException ioEx)
{
System.out.println("Socket closed or unable to open socket.");
}
catch(InterruptedException iEx)
{
iEx.printStackTrace();
}
}
}
class SSLReceiverThread extends Thread
{
private Socket socket;
public SSLReceiverThread(Socket s)
{
socket = s;
}
public void run()
{
String response = null;
BufferedReader input = null;
try
{
input = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
try
{
response = input.readLine();
while(!response.equals(null))
{
System.out.print(response + " ");
response = input.readLine();
}
}
catch(Exception e)
{
System.out.println("\nEnd of server data.\n");
}
socket.shutdownInput();
}
catch(IOException ioEx)
{
ioEx.printStackTrace();
}
}
}
Правильно ли я его не использую?Или мой SSLSocket не правильный?Потому что с подключением без SSL проблем нет.