[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 438
  • Last Modified:

Error In using socket.getOutputStream

I am trying to write a servlet that will launch a telnet connection to a Unix server. However, I got some exceptions like this :

System.out.println==>Creating a socket to handle it
System.out.println==>Here is the data inside log_In
255|253|24|255|253| 255|253|#255|253|$
System.out.println==>Right before I get the output Stream!
java.lang.NullPointerException
at java.net.PlainSocketImpl.getOutputStrea(PlainSocketImpl.java, Compiled Code)
at java.lang.Exception.<init>(Exception.java, Compiled Code)
at java.lang.RuntimeException.<init>(RuntimeException.java, Compiled Code)
at java.lang.NullPointerException.<init>(NullPointerException.java, Compiled Code)
at java.io.FileOutputStream.<init>(FileOutputStream.java, Compiled Code)
at java.net.SocketOutputStream.<init>(SocketOutputStream.java, Compiled Code)
at java.net.PlainSocketImpl.getOutputStream(PlainSocketImpl.java, Compiled Code)
at java.net.Socket$2.run(Socket.java, Compiled Code)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.Socket.getOutputStream(Socket.java, Compiled Code)
at SocketMangmnt.sendData(SocketMangmnt.java, Compiled Code)
at SocketMangmnt.sUnix(SocketMangmnt.java, Compiled Code)

I create a plain socket which connect to the telnet port of my Unix server like this :
         loginsoc = new Socket(host, 23);
         loginsoc.setTcpNoDelay(true);
         System.out.println("Creating a socket to handle it");

Then, I read the inputstream of that socket and I got those
255|253|24....(without the '|').  That should be the negotiation of the telnet protocol. Now, I use my sendData method (show below) to send a 3-byte data back to the Unix server and I got the Exception immediately.

private boolean sendData(byte bytestrm[], int size)
  {
      try
      {
          System.out.println("Right before I get the output Stream!");
          DataOutputStream doutstrm = new DataOutputStream(loginsoc.getOutputStream());
          doutstrm.write(bytestrm, 0, size);
          //TTTTTTTTTT  Print out the data it sends out
          System.out.println("Here is the data being sent out");
          for (int i=0;i<size;i++)
          {
              if (((int)bytestrm[i]>=32) && ((int)bytestrm[i]<=127))
                  System.out.print((char)bytestrm[i]);
              else
                  System.out.print(bytestrm[i]+"|");
          }

          //TTTTTTTTTTTT
          doutstrm.close();
          System.out.println(" --");
      }
      catch (IOException ioe)
      {
          return false;
      }
      return true;
  }

I don't know what causes the problem. It doesn't seem it is proxy server/firewall problem.  When I check the the socket properties, it still bounds to the local port and the remote telnet port.

I would be appreciated if somebody can get me a hand on this.
Thank you very much.
0
UTEK
Asked:
UTEK
1 Solution
 
msmolyakCommented:
A code snippet may help.
0
 
UTEKAuthor Commented:
Edited text of question.
0
 
UTEKAuthor Commented:
Edited text of question.
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
stalefishCommented:
Can you do a check before you use the OutputStream to make sure it is not null?

if(loginsoc == null) System.out.println("Login Socket is null");
....

if(doutstrm == null) System.out.println("DoutStrm is Null");
0
 
Sasha_MapaCommented:
hehe, an exception in Exception.<init> :-)
0
 
UTEKAuthor Commented:
Hm....I know the socket is not null. I can print out the localaddress and the Inetaddress.  The problem is most likely to be the socket.getOutputStream somehow returns a null pointer. But it doesn't make sense.
0
 
Ash_Commented:
what are you running the servlets on?? platform??

in the stack trace,this line is present :

at java.security.AccessController.doPrivileged(Native Method)

does the servlet runner you are using have a servlet "sandbox" like a applet sandbox ??

finally, try placing the servlet code in the servlet runner's classpath ( not the servlets directory)
0
 
UTEKAuthor Commented:
I am using the ServletExec from New Atlanta on NT workstation with peer web Service 3.0.

I have checked the security of my servlet runner and it grants all premittions to the local servlets.  If there is a servlet sandbox, it shouldn't allow me to connect to anything.
0
 
UTEKAuthor Commented:
Adjusted points from 75 to 100
0
 
UTEKAuthor Commented:
I finally I find out the source of the problem, but I don't know why it happenes like that. Does anybody know why?

I wrote a small test program like this:
<pre>
import java.io.*;
import java.net.*;

public class testconnection
{

  public testconnection() {
  }

  public static void main(String[] args)
  {
      Socket loginsoc;
      DataInputStream instrm;
      DataOutputStream doutstrm;

      try
      {
          loginsoc = new Socket("127.56.1.3", 23);
          loginsoc.setTcpNoDelay(true);
          System.out.println("Creating a socket to handle it");
 //<b>Line A</b>    instrm = new DataInputStream(loginsoc.getInputStream());
 //<b>Line B</b>    doutstrm = new DataOutputStream(new BufferedOutputStream(loginsoc.getOutputStream()));
      }
      catch (Exception e)
      {
          System.out.println("More likely socket Exception");
          return;
      }

      try
      {
          byte bstrm[] = new byte[1024];
 //<b>Line C</B>   DataInputStream instrm = new DataInputStream(new BufferedInputStream(loginsoc.getInputStream()));
 //<b>Line D</B>   instrm = new DataInputStream(loginsoc.getInputStream());
          int counter = instrm.read(bstrm);
          //KT DB
          instrm.close();

          /*Read the instream byte by byte and put them into an int array
            Since C is unsigned byte but java is signed byte, we have to use
            int which is 32-bit to keep a one byte information to avoid loss of
            info */
          if (counter <= 0)
          {
              System.out.println("Nothing in the in stream");
              return;
          }

          //TTTTTTTTTT  Print out the data it got
          System.out.println("Here is the data I get");
          for (int i=0;i<counter;i++)
          {
              if ((bstrm[i]>=32) && (bstrm[i]<=127))
                  System.out.print((char)bstrm[i]);
              else
                  System.out.print(bstrm[i]+"|");
          }
          System.out.println(" ");
          //TTTTTTTTTTTT
      }
      catch (Exception e)
      {
          System.out.println("Exception" + e.getClass().getName()+ ": " + e.getMessage());
          return;
      }


       try
      {
          byte bytestrm[] = {(byte)255, (byte)254, (byte)24};
          System.out.println("Right before I get the output Stream!");
 //<b>Line E</B>   DataOutputStream doutstrm = new DataOutputStream(loginsoc.getOutputStream());
 //<b>Line F</B>   doutstrm = new DataOutputStream(new BufferedOutputStream(loginsoc.getOutputStream()));
          doutstrm.write(bytestrm, 0, 3);
          //TTTTTTTTTT  Print out the data it sends out
          System.out.println("Here is the data being sent out");
          for (int i=0;i<bytestrm.length;i++)
          {
              if (((int)bytestrm[i]>=32) && ((int)bytestrm[i]<=127))
                  System.out.print((char)bytestrm[i]);
              else
                  System.out.print(bytestrm[i]+"|");
          }

          //TTTTTTTTTTTT
          doutstrm.close();
          System.out.println(" --");
      }
      catch (IOException ioe)
      {
          return;
      }

  }
}
0
 
UTEKAuthor Commented:
I finally I find out the source of the problem, but I don't know why it happenes like that. Does anybody know why?

I wrote a small test program like this:
<pre>
import java.io.*;
import java.net.*;

public class testconnection
{

  public testconnection() {
  }

  public static void main(String[] args)
  {
      Socket loginsoc;
      DataInputStream instrm;
      DataOutputStream doutstrm;

      try
      {
          loginsoc = new Socket("127.56.1.3", 23);
          loginsoc.setTcpNoDelay(true);
          System.out.println("Creating a socket to handle it");
 //<b>Line A</b>    instrm = new DataInputStream(loginsoc.getInputStream());
 //<b>Line B</b>    doutstrm = new DataOutputStream(new BufferedOutputStream(loginsoc.getOutputStream()));
      }
      catch (Exception e)
      {
          System.out.println("More likely socket Exception");
          return;
      }

      try
      {
          byte bstrm[] = new byte[1024];
 //<b>Line C</B>   DataInputStream instrm = new DataInputStream(new BufferedInputStream(loginsoc.getInputStream()));
 //<b>Line D</B>   instrm = new DataInputStream(loginsoc.getInputStream());
          int counter = instrm.read(bstrm);
          //KT DB
          instrm.close();

          /*Read the instream byte by byte and put them into an int array
            Since C is unsigned byte but java is signed byte, we have to use
            int which is 32-bit to keep a one byte information to avoid loss of
            info */
          if (counter <= 0)
          {
              System.out.println("Nothing in the in stream");
              return;
          }

          //TTTTTTTTTT  Print out the data it got
          System.out.println("Here is the data I get");
          for (int i=0;i<counter;i++)
          {
              if ((bstrm[i]>=32) && (bstrm[i]<=127))
                  System.out.print((char)bstrm[i]);
              else
                  System.out.print(bstrm[i]+"|");
          }
          System.out.println(" ");
          //TTTTTTTTTTTT
      }
      catch (Exception e)
      {
          System.out.println("Exception" + e.getClass().getName()+ ": " + e.getMessage());
          return;
      }


       try
      {
          byte bytestrm[] = {(byte)255, (byte)254, (byte)24};
          System.out.println("Right before I get the output Stream!");
 //<b>Line E</B>   DataOutputStream doutstrm = new DataOutputStream(loginsoc.getOutputStream());
 //<b>Line F</B>   doutstrm = new DataOutputStream(new BufferedOutputStream(loginsoc.getOutputStream()));
          doutstrm.write(bytestrm, 0, 3);
          //TTTTTTTTTT  Print out the data it sends out
          System.out.println("Here is the data being sent out");
          for (int i=0;i<bytestrm.length;i++)
          {
              if (((int)bytestrm[i]>=32) && ((int)bytestrm[i]<=127))
                  System.out.print((char)bytestrm[i]);
              else
                  System.out.print(bytestrm[i]+"|");
          }

          //TTTTTTTTTTTT
          doutstrm.close();
          System.out.println(" --");
      }
      catch (IOException ioe)
      {
          return;
      }

  }
}
</PRE>
0
 
UTEKAuthor Commented:
LINE C AND LINE E have been commented out.

See above for the test program
If I do the Socket.getOutputStream at Line B, it works fine without any exceptions. But If I do it at Line F, it gets me the null pointer exception.

On the other, my Socket.getInputStream can be either on Line A or Line D, both work fine.

Weird? Why?
0
 
UTEKAuthor Commented:
LINE C AND LINE E have been commented out.

See above for the test program
If I do the Socket.getOutputStream at Line B, it works fine without any exceptions. But If I do it at Line F, it gets me the null pointer exception.

On the other, my Socket.getInputStream can be either on Line A or Line D, both work fine.

Weird? Why?
0
 
UTEKAuthor Commented:
LINE C AND LINE E have been commented out.

See above for the test program
If I do the Socket.getOutputStream at Line B, it works fine without any exceptions. But If I do it at Line F, it gets me the null pointer exception.

On the other, my Socket.getInputStream can be either on Line A or Line D, both work fine.

Weird? Why?
0
 
UTEKAuthor Commented:
LINE C AND LINE E have been commented out.

See above for the test program
If I do the Socket.getOutputStream at Line B, it works fine without any exceptions. But If I do it at Line F, it gets me the null pointer exception.

On the other, my Socket.getInputStream can be either on Line A or Line D, both work fine.

Weird? Why?
0
 
falterCommented:
UTEK,

I think, the problem is instrm.close(),
this will not only close the InputStream it also closes the FileDescriptor of the Socket, because the InputStream and the OutputStream are based on the same FileDescriptor.
The Socket is holding this FileDescriptor in its SocketImpl.
 InputStream and OutputStream are only References to the same FileDescriptor, changing this referenced Object will of cause be visible in InputStream, OutputStream and the Socket.
So closing the Socket will also close OutputStream and InputStream. Closing the InputStream will close ...

If you have access to the Java sources have a look at
java.net.Socket
java.net.SocketImpl
java.net.PlainSocketImpl

Hope this helps a little bit!

regards
jf
0
 
UTEKAuthor Commented:
Thanks falter and Thanks you guys.
It seems it is my InputStrem.close() causing the problem. It also causes an socket.exception : descriptor not a socket being thrown.
0

Featured Post

2018 Annual Membership Survey

Here at Experts Exchange, we strive to give members the best experience. Help us improve the site by taking this survey today! (Bonus: Be entered to win a great tech prize for participating!)

Tackle projects and never again get stuck behind a technical roadblock.
Join Now