'Serializable'에 해당되는 글 3건

  1. 2010.03.10 [Java Communication] Reference (2)
  2. 2010.03.09 [Java Communication] Server & Client
  3. 2010.03.09 [Java Communication] 메세지 클래스
Project2010.03.10 11:12


  • yhg.comm.message
    • Message
      • int getType()
        • 클라이언트 종류 얻기
      • int getNumber()
      • void setNumber(int num)
        • 클라이언트 번호 설정
    • MSGBoolean extends Message
      • void setTrue()
      • void setFalse()
      • boolean get()
    • MSGChat extends Message
      • void setMessage(String str)
        • 채팅 메세지 설정
      • String getMessage()
    • MSGEnterClient extends Message
      • 서버에 클라이언트가 접속하였을 경우 이미 접속한 다른 클라이언트들에게 전송하는 메세지
    • MSGLeaveClient extends Message
      • 서버에 접속되어있는 클라이언트가 접속이 끊겼을 경우 다른 클라이언트들에게 전송하는 메세지
  • yhg.comm.server
    • ICommClientManagerEvent
      • void onReceiveMessage(CommClientManager cm, Message msg)
        • 서버가 클라이언트로부터 메세지를 받았을 때의 이벤트
      • void onSendMessage(CommClientManager cm, Message msg)
        • 서버가 클라이언트에게 메세지를 보낼때의 이벤트
    • ICommServerEvent
      • void onEnterClient(CommClientManager cm)
        • 서버에 클라이언트가 접속하였을 때의 이벤트
      • void onLeaveClient(CommClientManager cm)
        • 서버에서 클라이언트가 떠났을 때의 이벤트
    • CommClientManager
      • CommClientManager(CommServer server, Socket sock) throws IOException
      • void send(Message msg) throws IOException
        • 클라이언트에게 메세지 전송
      • Socket getSocket()
        • 클라이언트 소켓 얻기
      • InetAddress getLocalAddress()
        • 클라이언트 주소 얻기 (소켓을 얻어서 할경우 연결이 끊기면 정보를 잃기 때문에...)
    • CommServer
      • CommServer(int port) throws IOException
      • void setClientManagerEvent(ICommClientManagerEvent rec)
        • 이벤트 설정
      • void setServerEvent(ICommServerEvent apt)
        • 이벤트 설정
      • void sendAll(Message msg) throws IOException
        • 모든 클라이언트에게 메세지 전송
      • void sendAll(int num, Message msg) throws IOException
        • 지정한 클라이언트를 제외하고 메세지 전송
      • void sendTo(int num, Message msg) throws IOException
        • 지정한 하나의 클라이언트에게 메세지 전송
      • int getClientNumber(CommClientManager cm)
        • 클라이언트 번호 얻기
  • yhg.comm.client
    • ICommClientEvent
      • void onReceiveMessage(Message msg)
        • 클라이언트가 서버로부터 메세지를 받았을 경우 이벤트
      • void onSendMessage(Message msg)
        • 클라이언트가 서버로 메세지를 전송할 경우 이벤트
    • CommClient
      • CommClient(String address, int port) throws UnknownHostException, IOException
      • void send(Message msg) throws IOException
        • 서버로 메세지 전송
      • void setClientEvent(ICommClientEvent evt)
        • 이벤트 설정
      • Socket getSocket()
        • 서버 소켓 얻기

메세지를 추가할 경우 Message의 stataic변수를 만들면됩니다.
그리고 상속받는 Message클래스의 생성자에서 타입을 지정해야 합니다.

public으로 사용할수 있는 메소드등을 정리한 겁니다.

소스파일도 같이 올립니다.

신고
Posted by 초프(초보 프로그래머)
Project2010.03.09 19:09

스레드가 어려움
몇시간을 해도 통신이 잘 안됨
등등

프로젝트를 진행하면서 이런 문제점이 생길거 같아서 미리 이클래스를 작성 하였습니다.

현재로도 하나의 테스트 프로그램만을 작성해 보았으므로

다른 프로그램에서는 어떻게 동작할지는 예상할 수 없습니다 ^^;;

작성해본 간단한 채팅 프로그램의 서버와 클라이언트 입니다.

이것만 보셔도 대충 이해가 가실거라고 생각 됩니다.

--- Server ---

package yhg.comm.test;

import java.io.IOException;

import yhg.comm.message.MSGChat;
import yhg.comm.message.MSGEnterClient;
import yhg.comm.message.MSGLeaveClient;
import yhg.comm.message.Message;
import yhg.comm.server.CommClientManager;
import yhg.comm.server.CommServer;
import yhg.comm.server.ICommClientManagerEvent;
import yhg.comm.server.ICommServerEvent;

public class ChatServer {
	public static void main(String[] args){
		try {
			final CommServer server = new CommServer(1000);
			
			server.setClientManagerEvent(new ICommClientManagerEvent(){
				public void onReceiveMessage(CommClientManager cm, Message msg) {
					int sender = server.getClientNumber(cm);
					MSGChat content = (MSGChat)msg;
					
					System.out.println("["+cm.getSocket().getLocalAddress().toString()+"] receive Message : "+msg);
					
					switch(msg.getType()){
						case Message.type_MSGChat:
							MSGChat chat = new MSGChat();
							chat.setMessage("["+sender+"] "+content.getMessage());
							
							try {
								server.sendAll(sender, chat);
							} catch (IOException e) {
								e.printStackTrace();
							}
							break;
					}
				}
				
				public void onSendMessage(CommClientManager cm, Message msg) {
					
				}
			});
			server.setServerEvent(new ICommServerEvent(){
				public void onEnterClient(CommClientManager cm) {
					int newClient = server.getClientNumber(cm);
					MSGEnterClient ent = new MSGEnterClient();
					ent.setNumber(newClient);
					
					try {
						server.sendAll(newClient, ent);
						System.out.println("["+cm.getLocalAddress().toString()+"] Connect");
					} catch (IOException e) {
						e.printStackTrace();
					}
				}

				public void onLeaveClient(CommClientManager cm) {
					int clientNum = server.getClientNumber(cm);
					MSGLeaveClient ent = new MSGLeaveClient();
					ent.setNumber(clientNum);
					
					try {
						server.sendAll(clientNum, ent);
						System.out.println("["+cm.getLocalAddress().toString()+"] Disconnect");
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			});
			
			server.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

--- Client ---

package yhg.comm.test;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.NoSuchElementException;
import java.util.Scanner;

import yhg.comm.client.CommClient;
import yhg.comm.client.ICommClientEvent;
import yhg.comm.message.MSGChat;
import yhg.comm.message.MSGEnterClient;
import yhg.comm.message.MSGLeaveClient;
import yhg.comm.message.Message;

public class ChatClient {
	public static void main(String[] args){
		try {
			CommClient client = new CommClient("127.0.0.1",1000);
			client.setClientEvent(new ICommClientEvent(){
				public void onReceiveMessage(Message msg) {
					try{
						switch(msg.getType()){
							case Message.type_MSGEnterClient:
								MSGEnterClient enterMsg = (MSGEnterClient)msg;
								System.out.println("-- "+enterMsg.getNumber()+" 님이 입장 하였습니다 --");
								break;
							case Message.type_MSGLeaveClient:
								MSGLeaveClient leaveMsg = (MSGLeaveClient)msg;
								System.out.println("-- "+leaveMsg.getNumber()+" 님이 퇴장 하였습니다 --");
							case Message.type_MSGChat:
								MSGChat chat = (MSGChat)msg;
								System.out.println(chat.getMessage());
								break;
						}
					} catch(ClassCastException e){}
				}

				public void onSendMessage(Message msg) {
					
				}
			});
			client.start();
			
			Scanner scanner = new Scanner(System.in);
			
			while(true){
				String input = scanner.next();
				
				if(!input.equals("")){
					MSGChat chat = new MSGChat();
					chat.setMessage(input);
					client.send(chat);
				}
			}
		} catch (UnknownHostException e) {
		} catch (IOException e) {
		} catch (NoSuchElementException e){
		}
	}
}

문제점이 있으시면 바로바로 알려주세요~

신고
Posted by 초프(초보 프로그래머)
Project2010.03.09 18:59

팀프로젝트를 미리 준비하면서 만들어 본 통신 클래스...;

복잡했던 스레드 이런걸 단방에 해결해 주도록 만들었습니다.

1:n의 통신이 가능하게 하였으며... 중요 클래스를 건드리지 않고

이벤트를 작성하는 형식으로 만들어 보았습니다.

아직 부족한게 많고 허접할거 같지만... 


일단 처음으로 통신과정 중에 왔다 갔다할 객체를 메세지라고 하여 만들었습니다.

그리고 그 메세지 클래스를 상속받아서 구체적인 메세지들이 구현이 됩니다.

--- Message.Java ---

package yhg.comm.message;

import java.io.Serializable;

/**
 * 통신 중에 주고 받는 메세지
 * 
 * @author	Yoon HyunGook
 * @since	2010-03-08
 */
public class Message implements Serializable {
	private static final long serialVersionUID = 5795268628773097426L;
	private int number;
	private int type;

	/**
	 * 미리 정해진 메세지 타입
	 * 필요시에 추가 하면됨
	 */
	public final static int type_MSGTable = 1;
	public final static int type_MSGBoolean = 2;
	public final static int type_MSGChat = 3;
	public final static int type_MSGEnterClient = 4;
	public final static int type_MSGLeaveClient = 5;
	
	/**
	 * 생성자
	 * 
	 * @author	Yoon HyunGook
	 * @since	2010-03-08
	 */
	public Message(){
		type = 0;
	}
	
	/**
	 * 메세지 타입 설정
	 * 
	 * @author	Yoon HyunGook
	 * @since	2010-03-08
	 * 
	 * @param	메세지 타입
	 */
	protected void setType(int type){
		this.type = type;
	}
	
	/**
	 * 메세지 타입 얻기
	 * 
	 * @author	Yoon HyunGook
	 * @since	2010-03-08
	 * 
	 * @return	메세지 타입
	 */
	public int getType(){
		return type;
	}
	
	/**
	 * 클라이언트 번호 얻기
	 * 
	 * @author	Yoon HyunGook
	 * @since	2010-03-08
	 * 
	 * @return	클라이언트 번호
	 */
	public int getNumber(){
		return number;
	}
	
	/**
	 * 클라이언트 번호 설정
	 * 
	 * @author	Yoon HyunGook
	 * @since	2010-03-08
	 * 
	 * @param	클라이언트 번호
	 */
	public void setNumber(int num){
		this.number = num;
	}
	
	/**
	 * 객체 출력
	 * 
	 * @author	Yoon HyunGook
	 * @since	2010-03-08
	 * 
	 * @return	String
	 */
	public String toString(){
		return Integer.toString(getNumber());
	}
}


--- MSGChat.java ---
package yhg.comm.message;

/**
 * 채팅 메세지
 * 
 * @author	Yoon HyunGook
 * @since	2010-03-08
 */
public class MSGChat extends Message{
	private static final long serialVersionUID = 6997142338486570285L;
	private String message;
	
	/**
	 * 생성자
	 * 
	 * @author	Yoon HyunGook
	 * @since	2010-03-08
	 */
	public MSGChat(){
		setType(Message.type_MSGChat);
	}
	
	/**
	 * 전송 내용 설정
	 * 
	 * @author	Yoon HyunGook
	 * @since	2010-03-08
	 * 
	 * @param	전송 내용
	 */
	public void setMessage(String str){
		message = new String(str);
	}
	
	/**
	 * 전송 내용 얻기
	 * 
	 * @author	Yoon HyunGook
	 * @since	2010-03-08
	 * 
	 * @return	전송 내용
	 */
	public String getMessage(){
		return message;
	}
	
	/**
	 * 객체 출력
	 * 
	 * @author	Yoon HyunGook
	 * @since	2010-03-08
	 * 
	 * @return	String
	 */
	public String toString(){
		return getMessage();
	}
}


메세지 타입은 새로운 메세지가 생길때 마다 수동적으로 추가 해줘야 합니다.

type : 메세지의 종류를 구분
number : 클라이언트의 번호 (필요시만 사용)
신고
Posted by 초프(초보 프로그래머)