Solved

Error In using socket.getOutputStream

Posted on 2000-04-17
17
357 Views
Last Modified: 2008-02-01
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
Comment
Question by:UTEK
17 Comments
 
LVL 5

Expert Comment

by:msmolyak
ID: 2724349
A code snippet may help.
0
 

Author Comment

by:UTEK
ID: 2724372
Edited text of question.
0
 

Author Comment

by:UTEK
ID: 2724394
Edited text of question.
0
 
LVL 2

Expert Comment

by:stalefish
ID: 2724750
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
 
LVL 7

Expert Comment

by:Sasha_Mapa
ID: 2724771
hehe, an exception in Exception.<init> :-)
0
 

Author Comment

by:UTEK
ID: 2725241
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
 

Expert Comment

by:Ash_
ID: 2725382
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
 

Author Comment

by:UTEK
ID: 2727131
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:UTEK
ID: 2727922
Adjusted points from 75 to 100
0
 

Author Comment

by:UTEK
ID: 2731055
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
 

Author Comment

by:UTEK
ID: 2731060
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
 

Author Comment

by:UTEK
ID: 2731100
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
 

Author Comment

by:UTEK
ID: 2731128
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
 

Author Comment

by:UTEK
ID: 2731320
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
 

Author Comment

by:UTEK
ID: 2731447
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
 
LVL 3

Accepted Solution

by:
falter earned 100 total points
ID: 2731720
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
 

Author Comment

by:UTEK
ID: 2732313
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

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now