레이블이 Java인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Java인 게시물을 표시합니다. 모든 게시물 표시

2013년 2월 19일 화요일

[Java] TCP

TCP 프로토콜?
  • TCP는 Socket 과 ServerSocket를 사용하여 데이터를 주고 받습니다.
  • Socket 은 목적지 정보를 전송 수신하는 역할을 합니다.
  • ServerSocket 은 포트 번호와 Client와 연결되는 서버의 최대 연결 수를 지정 할 수 있습니다.
◆ 장점
  • 신뢰성(데이타 손실이 없습니다.)
  • 양뱡향 통신 가능
  • 바이트 스트림 지원
◆ 단점
  • UDP에 비해 다소 느릴 수 있음.
Client 예제
/*  * 클라이언트에서 작업할 내용  
 * 1)소켓 객체 생성(ip, port지정) ==> 해당 ip에 접속하여 정상적인 접속이 완료되면 객체가 생성  
 * 2)I.O 스트림 열기  
 * 3)자료 송/수신  
 * 4)소켓 닫기 
 * */
public class TestClient {
 static Socket s;

 public TestClient() throws IOException {
  s = new Socket("127.0.0.1", 9999); // 서버주소

  BufferedReader reader = new BufferedReader(new InputStreamReader(
    s.getInputStream()));
  PrintWriter writer = new PrintWriter(s.getOutputStream());
  String msg = "Strat!!";
  String rMsg = null;
  BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
  while (!msg.equals("bye")) {
   System.out.print("전송입력 : ");
   msg = in.readLine();
   writer.print(msg);
   writer.flush();
   System.out.println("가는 중...");
   rMsg = reader.readLine();
   System.out.print("받은 메세지:" + rMsg);
  }
 }

 public static void main(String[] args) throws IOException {
  try {
   new TestClient();
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   try {
    s.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }
}

  • 주소와 포트번호와 함께 Socket을 생성 합니다.
  • 바이트 스트림을 지원 하므로 바이트 형태로 데이타를 주고 받습니다.
  • in.readLine()으로 입력 받은 문자를 writer.print(msg)을 사용하여 Server에 보내고 writer.flush() 시켜줍니다.
  • rMsg = reader.readLine()은 Server에서 받은 메세지를 한줄씩 읽습니다.
  • BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream())) 와 PrintWriter writer = new PrintWriter(s.getOutputStream())에서 전송한 데이타와 수신한 데이터를 알 수 있습니다.

Server 예제
/*  * 서버에서 수행하는 일  
 *   1)서버소켓 객체 생성  
 *   2)클라이언트 접속 대기  
 *   3)자료 송/수신  
 *   4)소켓 닫기 */
public class TestServer {
 static ServerSocket ss = null;
 static Socket s = null;

 public TestServer() throws IOException {
  ss = new ServerSocket();
  s = new Socket();
  ss = new ServerSocket(9999);
  System.out.println("클라이언트 접속 대기 중...");
  s = ss.accept();
  System.out.println("클라이언트 접속!!");
  BufferedReader reader = new BufferedReader(new InputStreamReader(
    s.getInputStream()));
  PrintWriter write = new PrintWriter(s.getOutputStream());
  String msg = "Start!";
  while (!msg.equals("bye")) {
   System.out.println("받는 중...");
   msg = reader.readLine();
   System.out.println("수신데이타 : " + msg);
   write.println(msg);
   write.flush();
  }
 }

 public static void main(String[] args) {
  try {
   new TestServer();
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   try {
    ss.close();
    s.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }
}

  • ServerSocket으로 포트 번호를 맞춰 줍니다.
  • s = ss.accept() 부분이 Client가 접속하기를 기다리는 부분입니다. 서버는 클라이언트가 접속하기 전까지 대기하고있는 상태입니다.
  • msg = reader.readLine() 위에 스트림으로 받은 데이터를 다시 Client로 전송하는 부분입니다.

TCP를 설명하기 위해 간단히 작성된 소스입니다. 요약하자면 Client에서 Socket 를 사용하여 목적지(서버)의 주소와 포트번호를 설정하여 보내면 서버에서는 ServerSocket 에서 포트를 맞추고 accept()에서 접속하기를 기달리고 있다가 스트림을 이용하여 다시 전송하는 코드입니다.

관련글
  1. [Java] UDP
  2. [Java] 객체 저장(OutputStream, inputStream, BufferStream)

[Java] UDP

UDP 프로토콜?

  • UDP는 DatagramSocket 와 DatagramPacket를 사용하여 데이터를 전송한다는 것만 알면 됩니다.
  • DatagramSocket은 DatagramPacket를 전송하거나 수신 받기 위해 사용 합니다.
  • DatagramPacket은 UDP 통신에서 데이터를 담아서 전송하거나 받기 위해 사용 합니다.

◆ 장점
  • 복잡하지 않음
  • 시스템 로드를 줄일 수 있음
  • 빠름

◆ 단점
  • 데이타 손실이 있을 수 있음
Client 예제
public class BroadClient {
 public BroadClient() {
  new Thread(new ReadThread()).start();
 }

 class ReadThread implements Runnable {
  DatagramSocket ds = null;
  DatagramPacket packet = null;
  byte[] brr = new byte[200];

  public void run() {
   try {
    ds = new DatagramSocket(12345); // 서버 port를 맞춘다.
    packet = new DatagramPacket(brr, brr.length);// brr : 데이터그램 패킷을 수신할 바이트 배열, brr.length:데이터그램 수신 크기.
    while (true) {
     ds.receive(packet); // 블럭 되어 있는 부분.
     System.out.println("받은 문자열 : "+ new String(packet.getData())); // 바이트로 받은 내용을 문자로바꾼다.
     System.out.println(packet.getAddress().getHostAddress());// 보낸사람 address를 알 수 있다.
     Thread.yield();
    }
   } catch (Exception e) {
    System.out.println("받기 오류 :" + e);
    e.printStackTrace();
   }
  }
 }

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

  • 수신받는 부분의 DatagramPacket 부분입니다. packet = new DatagramPacket(brr, brr.length)
  • ds.receive(packet) 부분이 Server에서 데이타를 받는 부분입니다. 데이터를 받을때까지 블럭 되어있습니다.

Server 예제
public class BroadServer {
 boolean onAir = false;
 DatagramSocket ds;
 DatagramPacket packet;
 int port = 12345;// 받을 사람 port // 상용화 포트(1024 ~ 10000)

 InetAddress address;

 public BroadServer() {
  HowServer server = new HowServer();
  Thread trd = new Thread(server);
  onAir = true;
  trd.start();
 }

 static class Unse {
  static Random ran = new Random();
  static final String[] arr = { "오늘은 모든 일이 잘 풀릴것 같음.",
    "비가 올 것 같이 기분이 좋지 않음.", "안드로이드 공부 중.", "xml 중요.",
    "프로젝트 준비 철저.", "마무리를 잘하자!!" };

  static String getUnse() {
   return arr[ran.nextInt(arr.length)];
  }
 }

 class HowServer implements Runnable {
  String data;
  byte[] brr;

  public void run() {
   try {
    ds = new DatagramSocket();
    address = InetAddress.getByName("127.0.0.1");// 서버 주소
   } catch (Exception e) {
    e.printStackTrace();
   }
   try {
    while (onAir) {
     data = Unse.getUnse(); // 운세의 내용을 가져온다.
     brr = data.getBytes(); // String을 byte 배열로 만들기.
     packet = new DatagramPacket(brr, brr.length, address, port); // 배열, 배열길이, 주소, 포트번호.
     ds.send(packet);
     System.out.println("서버전송 문자열 :" + data);
     Thread.sleep(1000);
    }
   } catch (Exception e) {
    System.out.println("서버생성 오류 :" + e);
    e.printStackTrace();
   }
  }
 }

 public static void main(String[] args) {
  new BroadServer();
 }
}
  • 전송하는 부분의 DatagramPacket 부부입니다.packet = new DatagramPacket(brr, brr.length, address, port)
  • ds.send(packet) 부분이 Client로 데이타를 보내는 부분입니다.
UDP는 특별한 내용이 없습니다. DatagramSocket 와 DatagramPacket를 사용하며 send()로 보내며 receive()로 받는 다는 것만 기억하시면 됩니다.

관련글
  1. [Java] TCP
  2. [Java] 객체 저장(OutputStream, inputStream, BufferStream)

2013년 2월 17일 일요일

[Java] 객체 저장(OutputStream, InputStream, BufferStream)

객체를 저장하는 방법에는 2가지가 있습니다.
  1. 직렬화를 사용하여 저장
    • 자바 프로그램에서만 사용한다는 조건에서 사용합니다.
    • 클래스를 직렬화 할려면 implements Serializable를 사용해야 됩니다.
    • static 변수는 직렬화 하지 못합니다. 
    • 클래스 중에 직렬화를 하고 싶지 않은 변수에는 transient를 사용합니다.
  2. 문자로 저장
    • 타 프로그램에서도 저장된 객체를 사용 할 수도 있을때 사용합니다.
◆ 직렬화를 사용할 경우
 try {
 //  "dg.ser"로 저장합니다.
  ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("dg.ser"));
  oos.writeObject(d);
  oos.close();
  
 //  파일이름이 "dg.ser"인 파일을 가져옵니다.
  ObjectInputStream ois = new ObjectInputStream(new FileInputStream("dg.ser"));
  d = (DungeonGame)ois.readObject();
  ois.close();
  
 } catch (Exception e) {
  // TODO: handle exception
  e.printStackTrace();
 }

《저장》
  • FileOutputStream를 사용하여 바이트 형태로 저장합니다.
  • ObjectOutputStream를 사용하여 직렬화 하여 저장합니다.
  • ObjectInputStream를 닫아 줍니다. ObjectInputStream를 닫으므로서 밑에 있는 FileOutputStream는 자동으로 닫힙니다.
《가져오기》
  • FileOutputStream를 사용하여 바이트 형태로 읽습니다.
  • ObjectOutputStream를 사용하여 클래스를 찾아서 불러온 다음 저장되었던 인스턴스 변수값을 다시 대입합니다. 직렬화된 객체의 생성자는 실행되지 않습니다.
  • ObjectInputStream를 닫아 줍니다. ObjectInputStream를 닫으므로서 밑에 있는 FileOutputStream는 자동으로 닫힙니다.
◆ 문자로 저장
    try {
     //  "wawoo.txt"로 저장합니다.
      BufferedWriter writer = new BufferedWriter(new FileWriter("wawoo.txt"));
      writer.write("wawoo oops!");
      writer.close();
      
     //  파일 이름이 "wawoo.txt"인 것을 불러옵니다.
      BufferedReader reader = new BufferedReader(new FileReader(new File("wawoo.txt")));
      String line = null;
      while ((line = reader.readLine()) != null) {
       System.out.println(line);
      }
      reader.close();
      
     } catch (Exception e) {
      // TODO: handle exception
      e.printStackTrace();
     }

    《저장》
    • FileWriter를 사용하여 문자 형태로 저장합니다.
    • BufferedWriter를 사용하여 효율을 높입니다. 버퍼를 사용하는 목적중에 하나는 시스템 효율입니다. 버퍼는 box라고 생각하고 박스가 차면 한번에 데이터를 처리한다고 생각하면 됩니다.
    • BufferedWriter를 닫아줍니다.여기서도 역시 BufferedReader만 관리하면 하위단에 있는 FileReader는 자동으로 닫힙니다.
    《가져오기》
    • FileReader를 사용하여 저장된 파일을 연결합니다.
    • BufferedReader를 사용하여 효율을 높입니다.
    • BufferedReader를 닫아줍니다.