Homebrewed SocketImplFactory导致空指针

时间:2012-03-17 03:50:16

标签: java sockets

正如标题描述的那样,我有一个自制的SocketImplFactory导致我的代码中断

(ServerSocket).close();

我的智慧结束了。我现在发布所有相关文件,以及两次运行。

首先,server2.java:

import java.net.Socket;
import java.net.ServerSocket;

public class server2 {
  public static void main(String[] argv){

    if(argv.length!= 1){
      System.err.println("usage: server1 <hostport>");
      System.exit(1);
    }

    try{
      TCPStart.start();

      ServerSocket sock = new ServerSocket(Integer.parseInt(argv[0]));

      sock.close();
      /*Socket connSock = sock.accept();

      System.out.println("got socket "+connSock);

      Thread.sleep(1*1000);
      connSock.close();
      Thread.sleep(35*1000);            */
    }
    catch(Exception e){
      System.err.println("Caught exception "+e);
      e.printStackTrace();
    }
  }
}

下一个TCPStart.java:

import java.net.*;


//---------------------------------------------------
//
// class TCPStart
//
// this is the hub of the entire socket implementation.
// all modules are initialized here.
//
//
// code that runs on TOP of this whole implementation will
// be put in this file, as separate threads.
//
// to start our implementation of TCP, type
//   java TCPStart <UDP port #>
//
//
//---------------------------------------------------
class TCPStart {

  public final static String PORTRESOURCE = "UDPPORT";
  public final static String LOSSRATERESOURCE = "LOSSRATE";

  static public void start() {

    // check command line args
    if (System.getProperty(PORTRESOURCE)==null) {
      System.err.println("Must set "+PORTRESOURCE+" for UDP port to use with "+
             "-D"+PORTRESOURCE+"=<num>");
      System.exit(1);
    }        


    // this number will initialize what port # you want your UDP
    // wrapper to run on.
    int portForUDP = Integer.parseInt(System.getProperty(PORTRESOURCE));


    // initialize TCPWrapper's port number for UDP wrapping
    TCPWrapper.setUDPPortNumber( portForUDP );


    // initialize more TCPWrapper stuff here, if you want to test packet
    // dropping, or if you want to change the sending-rate limit


    // create an instance of the Demultiplexer
    Demultiplexer D = new Demultiplexer( portForUDP );

    // create an instance of OUR SocketImplFactory
    StudentSocketImplFactory myFactory = new StudentSocketImplFactory(D);


    // tell all Socket objects of this program to use OUR
    // implementation of SockImpl
    try {
      Socket.setSocketImplFactory( myFactory );
      ServerSocket.setSocketFactory( myFactory ); //This is the problem line.
    } catch (Exception e) {
      System.out.println(e);
      System.exit(1);
    }


    // start the demultiplexer
    D.start();

    if (System.getProperty(LOSSRATERESOURCE)!=null) {
      TCPWrapper.dropRandomPackets
    (System.currentTimeMillis(),
     Double.parseDouble(System.getProperty(LOSSRATERESOURCE)));
    }        


  }
}

最后,StudentSockImplFactory.java

import java.net.*;

//---------------------------------------------------
//
// class StudentSocketImplFactory
//
// this object is what actually creates each INSTANCE of a
// SocketImpl object.  In TCPStart.main(), we call
//
//     Socket.setSocketImplFactory( new StudentSocketImplFactory(D) );
//
// (this is a static function)
// so, when we create a java Socket, it will make a call to
// createSocketImpl(), and the Socket will use OUR code!!!
//
//---------------------------------------------------
class StudentSocketImplFactory implements SocketImplFactory {

    // the Demultiplexer has to be known to every SocketImpl, so that it
    // can communicate with it
    private Demultiplexer D;


    public StudentSocketImplFactory(Demultiplexer D) {
        super();
        this.D = D;
    }

    // Socket object makes this call to get one instance of SocketImpl.
    // reminder: each socket will get a DIFFERENT instance of
    // SocketImpl. this is GOOD, so that we will have one TCPConnection
    // for each Socket!!
    public SocketImpl createSocketImpl() {
        return ( new StudentSocketImpl(D) );
    }
}

如果我注释掉上述问题,那么一切正常,直到我尝试实际接受连接。运行失败:

$ java -DUDPPORT=12345 server2 54321
java.lang.NullPointerException: null buffer || null address

提前感谢所有帮助。

1 个答案:

答案 0 :(得分:1)

我找到了自己的答案,这对很多人来说可能没什么意义,但我会发布它,以便如果其他人有类似的问题,他们就能够在Google方框上找到这个答案:

原来,

(ServerSocket).close();

致电

(SocketImpl).close();

我以前没有意识到这一点。由于我的工厂被重置为使用不同的SocketImpl(即我写的那个),当我尝试发送Fin包时,可以理解的是没有人发送它,所以它给了空地址错误。只是去展示,有时你必须在问题上睡觉,答案将在早上出现。