0

With the following code an error occurs with reading the inputstream. I use the following code:

public void run() {
    try {
        SocketAddress sockaddr = new InetSocketAddress(nServer, nPort);
        nsocket = new Socket();
        nsocket.connect(sockaddr, 10 * 1000);
        if (nsocket.isConnected()) {
            nsocket.setSoTimeout(20 * 1000); 
            nis = nsocket.getInputStream();
            nos = nsocket.getOutputStream();
            if (nProtocol.equals("ntripv1")) {
                String requestmsg = "GET /" + nMountpoint + " HTTP/1.0\r\n";
                requestmsg += "User-Agent: NTRIP LefebureNTRIPClient/20131124\r\n";
                requestmsg += "Accept: */*\r\n" + "Connection: close\r\n";
                if (nUsername.length() > 0) {
                    requestmsg += "Authorization: Basic " + ToBase64(nUsername + ":" + nPassword) +"\r\n";
                }
                requestmsg += "\r\n";
                nos.write(requestmsg.getBytes());
            } else {
            }

            byte[] buffer = new byte[4096];
            int read = nis.read(buffer, 0, 4096);
            while (read != -1) {
                byte[] tempdata = new byte[read];
                System.arraycopy(buffer, 0, tempdata, 0, read);

                try {
                    dataMessenger.send(Message.obtain(null, MSG_NETWORK_GOT_DATA, tempdata));
                } catch (RemoteException e2) {
                }
                read = nis.read(buffer, 0, 4096);
            }
        }
    } catch (SocketTimeoutException ex) {
        try {
            dataMessenger.send(Message.obtain(null, MSG_NETWORK_TIMEOUT));
        } catch (RemoteException e2) {
        }
    } catch (Exception e) {
            LogMessage(e.getLocalizedMessage());
        e.printStackTrace();
    } finally {
        try {
            nis.close();
            nos.close();
            nsocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            dataMessenger.send(Message.obtain(null, MSG_NETWORK_FINISHED));
        } catch (RemoteException e2) {
        }
    }
}

The server sides works well with other applications. This code also make a connection with the server and gets some date but after a little while it quites at nis.read.

The codes is written with java 1.8 for android studio.

Does anyone have an idea to get all the information from the server and read all the information so it can be used in the application.

Update The error is given with the following line in the while-loop:

read = nis.read(buffer, 0, 4096); 

Update 2 The given error is: System.err: java.net.SocketException: Connection reset

hnefatl
  • 5,860
  • 2
  • 27
  • 49
Hanno K
  • 11
  • 5

1 Answers1

-1

Always .flush() on the outputstream when you are done sending a message. Think of it like a commit if you must, but its really just a buffering matter.

Secondly. it is very possible that the server is using http keep-alive and doesn't hangup (even though you put Connection: close, which is the default for HTTP/1.0 too); then it's the client side's job to hang up. To do so you need to detect the content is finished, so you must support both content-length response header if present, or 'chunked' transport encoding (likely if the answer is any larger than some arbitrary amount like a few kB). HTTP is a nice sport...!

You can also try the no http version on the GET line (implies HTTP 0.9) which I think simply doesn't support http keep-alive.

If the server is presuming keep-alive is on (see https://en.wikipedia.org/wiki/HTTP_persistent_connection) then that would explain the behavior. See also https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection

I recommend you install Wireshark and sniff the traffic. It's relatively intuitive to use. You will see if all data was sent and if the server really forgot to close (TCP FIN).

user2023577
  • 1,752
  • 1
  • 12
  • 23
  • I added the line 'nos.flush();' after 'nos.write(requestmsg.getBytes());' It only still didn't read /received all the information needed. – Hanno K Apr 29 '18 at 15:37
  • Socket output streams are unbuffered and do not need flushing. The `Connection: close` header must not be ignored by the peer. – user207421 Apr 29 '18 at 16:36
  • @EJP: we've seen bad servers before. I wouldn't be surprised that throwing 1.0 at one would be ignored, and thus it would assume 1.1, hence the default keep-alive. We don't know, the OP has to try something else. As for (un)buffered socket streams, you should really not count on absence of buffers, ever. Besides, unbuffered i/o of any kind (socket or disk) is a crime...in vast majority of cases. – user2023577 Apr 29 '18 at 19:01
  • @user2023577 Crime? Rubbish. The *only* buffered without stream in Java is, err, `BufferedOutputStream`. Java very sensibly makes buffering orthogonal to the target of the stream. I didn't say anything about 1.0 or 1.1. – user207421 May 18 '18 at 22:16