简体   繁体   English

自制SocketImplFactory导致空指针

[英]Homebrewed SocketImplFactory Causing Null Pointer

Exactly as the title describes, I've got a homebrewed SocketImplFactory that is causing my code to break on 就像标题所描述的一样,我有一个自制的SocketImplFactory,它导致我的代码中断

(ServerSocket).close();

I'm at my wits end. 我机智。 I'm now posting all the relevant files, as well as two runs. 我现在要发布所有相关文件以及两次运行。

First, server2.java: 首先,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();
    }
  }
}

Next TCPStart.java: 下一个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)));
    }        


  }
}

And, Finally, StudentSockImplFactory.java 最后,是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) );
    }
}

If I comment out the aforementioned trouble line, it all works well, until I try to actually accept connections. 如果我注释掉前面提到的问题线,那么在我尝试实际接受连接之前,一切都很好。 A failed Run: 运行失败:

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

Thanks in advance for all the help. 在此先感谢您提供的所有帮助。

I found out my own answer, which probably won't make sense to many people, but I'm going to post it so that if Anyone else has a similar Problem, they'll be able to find this answer on the Google box: 我找到了自己的答案,这对很多人来说可能没有什么意义,但我将其发布,以便其他人遇到类似的问题时,他们也可以在Google框中找到以下答案:

Turns out, 原来,

(ServerSocket).close();

Calls 来电

(SocketImpl).close();

Which I did not previously realize. 我以前没有意识到。 Since my factory was being reset to use a different SocketImpl (namely, the one I'm writing), when I tried to send a Fin Packet, it understandably didn't have anyone to send it to, so it gave a null address error. 由于我的工厂被重置为使用其他SocketImpl(即我正在编写的SocketImpl),因此当我尝试发送Fin数据包时,可以理解没有人将其发送给它,因此给出了空地址错误。 Just goes to show, sometimes you have to sleep on a problem, and the answer will come in the morning. 只是显示一下,有时您需要解决一个问题,答案会在早上出现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM