0

我编写了一个扩展 Socket 类的类 - 目的是保留常规套接字的所有方法,同时添加我自己的两个方法:

public class ClientSocket extends Socket{

private long lastOnline;

public ClientSocket() {
      super();
}

public long getLastOnline() {
    return lastOnline;
}

public void setLastOnline(long lastOnline) {
    this.lastOnline = lastOnline;
}

当我尝试初始化此类的新实例并向其添加打开的套接字时,我做错了(或者我可能有问题),它告诉我无法将套接字设置为ClientSocket 对象(虽然它扩展了 Socket):

ClientSocket socket = serverSocket.accept();

我该如何解决这个问题?谢谢!

4

3 回答 3

7

serverSocket.accept()返回一个普通的Socket,而不是一个ClientSocket
AClientSocket 是 a Socket,但反之则不然。

于 2012-05-13T12:40:22.713 回答
1

您可以使用组合

public class ClientSocket {

    private final Socket socket;
    private long lastOnline;

    public ClientSocket(Socket socket) {
        this.socket = socket;
    }

    public long getLastOnline() {
         return lastOnline;
    }

    public void setLastOnline(long lastOnline) {
        this.lastOnline = lastOnline;
    }

    ...
}

然后创建一个ClientSocket:

ClientSocket clientSocket = new ClientSocket(serverSocket.accept());
于 2012-05-13T13:39:44.627 回答
0

作为记录,我相信您的特殊情况最好通过组合而不是继承来解决。Aka,最好包装通过检索的套接字accept,而不是像现在一样尝试子类化。有一本好书(Joshua Bloch 的 Effective Java)描述了何时使用组合而不是继承。阅读后,如果您认为继承适合您的用例,您可以为套接字实现它,如下所示

更专业的套接字实现:

public class AuditableClientSocket extends Socket {
   private long lastPacketReceived = -1;

   // Constructors removed for brevity. Add them back here

   public long getLastPacketReceived() {
      return lastPacketReceived;
   }

   protected void setLastPacketReceived(long lastPacketReceived) {
      this.lastPacketReceived = lastPacketReceived;
   }

   public String formatLastReceived() {
      if (lastPacketReceived < 0)
         return "Never";

      return new Date(lastPacketReceived).toString();
   }
}

能够创建专用套接字的服务器套接字实现:

public class AuditableClientServerSocket extends ServerSocket {

   // Constructors removed for brevity. Add them back here

   @Override
   public Socket accept() throws IOException {
      if (isClosed())
         throw new SocketException("Socket is closed");
      if (!isBound())
         throw new SocketException("Socket is not bound yet");
      final Socket s = new AuditableClientSocket((SocketImpl) null);
      implAccept(s);
      return s;
   }
}

测试类:

public class AuditableClientServer implements Runnable {
   public static void main(String[] args) {
      AuditableClientServer server = new AuditableClientServer();
      new Thread(server).start();
   }

   private AuditableClientServerSocket serverSocket = null;

   public void run() {

      try {
         serverSocket = new AuditableClientServerSocket(5656);
         final AuditableClientSocket sock = (AuditableClientSocket) serverSocket.accept();
         System.out.printf(
               "Client connected at %s. Last received packet at %s",
               new Date(), sock.formatLastReceived());

         sock.close();
         serverSocket.close();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

public class AuditableClient {
   public static void main(String[] args) {
      try {
         Socket s = new Socket("localhost", 5656);
         s.close();
      } catch(IOException ioe) {
         ioe.printStackTrace();
      }
   }
}
于 2012-05-13T13:40:19.587 回答