본문 바로가기

Backend/Java

[JAVA] ObjectStream을 이용한 Socket 통신

728x90

 String으로만 소켓 통신을 한다면, 파일 같은 자료구조나 클래스는 보낼 수 없다.

따라서 소켓 통신을 할때 ObjectStream 으로 객체를 이용하여 통신을 하도록 하는 것이 좋다. 이때 객체는 Serializabe을 implements 한 직렬화한 클래스 여야 한다.

 


* 먼저 기본적으로 어떻게 동작하는지 살펴보겠다. 

단순히 서버에 로그인 한걸 알리는 코드이다.

public class Member implements Serializable {
	private static final long serialVersionUID = 1L;
	private String id;
	private String pwd;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
}
public class Server {
	public Server() {
		try {
			ServerSocket serverSocket = new ServerSocket(5000);
			System.out.println("서버 가동됨");
			Socket socket = serverSocket.accept();
			System.out.println("클라이언트 연결 접수됨...");
			System.out.println("[client] : " + socket.getInetAddress());

			InputStream is = socket.getInputStream();
			OutputStream os = socket.getOutputStream();
			ObjectInputStream ois = new ObjectInputStream(is);
			ObjectOutputStream oos = new ObjectOutputStream(os);

			Member member = (Member) ois.readObject();
			String id = member.getId();
			String pwd = member.getPwd();
			System.out.println("id : " + id + "\npwd : " + pwd);
			
			oos.writeObject(id+ " 님 로그인 성공.");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		new Server();
	}
}
public class Client {
	public Client() {
		try {
			Socket socket = new Socket("localhost", 5000);
			
			OutputStream os = socket.getOutputStream();
			InputStream is = socket.getInputStream();
			
			//OutputStream 먼저 뽑아야된다. 
			ObjectOutputStream oos = new ObjectOutputStream(os);
			ObjectInputStream ois = new ObjectInputStream(is);
	         
			Member member = new Member();
			member.setId("zeroco");
			member.setPwd("1234");

			oos.writeObject(member);
			
			String message;
			message = (String) ois.readObject();
			System.out.println(message);

		} catch (IOException e) {
			System.out.println("오류");
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			System.out.println("오류");
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		new Client();
	}
}

실행결과

# 실행시 주의해야할 점이 있다. 

 

OutputStream을 먼저 받아와야 실행시 오류가 나지 않는다. 

이 순서로 받아와야 한다. 순서가 틀릴 경우 아무것도 출력되지 않는다. 

 

			ObjectOutputStream oos = new ObjectOutputStream(os);
			ObjectInputStream ois = new ObjectInputStream(is);

위 코드는 문제가 있다. 타입의 경우 클라이어트에서는 String 으로 받아주고, Server에서는 Member라는 객체로 받아온다.  따라서 새로운 클래스를 만들어 한번더 감싸줘야 한다. 밑에 코드처럼 전달해야할 객체를 새롭게 만드는 것이다. 

File을 전달할때는 file만을 전달할 수 있고, text를 전달할때는 text만, member정보도 마찬가지로 전달할 정보를 골라 받을 수 있는 것이다. 어떻게 받을지는 Protocol 클래스를 만들어서 규칙을 정해야 한다. 

 

public class ObjectMessage implements Serializable {
    private String text;
    private File file;
    private Member member;
    private Protocol protocol;
    ...
}

 

728x90