如何接受自定义套接字?

时间:2016-06-26 08:14:39

标签: java sockets serversocket

我正在体验套接字& ServerSockets,我从java.net.Socket(CustomSocket)创建了一个子类,我想知道当ServerSocket收到类似的连接时,我该怎么做才能重新创建Socket:

CustomSocket cs = CustomServerSocket.accept();

我需要“cs”与请求连接到CustomServerSocket的CustomSocket相同,因为我需要在服务器端知道请求连接的套接字的String ID:

cs.getId(); //(shoud return the ID, but returns an empty String)

以下是CustomServerSocket代码:

        package negocio;

    import java.io.IOException;
    import java.net.Socket;
    import java.net.SocketException;
    import java.net.UnknownHostException;

    public class CustomSocket extends Socket{
        private String id;


        public CustomSocket(String host, int puerto, String id) throws UnknownHostException, IOException{
            super(host, puerto);
            this.id = id;
        }

        public CustomSocket(String host, int puerto) throws UnknownHostException, IOException{
            super(host, puerto);
            this.id = "";

        }

        public CustomSocket(){
            super();
            this.id = "";
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String toString(){
            return "cSocket ID: "+this.id;
        }
    }

以下是CustomServerSocket代码:

package negocio;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.SocketException;

public class CustomServerSocket extends ServerSocket {



    public CustomServerSocket(int puerto) throws IOException{
        super(puerto);
    }

    @override
    public CustomSocket accept() throws IOException{
        if(this.isClosed()){
            throw new SocketException("Socket is closed");
        }
        if(!this.isBound()){
            throw new SocketException("Socket is not bound yet");
        }   
        CustomSocket ms = new CustomSocket();
        this.implAccept(ms);
        return ms;
    }
}

2 个答案:

答案 0 :(得分:1)

首先,考虑一下你需要的关系。您的CustomSocket似乎是客户端/服务器应用程序中的客户端。您确定必须使用是 - 关系吗?您的自定义类旨在将数据发送到ServerSocket。它应该拥有 Socket来完成它的工作,但是没有必要一个Socket。因此, has-a 关系是设计应用的首选方式。 通常,请避免从非为此目的设计的类中进行子类化。 SocketServer和Socket不是为子类设计的(通常,如果类是为子类设计的,则在该类的文档中指出)。这种子类没有任何好处。相反,您的应用程序变得不那么灵活了。

第二,Socket和ServerSocket使用Streams相互传输数据。只需将Stream中所需的所有必要信息从Socket传输到ServerSocket。

为了简洁起见,我避免使用样板代码。

public class Client {
private String id;
private Socket socket;

public Client(final Socket socket, final String id) {
    this.socket = socket;
    this.id = id;
}

void sendData() {
    try (DataOutputStream idToSend = new DataOutputStream(socket.getOutputStream())) {

        idToSend.writeUTF(this.id);
        idToSend.flush();

    } catch (IOException e) {
    }
}
}

和服务器:

public class Server {

private ServerSocket serverSocket;

Server(final int port) throws IOException {
    serverSocket = new ServerSocket(port);
}

void receiveData(Socket socket) {
    try (DataInputStream idStream = new DataInputStream(socket.getInputStream())) {

        String id = idStream.readUTF();
        Client client = new Client(socket, id);

    } catch (IOException e) {
    }
}
}

最后一个。您必须了解ServerSocket和Socket类的主要用途。简而言之,第一个等待通过网络进入的请求。第二个是第一个的终点。您不会在ServerSocket端接收套接字既不是标准也不是自定义接受套接字。相反,您将在它们之间建立连接。有一系列流类传输数据。只需使用它们。如果需要执行某些验证,请为此目的编写ServerProtocol类。

答案 1 :(得分:0)

您需要覆盖accept()以创建带有CustomObject参数的SocketImpl,然后使用它调用implAccept()并将其返回。

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