0

I have this dummy program:

package com.company;

import javax.net.ssl.*;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.security.*;
import java.security.cert.CertificateException;

class MyClass implements Serializable
{
    private int i,j;

    public MyClass(int i, int j)
    {
        this.i = i;
        this.j = j;
    }

    public int getJ()
    {
        return j;
    }

    public void setJ(int j)
    {
        this.j = j;
    }

    public int getI()
    {
        return i;
    }

    public void setI(int i)
    {
        this.i = i;
    }
}
class SSLContextHelper
{
    static SSLContext createSSLContext(String path) throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, IOException, KeyManagementException, CertificateException
    {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyStore.load(new FileInputStream(path),"DSL2137976".toCharArray());

        // Create key manager
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
        keyManagerFactory.init(keyStore, "DSL2137976".toCharArray());
        KeyManager[] km = keyManagerFactory.getKeyManagers();

        // Create trust manager
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
        trustManagerFactory.init(keyStore);
        TrustManager[] tm = trustManagerFactory.getTrustManagers();

        // Initialize SSLContext
        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(km,  tm, new SecureRandom());

        return sslContext;
    }
}
class ServerThread extends Thread
{
    ServerSocket server;
    Socket client;
    ObjectOutputStream out;
    ObjectInputStream in;
    boolean issecure;
    SSLContext sslContext;
    public ServerThread(int port, boolean issecure) throws IOException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException
    {
        this.issecure=issecure;
        client=null;
        if(issecure)
        {
            sslContext = SSLContextHelper.createSSLContext("/usr/lib/jvm/java-8-openjdk/jre/lib/security/ssltest");
            SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory();
            server = sslServerSocketFactory.createServerSocket(port);
            server.setSoTimeout(200);
        }
        else
            server=new ServerSocket(port);
    }

    @Override
    public void run()
    {
        while (true)
        {
            try
            {
                if(client==null)
                {
                    if (issecure)
                    {
                        SSLSocket clientssl = (SSLSocket) server.accept();
                        clientssl.setEnabledCipherSuites(clientssl.getSupportedCipherSuites());
                        clientssl.startHandshake();
                        client = clientssl;
                    }
                    else
                        client = server.accept();

                    in = new ObjectInputStream(client.getInputStream());
                    out = new ObjectOutputStream(client.getOutputStream());
                    client.setSoTimeout(200);
                }
                String[] req = in.readUTF().split("\n");
                out.writeUTF("hello I'm the server");
                out.flush();
                req = in.readUTF().split("\n");
                out.writeUTF("I mean I'll serve you");
                out.flush();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }
}
public class Main
{
    public static void main(String... args) throws IOException, ClassNotFoundException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException
    {
        ServerThread serverThread=new ServerThread(14200, true);
        serverThread.setDaemon(true);
        serverThread.start();
        ServerThread mail=new ServerThread(14201, false);
        mail.setDaemon(true);
        mail.start();
        try
        {
            Thread.sleep(5000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }

        SSLSocket client=(SSLSocket)SSLContextHelper.createSSLContext("/usr/lib/jvm/java-8-openjdk/jre/lib/security/ssltest").getSocketFactory().createSocket();
        client.connect(new InetSocketAddress("localhost",14200),5000);
        Socket mailclient = new Socket();
        mailclient.connect(new InetSocketAddress("localhost", 14201), 5000);
        client.startHandshake();
        client.setSoTimeout(5000);
        ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
        ObjectInputStream in = new ObjectInputStream(client.getInputStream());

        out.writeUTF("hello\nhow are you");
        out.flush();
        System.out.println(in.readUTF());
        out.writeUTF("what\nI didn't understand");
        out.flush();
        System.out.println(in.readUTF());
        int i=0;
        while (i<=1)
        {
            try
            {
                try
                {
                    Thread.sleep(10000);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }

                out.writeUTF("hello\nhow are you");
                out.flush();
                System.out.println(in.readUTF());
                out.writeUTF("what\nI didn't understand");
                out.flush();
                System.out.println(in.readUTF());
                i++;
            }
            catch (SocketTimeoutException ignored)
            {

            }
        }
    }
}

It's just a simulation of a real program I have, the Thread.sleep on the client side is a simulation of a user doing some interaction with the system before clicking a button(the first sleep is the simulation of the user putting the sign in information, the second sleep is the user opening tab,clicking link,answers dialogs,etc).

Unfortunately I'm getting EOFException in the server side right after the server.accept succeed(that is when the client connects).

I know that this exception occurs when there is no data to get but this happens even after these two lines(the first ones before the while loop) on the client side:

out.writeUTF("hello\nhow are you");
out.flush();

after these two lines the client waits 5 seconds(the timeout I put) , during this 5 seconds the server keeps on its EOFException, when the timeout finishes the client gets SocketTimeoutException and the program exits.

The original program is getting the same EOFException on the server side, it began when I moved to SSLSockets.

So what's the issue here ?

Edit

I have found that when I remove the timeout(the Read timeout not the Accept timeout) it works perfectly.

Playing with the timeout, setting it to different value gives me strange NullPointerExceptions(that in is null !!!!!!!!!!).

I need the timeout because in my real program the server won't wait the client forever, it has other clients to serve as well .

Why timeout causes this ?

niceman
  • 2,653
  • 29
  • 57
  • 200ms is a ridiculously short timeout. It should be in tens of seconds. The server doesn't need a read timeout to service multiple clients. All that code that does I/O with the client should be in a separate thread from the accept loop, including construction of the object streams. If you want help with this problem you'll have to post the stack trace for a start. – user207421 Dec 13 '15 at 00:17
  • @EJP create a thread for every client Is what I'm trying to avoid because I want to work in nodejs way(one threaded server), anyway "tens of seconds" !!!! hmmm a server who would serve let's say 1000 clients, with a timeout of tens of seconds you'll have 999 clients waiting tens of seconds – niceman Dec 13 '15 at 18:35
  • I don't see what 'node.js way' has to do with Java code, or why you would want to emulate a fairly crippled system. Sounds like you're looking for NIO. – user207421 Dec 13 '15 at 18:55

0 Answers0