E D R , A S I H C RSS

Java Network Programming

작정자: 최광식(woodpage)

etc(?): 김영현(erunc0)


*책은 한 반정도 보왔는데. 2월달안에 나머지를 볼수 있다.
*하지만 문서를 남면서 책을 보는게 아직 책내용을 확실히 이해하지 않은이상 힘들다 ㅠ.ㅠ
*지금은 여서 접는것이고. 누군가 Java Network Programming을 본다면 참여하 바란다 ^^;;

책을 보다가 웬지 적으면서 보는게 좋다는 생각이 든다.

JAVA Network Programming




1. PART1 배경지식

  • 1장 : 프로그래머가 알아야하는 네트워크의
  • 2장 : 자바 보안 모델
  • 3장 : 예외처리
  • 4장 : 자바로 풀어보는 다중 쓰레딩

1.1. Chapter1 프로그래머가 알아야하는 네트워크의

  • 네트워크관한 초지식들이 나온다. (TCP/IP,UDP.등등을 소개)

1.2. Chapter2 자바 보안 모델

  • 자바의 두가지 보안
    • 본질적 성격을 띄는 로우 레벨 보안 : 네트워크를 통해서 읽혀진 바이트코드의 무결성과 관련 매우중요한 부분이긴하나 프로그래머가 직접적으로 세세하게 알필요없음
    • 자원과 관련된 보안 : 자원과 관련된 보안은 로우 레벨 보안보다 좀더 프로그래머에게 직접적으로 관련되어있음 애플릿을 클라이언트로 사용할때 더 중요함 이는 애플릿이 보안 제약에 직접적으로 연관되어 있 때문
    • 그외 URL프로토콜,IP멀티캐스트,DNS,방화벽,HTTP 프록시 서버,SOCKS,방화벽 내부의 DNS에 관해 간단한 설명 나옴

1.3. Chapter3 예외처리

  • 보통 자바책에서 볼수있는 정도의 예외처리에 관한 설명이 나와있음
  • 간단한 사용자 예외
    ~cpp 
     import java.io.IOException;
    
     public class AuthException extends IOException{  //사용자 예외를 정의할때 적당한 예외 클래스의 서브클래스가 되는것이 중요한데
       public AuthException(){                        //네트워킹 코드에서는 IOException이 적당하다.
       }                                              //당연한 얘지만 IOException을 처리하는 다른 모든 코드에서 처리될수있다.
       public AuthException(String detail){
          super(detail);
       }
     }
     

1.4. Chapter4 자바로 풀어보는 다중 쓰레딩

  • 다중 쓰레딩은 자바 네트워크 프로그래밍에서 매우 중요한 부분이다. ^^;;
  • 화(Synchronization) : 동화란 여러 쓰레드가 동시에 작업할 떄 각 쓰레드의 작업 순서를 제어하 위한 메커니즘이다.
    • 자바에서 코드의 특정 부분을 한번에 한 쓰레드만이 접근할수 있도록 해주위해 synchronized 문장을 사용
      ~cpp 
        synchronized(anObject){
            //중요한 코드들
        }
        
    • 세마포어(semaphores) : 세마포어란, 자바 객체가 아니라 특별한 형태의 시스템 객체이며, 이객체는 '얻(get)'와 '놓(release)'라는 두 가지 능을 가지고 있다 한 순간에, 오직 하나의 쓰레드만이 세마포어를 얻을 수 있으며(get), 한 쓰레드가 세마포어를 가지고 있는 동안 세마포어를 얻으려고 시도한 다른 쓰레드들은 모두 대 상태에 들어간다. 다시 쓰레드가 세마포어를 놓으면(release) 다른 쓰레드가 세마포어를 얻고(get) 다시 대상태로 들어간다. 이런한 매커니즘을 사용하여 특정 작업을 동화 할수있다.
    • 화의 효율 : 대부분의 경우 동화 작업은 매우 중요하며, 때로는 적대 생략해서는 안되는 경우도 있다. 그러나 불필요한 동화 작업은 프로그램의 수행 성능을 떨어뜨리고, 재사용성을 감소시키며, 프로그램이 교착 상태에 빠지게 할 수도 있다.
  • Thread 클래스 : 보통 상속받아서 사용
    ~cpp 
     public class SubThread extends Thread{
        public void run(){
              //쓰레드 작업
        }
        public static void main(String[] args){
           SubThread subThread = new SubThread();
           subThread.start();  //쓰레드 시작
        }
     
  • Runnable 인터페이스 : Thread 클래스를 직접 상속받지 않은 클래스의 객체가 손쉽게 쓰레드를 생성할수 있도록 해줌
    ~cpp 
     public class ThreadDemo implements Runnable{
        protected Thread execution;
    
        public synchronized void begin(){ //동화
          if(execution == null){
            execution = new Thread(this); //Runnable 인터페이스를 구현한 것을 넣어줌
            execution.setPriority(Thread.MIN_PRIORITY); //우선수위를 정함
            execution.start();            // 쓰레드시작
          }
        }
    
        public synchronized void end(){ //동화
          if(execution !=null){
             execution.interrupt();  //stop()을 쓰는 것은 별로 바람직하지 않다 stop()은 쓰레드가 어떤 상황에 있더라도 쓰레드를 바로 멈추어 버리 때문에,
             execution = null;       //쓰레드가 크리티컬 섹션을 수행하는 도중 이 메소드가 호출되는 경우,중요한 데이터에 다른 쓰레드가 영영 접근할수 없는
          }                          //경우가 생길 수도 있다. 따라서 stop() 메소드를 사용하는 대신 쓰레드 자신의 종료상태를 인지하고, 수행을 중지하는 플래그
        }                            //사용하는 방법이 더좋다. 가장 권장되는 방법은 위와 같은 플래그와 함께 interrupt()를 사용하는 것이다.
    
        public void run(){
          try{
              Thread myself = Thread.currentThread(); //현재 실행중인 쓰레드를 가져온다.
              while(execution == myself){
                  //쓰레드 작업
              }
          }finally{
              synchronized(this){
                  execution =null;
              }
          }
        }
        
    • ThreadGroup 클래스 : 여래개의 쓰레드르 그룹으로 만들어 손쉽계 Thread를 관리
    • Thread 통지(notification)메소드 : 주의해야 할 점은, 이 메소드들 호출하는 쓰레들이 반드시 synchronized 블록으로 동화 되어야 한다는 점이다.
      • wait() : notify() 메소드를 호출할 때까지 블록킹된다.
      • notify() : 대하고 있는 쓰레드중 하나를 꺠운다.
      • notifyAll() : 메소드가 호출된 객체에서 대하고 있는 모든 쓰레드들을 깨운다.
    • 효과적인 다중 쓰레딩 : 자바에서 쓰레드를 생성하는 것은 매우 느린 작업이며 일부 자바 가상 머신은 쓰레드에 관련된 메모리 누스 때문에 고생하도 한다. 따라서 효과적인 쓰레딩을 위해서는 새로 쓰레드르 생성하는 것 보다 이전에 생성했던 쓰레드 객체를 재사용하느 것이 좋다 진보된 형대의 자바 가상 머신에서는 시스템 레벨에서 이러한 쓰레드 재사용을 지원하도 하지만, 이경우조차도 쓰레드를 재상용하는 방식을 사용하면 여러가지 이점을 얻을수 있다. --예제는 17장쯤에..

2. PART2 스트림

  • 5장 : 스트림을 소개합니다.
  • 6장 : 스트림을 사용한 파일 처리 프로그램밍의 진수
  • 7장 : 필터를 이용한 스트림의 확장
  • 8장 : API로 제공되는 스트림 필터
  • 9장 : 메모리 반의 I/O스트림
  • 10장 : 문자 스트림을 사용한 개선된 I/O
  • 11장 : 문자 스트림 필터
  • 12장 : 메모리 반의 문자 스트림
  • 13장 : 파워업! 객체 스트림

2.1. Chapter5 스트림을 소개합니다

  • 스트림 : 네트워크 프로그램에서 아주중요한부분 > 요책이 스트림에대해서 자세히나온다.딴데는 대충 설명하는데...;
  • OutpuStream,InputStream : 모든 다른 스트림 클래스들의 수퍼클래스이다. 이 Chapter에서는 이둘 클래스 설명
    • OutputStream 클래스 : OutputStream 클래스는 통신 채널로의 관문을 의미한다. 즉, OutputStream으로 데이터를 써넣으면 데이터는 연결된 통신 채널로 전송될 것이다.
      ~cpp 
        import java.io.*;
      
        public class SimpleOut {    //간단한 OutputStream 예제
      
          public static void println(String msg) throws IOException{
             synchronized(System.out){ //메시지를 터미널에 출력하던 도중에 다른 쓰레드에 의해 String이 출력될수 없도록 동화처리
                 for(int i=0; i<msg.length(); ++i)
                     System.out.write(msg.charAt(i) & 0xff); //16비트 유니코드로 구성된 String은 연속한 바이트로 매스킹한후 출력
                 System.out.write('\n');   //개행문자 출력
             }
          System.out.flush();  //버퍼에 저장된 모든 데이커가 출력되었음을 확인하는 의미에서 스트림을 flush시킨다.
          }
      
          public static void main(String[] args) throws IOException {
            for(int i=0; i<args.length;i++){
               println(args[i]);       //넘겨받은 문자를 하나씩 넘김
            }
          }
        }
        
    • InputStream 클래스 : InputStream 클래스는 통신 채널로부터 데이터를 읽어 내는 관문을 의미한다. OutputStream에 의해 통신 채널로 쓰여진 데이터는 해당하는 InputStream에 의해 읽혀진다.
      ~cpp 
        import java.io.*;
      
        public class SimpleIn { //간단한 InputStream 예제
      
           public static void main(String[] args) throws IOException {
              byte[] buffer = new byte[8];     //작은 버퍼를 만들고
              int numberRead;
              while((numberRead =System.in.read(buffer))>=0)   //가능한 많은 양을 읽는다. EOF가 -1을 반환하면 출력한다.
                 System.out.write(buffer,0,numberRead);
          }
        }
        
  • 그외 뒤에서 배울 스트림들을 소개하고 있다.

2.2. Chapter6 스트림을 사용한 파일처리 프로그래밍의 진수

  • 이장에서는 FileOutputStreamFileInputStream에 관해 다루고 있다.
    • FileOutputStreamFileInputStream은 파일에 대한 바이트 반의 스트림 엑세스를 제공하는 2개의 표준 클래스이다.
  • 이외에 File,FileDescriptor,RandomAccessFile에 관해 간략히 나오고 파일스트림과 같이 사용하는 예제가 나온다.
    • File클래스 : 시스템에 독립적인 파일의 이름을 나타내고 실제 파일에 관한 정보를 결정하는 메소드뿐만아니라, 파일의 속성을 바꾸는 메소드도 제공
    • FileDescriptor클래스 : FileDescriptor 객체는 하위 레벨의 시스템 파일 설명자로의 핸들이다. 파일 설명자는 열려진 파일을 의미하며, 읽 작업이나 쓰 작업을 위한 현재의 파일 내의 위치와 같은 정보들을 포함한다. RandomAccessFile이나 FileOutputStream, FileInputStream을 사용하지 않고는 유용하게 FileDescritor를 생성할수 있는 방법은 없다 . --;
    • RandomAccessFile클래스 : 파일스트림을 사용하지않고 파일을 쉽게 다룰수 있음 장점은 파일스트림 클래스는 순차적 엑세스만이 가능하지만 이것은 임의의 엑세스가 가능하다. 여RandomAccessFile클래스랑 파일 스트림을 같이 쓰는데 RandomAccessFile의 장점을 가지고 네트워크에서도 별다른 수정없이 사용할수있다. 예제는 밑에 --;
  • FileOutputStream 클래스 : 연속적인 데이터가 파일에 쓰여질수 있도록 해줌
  • FileInputStream 클래스 : 연속적인 데이터를 읽을수 있게 해줌 --;
  • 간단한 파일 스트림 예제
    ~cpp 
     import java.io.*;
    
     public class copy {
       //메인
       public static void main(String[] args) throws IOException {
         if(args.length !=2) //넘어오는 args가 파일이 원본 복사본 두개여야한다.
           throw ( new IllegalArgumentException ("Syntax:Copy <src> <dst>"));
         FileInputStream in = new  FileInputStream(args[0]); //원본 파일
         FileOutputStream out = new FileOutputStream(args[1]); //복사본 파일
    
         byte[] buffer = new byte[16];
         int numberRead;
         while((numberRead = in.read(buffer)) >=0) //파일을 버퍼에 가능한 많은 양을 읽고 읽은 양만큼 파일에 쓴다. 파일이 EOF일 때까지.
           out.write(buffer,0,numberRead);  //여서 0은 초시작위치이고 파일에 쓸때마다 점점 옆으로 이동한다 --;
         out.close();  //close가 호출되지 않으면 FileOutputStream에 가비지 콜렉션이 일어날 때에 파일과 하부의 FileDescriptor가 자동으로 닫힌다.
         in.close();  //위에랑 마찬가지
       }
     }
     
  • 덮어쓰(Overwriting)능을 갖춘 FileOutputStream
    ~cpp 
     import java.io.*;
     public class SimpleOverwritingFileOutputStream extends OutputStream {
    
      protected RandomAccessFile file; //랜덤 엑세스 파일
    
      public SimpleOverwritingFileOutputStream(String filename) throws IOException {
        file = new RandomAccessFile(filename,"rw"); //RandomAccessFile은 파일이 존재하지 않으면 자동으로 파일생성 하고 그렇지
                                                    //않으면 파일을 연다 파일을 열면 포인터는 자동으로 파일의 시작부분을 가리키미로
                                                    //데이터를 쓰면 존의 파일 내용 위에 덮어 쓰여진다.
      }
      public void write(int datum) throws IOException {
        /**@todo: implement this java.io.OutputStream abstract method*/
        file.write(datum);
      }
      public void close() throws IOException{
        file.close();
      }
     }
     
  • 위치 이동(Seeking)능을 갖춘 FileOutputStream
    ~cpp 
     import java.io.*;
     public class SeekableFileOutputStream extends FileOutputStream {
      protected RandomAccessFile file;
    
      public SeekableFileOutputStream(String filename)throws IOException {
        this(new RandomAccessFile(filename,"rw")); // 자신의 또다른 생성자에게 넘겨준다.--;
      }
      public SeekableFileOutputStream(File file) throws IOException{
        this(file.getPath()); //역시 자신의 생성자를 호출함
      }
      protected SeekableFileOutputStream(RandomAccessFile file) throws IOException{
        super(file.getFD());  //FileOutputStream에다가 FileDescriptor를 인자로 념겨줌
        this.file=file;
      }
      public void setPosition(long position) throws IOException{
        file.seek(position); //position의 위치로 파일 포인터 위치를 변경
      }
      public long getPosition() throws IOException{
        return file.getFilePointer(); //현재 파일 포인터 위치를 돌려줌
      }
      public long getLength() throws IOException{
        return file.length(); //파일 길이를 돌려줌
      }
      public void write(int b) throws java.io.IOException {
        /**@todo: implement this java.io.OutputStream abstract method*/
        file.write(b);
      }
     }
     
  • 표시/리셋(mark/reset)능을 갖춘 FileInputStream만들
    ~cpp 
     import java.io.*;
     public class MarkResetFileInputStream extends FileInputStream {
      protected long markedPosition;  //마크될 위지
      protected RandomAccessFile file;  //랜덤 엑세스 파일
      public MarkResetFileInputStream(String filename)throws IOException {
        this(new RandomAccessFile(filename,"r")); //랜덤엑세스 파일을 생성해서 다른 생성자로
      }
      public MarkResetFileInputStream(File file)throws IOException {
        this(file.getPath()); //파일명을 넘겨주어 위로 --;
      }
      protected MarkResetFileInputStream(RandomAccessFile file) throws IOException{
        super(file.getFD());  //FileDescriptor를 넘겨주고
        this.file=file;    //파일을 저장해논다. 이러면 랜덤엑세스랑 FileInputStream 사용할수있다.
        markedPosition = -1;
      }
      public boolean markSupported(){
        return true;
      }
      public void mark(int readAheadLimit){
        try{
          markedPosition = file.getFilePointer(); //현재위치를 억한다.
        }catch(IOException ex){
          markedPosition = -1;
        }
      }
      public void reset() throws IOException{
        if(markedPosition == -1)
          throw new IOException("No mark set.");
        file.seek(markedPosition); //마크해논위치로 다시간다.
      }
     }
     

2.3. Chapter7 필터를 이용한 스트림 확장

  • 지금까지는 한 바이트나 바이트 배열정도의 읽고/쓰를 지원하는 간단한 스트림만을 보와왔다. 이러한 수준의 통신은 필요이상으로 번거롭다. 그래서 이번장에서는 존의 스트림의 위에 부가적인 능을 제공할 수 있는 스트림인 스트림 필터(stream filter)에 대해 소게하곘다.
  • FileterOutputStream , FilterInputStream 클래스 : 이것은 입출력 스트림 필터에 대한 템플리트로 이미 존재하는 InputStream,OutputStream에 연결해서 요구된 내용을 연결된 스트림의 메소드로 전댈해 주는것 이외의 능은 제공하지 않는다.
  • 표준 스트림 필터 :간략히 살펴본다.
    • BufferedOutputStreamBufferedInputStream : 존의 스트림 위에서 입출력 버퍼링을 제공한다. 입출력 되는것을 버퍼에 저장해서 중간중간에 flush를 이용해 쏟아낸다. 그러면 스트림에 대한 오버헤드를 줄일수 있다.
  • DataOutputStreamDataInputStream : 존의 바이트만 읽고 쓰는 스트림위에서 상위 수준의 통신이 가능하다. 예를 들어 String이나 부동점 실수와 같은 것을 통신할 수있다. 존의 수준낮은(?) 것은 바이트 단위로 통신해야한다.
  • PushbackInputStream : 입력 스트림으로 데이터의 읽 복구 능을 지원한다. 다시 말하면, 데이터가 입력 스트림으로 다시 넣어져서, 다음 번에 읽를 수행할 때에 다시 읽혀질 수 있게 된다.
  • SequenceInputStream : 일련의 InputStream들이 순차적으로 연결된다. 하나의 SequenceInputStream에 여러 InputStream이 연결되서 하나의 긴 InputStream처럼 보인다.
  • LineNumberInputStream : LineNumberReader 클래스에 의해 쓸모가 없어진 이 스트림은 초보적인 수준으로 줄에 번호 매능을 제공한다.
  • PrintStream : PrintWriter 클래스에 의해 쓸모가 없어진 이 클래스는 ASCII 텍스트 데이터의 출력능을 제공한다.
  • 스트림 필터의 사용 예제 : System.in으로 입력받는것을 BufferedInputStream필터를 거쳐서 LineNumberInputStream을 거처 DataInputStream을 거처서 DataOutputStream에 쓰여지고 BufferedOutputStream으로 버퍼링돼 한번에 출력된다. --;
    ~cpp 
     import java.io.*;
     public class FilterTest{
      public static void main(String[] args) {
        BufferedInputStream bufferedIn = new  BufferedInputStream(System.in); //장치 입력을 버퍼 필터로 받는다.
        BufferedOutputStream bufferedOut = new BufferedOutputStream(System.out); //화면에 출력하전 버퍼아웃픗스트림을 거친다.
        LineNumberInputStream lineNumberIn = new LineNumberInputStream(bufferedIn); //버퍼입력을 다시 라인을 붙여주는 필터가 받음
        DataInputStream dataIn = new DataInputStream(lineNumberIn); //라인이 붙은 입력을 DataInputStream으로 받아서 한바이트이상을 전달함
        DataOutputStream dataOut = new DataOutputStream(bufferedOut); //한바이트이상을 받음
        try{
          String line;
          while(true){
            line = dataIn.readLine();  //한줄 입력을 받는다.
            String response = lineNumberIn.getLineNumber() + " : " + line.toUpperCase() + "\n"; //줄번호를 얻어서 붙임 대문자로 바꿈
            dataOut.writeBytes(response); //BufferdOutputStream에 쓴다.
            if(line.equals("exit"))    //exit가 들어오면 루프를나간다.
              break;
          }
          dataOut.flush();         //이제까지 버퍼에 모아논것을 출력한다.
        }catch(IOException ex){
          System.err.println(ex);
        }
      }
     }
     

2.4. Chapter8 API로 제공되는 스트림 필터

  • 지금까지는 스트림 필터의 개념을 중심으로 보왔고 이번장에서는 API로 제공되는 몇가지 스트림에 관해 살펴보고 자만의 필터를 만들어본다.
    • DataOutputStream,DataInputStream,BufferedOutputStream,BufferedInputStream,PrintStream,SequenceInputStream,LineNumberInputStream,PushbackInputStream 클래스에 관해서 좀 자세히 설명을 해놓고 있다.
  • 한 2시간 본거 같은데 마땅히 적을께 없다 --; 허접 중목되는부분이 많다. --;

2.5. Chapter9 메모리 반의 I/O 스트림

  • 두가지 본 스트림에 관에서 설명
  • ByteArrayOutputStream
  • ByteArrayInputStream
  • PipedOutputStream
  • PipedInputStream

2.6. Chapter10 문자 스트림을 사용한 개선된 I/O

  • 지금까지는 바이트 스트림을 주로 봤는데 이제부터는 스트림의 양대산맥인 문자 스트림에 대해 알아본다.
  • Write : 바이트 스트림의 OutputStream과 같은 역할
  • Reader : 바이트 스트림의 InputStream과 같은 역할
  • OutputStreamWriter : 문자 반의 Writer에서 바이트 반의 OutputStream 채널로의 연결을 지원 문자->OutputstreamWriter->바이트
  • InputStreamReader : 바이트 반의 InputStream을 문자 스트림과 연결 바이트->InputStreamReader->문자
  • FileWriter : 텍스트 파일을 플랫폼의 본 문자 인코딩 방식을 사용하여 출력하는 문자 스트림 인터페이스를 제공 파일에 쓰는것임 --;
  • FileReader : 플랫폼의 본 문자 인코딩 방식을 사용하여 텍스트 파일을 읽 위한 문자 스트림 인터페이스를 제공한다. 파일에서 읽는것임 --;

2.7. Chapter11 문자 스트림 필터

  • 바이트 스트림에서 능을 확장하위한 필터가 있었듯이 문자 스트림에도 필터가 있다.
  • FilterWriter : 모든 문자 스트림 필터의 스퍼클래스로 다른 Writer 객체에 연결되어서 모든 호출 연결된 스트림으로 전달한다.
  • FilterReader : 모든 Reader 문자 스트림 필터의 수퍼클래스로, 다른 Reader객체와 연결하여 모든 메소드의 호출을 연결된 스트림으로 전돨한다.
  • BufferedWriter : 연결된 스트림에 출력 버퍼링 능을 제공한다. 모든데이터는 버퍼가 가득 찾거나 flush() 메소드가 호출되거나 close() 메소드가 호출될 때까지 내부 버퍼에 저장되었다가 여러 문자를 한꺼번에 출력하는 write()메소드의 호출을 통해 연결된 스트림으로 출력된다.
  • BufferdReader : 연결된 스트림에 입력 버퍼링을 제공하는 FilterReader이다. 데이터는 커다란 덩어리로 한꺼번에 연결된 스트림에서 내부 버퍼로 읽혀지므로 작은 크의 데이터는 내부 버퍼로부터 효율적으로 읽힐 수 있다.
  • LineNumberReader :연결된 스트림의 텍스트를 구성하는 각줄의 번호를 카운팅하는 능을 초보적으로 나마 제공한다. 이클래스는 BufferedReader의 서브클래스이므로, 연결된 스트림으로서의 버퍼링을 자동으로 제공한다.
  • PrintWriter : PrintStream을 대체하는 Writer 클래스로 데이터를 텍스트 형식으로 출력하는 메소드를 제공한다.
  • PushbackReader : PushbackInputStream과 마찬가지로 ,푸시백 버퍼를 제공하여 이미 읽은 문자의 복구능을 제공해 주는 클래스이다.

2.8. Chapter12 메모리 반의 문자 스트림

  • PipedWriter : 파이프 클래스는 스레드 통신 수단인데 Writer니깐 문자반이다. PipedReader와 연결되서 한쪽에서 쓰고 다른쪽에서 읽는다.
  • PipedReader
  • CharArrayWriter : 이클래스는 바이트스트림의 ByteArrayOutputStream과 대응대는것으로 Char배열로 문자를 내보낼수있다.
  • CharArrayReader
  • StringWriter : 전반적으로 CharArrayWriter 클래스와 비슷하다.
  • StringReader

2.9. Chapter13 파워업! 객체 스트림

  • 이번장에서 Object를 통신채널로 전송할수있는 객체 스트림에 대해 배우고있다 --;
  • ObjectOutputStream,ObjectInputStream에 대해 자세히 배우는데 개념이 좀 맘에 안온다.
  • 끝에 예제를 보고 조금 이해가 가긴하는데 다음장부터 본격적인 네트웍으로써 이해를 하겠다 --;
  • 객체 스트림의 서브클래스 구현 : 직렬화 될수 없고, 그외 여러가지 방법으로도 직렬화시키 어려운 클래스의 전송을 제공하 위해 객체 스트림의 서브클래스를 구형해야함
    ~cpp 
     interface MyOSContants {
      final short myOSMagick = (short)0x1359;
      final short myOSVersion = (short)0x0010;
     }
    
     import java.io.*;
     import java.net.*;
    
     public class MyDatagramPacket implements Serializable { //이클래스는 직렬화를 할수있다.
       private byte[] data;                                  //직렬화를 할수없는 DatagramPacket을 깜싸서 직렬화를 할수있게한다.
       private int offset,length,port;
       private InetAddress address;
    
       MyDatagramPacket(DatagramPacket packet) {  //DatagramPacket으로부터 정보를 념겨받는다.
         data = packet.getData();
         offset = packet.getOffset();
         address = packet.getAddress();
         port = packet.getPort();
       }
    
       DatagramPacket toDatagramPacket(){ //DatagramPacket을 넘겨준다.
         return new DatagramPacket(data,offset,length,address,port);
       }
     }
    
     import java.io.*;
     public class MyFile extends File{//이클래스 자체로 직렬화할수있지만 예제다 --;
       private String originalPath;  //오리지날 패스
    
       public MyFile(File file) {  //파일을 받고
         super(file.getAbsolutePath());  //절대경로를 넘겨준다/
         originalPath = file.getPath();  //오리지날 패스를 받는다.
       }
       public String getOriginalPath(){
         return originalPath;
       }
     }
    
     import java.io.*;
     import java.net.*;
    
     public class MyAltDatagramPacket extends MyDatagramPacket {
    
       public MyAltDatagramPacket(DatagramPacket packet) {
         super(packet);
       }
       private Object readResolve(){
         return toDatagramPacket();
       }
     }
    
     import java.io.*;
     import java.net.*;
     public class MyObjectOutputStream extends ObjectOutputStream implements MyOSContants{
    
       public MyObjectOutputStream(OutputStream out)throws IOException {
         super(out);
         enableReplaceObject(true); //이메소드를 호출해야만 replaceObject를 호출할수있음 보안문제
       }
       protected void writeStreamHeader() throws IOException{
         super.writeStreamHeader(); //수퍼클래스의 헤더를 출력한후에
         writeShort(myOSMagick);  //스트림의 메직넘버인 myOSMagick과
         writeShort(myOSVersion); //버전 번호인 myOSVersion을 출력한다.
       }
       protected Object replaceObject(Object object) throws IOException{
         if(object.getClass() == DatagramPacket.class)
           return new MyDatagramPacket((DatagramPacket)object);
         else if(object.getClass().getName().equals("java.io.File"))
           return new MyFile((File)object);
         else
           return object;
       }
     }
    
     import java.io.*;
     import java.net.*;
    
     public class MyObjectInputStream extends ObjectInputStream implements MyOSContants {
    
       public MyObjectInputStream(InputStream in)throws IOException {
         super(in);
         enableResolveObject(true); //resolveObject()호출 가능하게한다.
       }
       protected void readStreamHeader() throws IOException{ //스트림을 읽는다.
         super.readStreamHeader();
         if(readShort() !=myOSMagick)              //고유번호가 틀리면
           throw new StreamCorruptedException("Incompatible myOSMagick number");
         if(readShort() > myOSVersion)            //버전이 높으면
           throw new StreamCorruptedException("Incompatible myOSVersion number");
       }
       protected Object resolveObject(Object object) throws IOException{
         if(object instanceof MyDatagramPacket)
           return ((MyDatagramPacket)object).toDatagramPacket();
        else
           return object;
       }
     }
     
  • PART2를 마치며 : 그동안 자바책을 보면서 한번도 깊이 접해보지못한 스트림에관해 배웠다. 재밌었다 ^^;;

3. PART3 네트워킹

  • 14장 : 클라이언트 네트워킹
  • 15장 : 클라이언트 프로그래밍 실전 예제
  • 16장 : 서버 네트워킹
  • 17장 : 웹 서버 프로그래밍
  • 18장 : 완벽 구현! 클라이언트/서버 인터넷 애플리케이션
  • 19장 : URL 클래스의 활용
  • 20장 : 데이터그램 네트워킹
  • 21장 : 데이터그램 애플리케이션 실전 예제
  • 22장 : 멀티캐스트 네트워킹

3.1. 14장 클라이언트 네트워킹



4. 잡담


core java 다볼때 까지 둘려라. 다음주까지 다 봐주마.. 켈켈켈.. + 그리고, Java Network 니가 세미나 해줘.. 아니 1대1 강의..?? 캬캬

광식 술먹고 쓰려니깐 잘안써진다 --;

광식 스트림 부분은 그간에 넘 놀았다. 밀리니 쓰 힘들다. --; 새롭게 네트웍부터 ..
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:30
Processing time 0.0489 sec