라봉이의 개발 블로그

Java Socket 클래스 상속하는 방법 본문

Java

Java Socket 클래스 상속하는 방법

Labhong 2019. 2. 10. 21:58
반응형
Java_Socket클래스_상속하는_법

Java Socket 상속하기

자바를 공부하는 와중에 채팅 서버를 구현해보고 싶었다. 링크

간단하게 Room을 구현하는 도중에 채팅방을 이용하는 유저에게 닉네임을 부여하고 싶었다.

유저 클래스를 생성하고 그 유저 클래스에 소켓 변수 필드를 만들어도 되지만 간단하게 하고 싶어서 Socket 클래스를 상속 받는 새로운 클래스를 만들어 닉네임과 아이디 필드를 생성하고 싶었다.

public class UserSocket extends Socket {
    private String uid;			// 아이디
    private String name;		// 닉네임
    private PrintWriter pw;		// 소켓 output stream 랩핑
    private BufferedReader br;	// 소켓 input stream 랩핑

    public void setIOStream() throws IOException{
        br = new BufferedReader(new InputStreamReader(this.getInputStream()));
        pw = new PrintWriter(new OutputStreamWriter(this.getOutputStream()));
    }
	...
}

 

하지만 웬걸 오류가 발생했다. 다음 코드에서 문제가 발생했다.

while(true) {
    UserSocket socket = serverSocket.accept();		// ERROR: 타입 에러!! 
    if( socket != null ) {
        ClientSocketHandler sr = new ClientSocketHandler(socket); // 소켓을 필드로 갖는 스레드를 생성합니다.
        t = new Thread(sr);
        t.start();
    }
}

 

ServerSocket 클래스의 인스턴스 serverSocket의 accept() 함수는 연결된 클라이언트의 Socket 인스턴스를 반환한다. 하지만 참조 변수는 UserSocket 타입이기 때문에 타입 에러가 났던 것이다.

안일했다. 이와 관련하여 자료가 있는 지 검색했다.

검색 결과 Socket 클래스를 상속한 새로운 Socket 클래스를 사용하기 위해서는 새로운 ServerSocket 클래스 또한 필요하다는 것을 알았다. 오라클 자료 / 스택오버플로 자료

 

그 전에 먼저 ServerSocket 클래스의 accept 메서드 코드를 직접 봤다.

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 Socket((SocketImpl) null);	// 소켓 인스턴스 생성
        implAccept(s);
        return s;
    }

 

소켓 인스턴스 생성 부분을 UserSocket으로 변경하면 되기 때문에 먼저 새로운 ServerSocket 클래스 CustomServerSocket을 생성한 뒤 accept() 메서드를 오버라이딩했다.

public class CustomServerSocket extends ServerSocket {
    public CustomServerSocket() throws IOException {
        super();
    }

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

    @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 UserSocket((SocketImpl) null);
        implAccept(s);
        ((UserSocket) s).setIOStream();
        return s;
    }
}

 

추가로 클라이언트가 서버에 소켓을 생성할 때 블록이 되는데 이 때, implAccept 함수에서 블록 되는 것을 알 수 있었다.

반응형
Comments