0

I'm writing a simple ServerSocket program and connecting to it from two browser tabs by urls: http://127.0.0.1:8080/Q1 and after a 10 sec pause http://127.0.0.1:8080/Q2.

My problem is that on ubuntu18 machine with java10 it works quick and fine. But on two win machines (my win8.1 with java8 and other win10 with java11) it hangs up after first query and does nothing for up to 2 minutes, server stays quiet if I don't send second query. If I send second query I get result for both queries (in swaped order first Q2 then Q1) in browser and my server reports reading both queries and next two browser does for favicons (swaped too - first Q2 then Q1 in 90% cases).

And if I just wait after starting Q1 (without starting Q2), first I see Socket#1 is created and it waits. It waits for 2 minutes and closes. Then in a moment server creates #2 sockets and quickly answers on Q1, closes, creates #3 socket gets and answers Q1-favicon query, that browser sent. All done very fast and beautiful. I would like not to have this pause with #1 Socket. I don't have it on ubuntu18 machine.

What am I doing wrong? Or is it something wrong with my win machines? Does your win machines process first query without waiting for second query?

import java.io.PrintWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.net.Socket;
import java.net.ServerSocket;
import java.util.stream.Collectors;
import java.io.IOException;

public class localhost {
    public static void main(String[] args) {
        int portNumber = 8080;
        System.out.println("Started...");
        String s="#";
        String ans="#";
        try (
        ServerSocket serverSocket = new ServerSocket(portNumber)){
            String httpResponse;
            int i=0;
            while(true){
                i++;
                System.out.println("Creating new Clien Socket #"+i);
                try( Socket clientSocket = serverSocket.accept()){
                    System.out.println("Accepted... "+clientSocket.toString());
                    try(InputStream in=clientSocket.getInputStream();){
                        {byte[] buffer = new byte[10000];
                        int total = in.read(buffer);
                        if (total>0) {
                            s = new String(java.util.Arrays.copyOfRange(buffer, 0, total));
                            System.out.println(s);

                            httpResponse = "HTTP/1.1 200 OK\r\n\r\nHello, there, "+ s.substring(5,7) +"!";
                            OutputStream out=clientSocket.getOutputStream();
                            out.write(httpResponse.getBytes());
                        } else { System.out.println("Empty..."); }
                        System.out.println("Finished #"+i+" "+clientSocket.toString());
                        System.out.println();}
                    }
                }
            }

        } catch(Exception e){
            System.out.println("Error: "+e);
        }
        System.out.println("I'm done "+s);
    }
}

UPD: For Q1 without Q2 case if I'm getting it right Wireshark shows two sockets - 50410 and 50411, while server accept()-ed only one - 50411. Looks like 50410 causes waiting, what is this empty query and where is it coming from?Wireshark screenshot

Rustam A.
  • 809
  • 8
  • 15
  • Did you start your application in cmd (windows)? – Wulf Mar 29 '19 at 10:17
  • I start it in VS Code (with code-runner extension in terminal) on all 3 machines. – Rustam A. Mar 29 '19 at 10:31
  • 1
    I run your code and it works... – Wulf Mar 29 '19 at 11:06
  • Thank you @Wufo what browser are you running queries from? I use chrome on win machines but firefox in ubuntu. I just tried sending queries form chrome-incognito-mode and firefox. In both cases everything works - no empty queries. But chrome (all ext off) doesn't work - it sends empty query first. – Rustam A. Mar 29 '19 at 11:42
  • 1
    I'm sending from chrome. What I do: 1. Start the program -> Started... Creating new Clien Socket #1 2. Access "http://localhost:8080/Q1" via chrome. 3. It looks like chrome sends 2 times because console log: .... Finished #1.. Creating #2.. Finished #2... Creating #3... – Wulf Mar 29 '19 at 11:51
  • Thanks a lot, Wufo. Now I found similar questions and looks like have an answer - could you go to chrome settings and check if you have option "Use a prediction service to load pages more quickly" turned OFF? (You can search options by it name). I had it on and when I turn it off, there where no more empty tcp packets. – Rustam A. Mar 30 '19 at 00:11
  • You aren't closing the accepted socket. – user207421 Mar 30 '19 at 01:03
  • Accepted socket is declared in "try" statement of "try with resources" block. So it is closed automatically when reading is finished (in normal way or when connection is closed). – Rustam A. Mar 30 '19 at 06:26

1 Answers1

-1

In a similar question I found a useful link saying it may be caused by "Predict network actions to improve page load performance" setting. So I tried turning off prediction settings one by one and it worked. In chrome version 73.0.3683.86 (Official Build) (64-bit) this behavior was caused by chrome setting "Use a prediction service to load pages more quickly" turned on.

So in just go to setting -> advanced -> privacy and security -> Use a prediction service to load pages more quickly and turn it OFF. (Or, if you don't have it in your chrome version, try turning off similar settings ).

Rustam A.
  • 809
  • 8
  • 15
  • Why would you want to turn it off? There isn't a problem here to be solved. – user207421 Mar 30 '19 at 01:06
  • To observe pure html protocol + to be sure it's not my code bug -> to understand how networking (and java networking) works. Priceless. And to help others that will fight to understand this behavior. Plus now I understand that empty packets is not rear situation in networking even without any attacks. – Rustam A. Mar 30 '19 at 07:24