*책은 한 반정도 보왔는데. 2월달안에 나머지를 볼수 있다.
*하지만 문서를 남기면서 책을 보는게 아직 책내용을 확실히 이해하지 않은이상 힘들다 ㅠ.ㅠ
*지금은 여기서 접는것이고. 누군가 Java Network Programming을 본다면 참여하기 바란다 ^^;;
책을 보다가 웬지 적으면서 보는게 좋다는 생각이 든다.
JAVA Network Programming
- 1장 : 프로그래머가 알아야하는 네트워크의 기본
- 2장 : 자바 보안 모델
- 3장 : 예외처리
- 4장 : 자바로 풀어보는 다중 쓰레딩
1.1. Chapter1 프로그래머가 알아야하는 네트워크의 기본 ¶
- 네트워크관한 기초지식들이 나온다. (TCP/IP,UDP.등등을 소개)
1.2. Chapter2 자바 보안 모델 ¶
- 자바의 두가지 보안
- 본질적 성격을 띄는 로우 레벨 보안 : 네트워크를 통해서 읽혀진 바이트코드의 무결성과 관련 매우중요한 부분이긴하나 프로그래머가 직접적으로 세세하게 알필요없음
- 자원과 관련된 보안 : 자원과 관련된 보안은 로우 레벨 보안보다 좀더 프로그래머에게 직접적으로 관련되어있음 애플릿을 클라이언트로 사용할때 더 중요함 이는 애플릿이 보안 제약에 직접적으로 연관되어 있기 때문
- 그외 URL프로토콜,IP멀티캐스트,DNS,방화벽,HTTP 프록시 서버,SOCKS,방화벽 내부의 DNS에 관해 간단한 설명 나옴
1.4. Chapter4 자바로 풀어보는 다중 쓰레딩 ¶
- 다중 쓰레딩은 자바 네트워크 프로그래밍에서 매우 중요한 부분이다. ^^;;
- 동기화(Synchronization) : 동기화란 여러 쓰레드가 동시에 작업할 떄 각 쓰레드의 작업 순서를 제어하기 위한 메커니즘이다.
- 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장쯤에..
- 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 스트림을 사용한 파일처리 프로그래밍의 진수 ¶
- 이장에서는 FileOutputStream과 FileInputStream에 관해 다루고 있다.
- 이외에 File,FileDescriptor,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 필터를 이용한 스트림 확장 기법 ¶
2.4. Chapter8 API로 제공되는 스트림 필터 ¶
- 지금까지는 스트림 필터의 개념을 중심으로 보왔고 이번장에서는 API로 제공되는 몇가지 스트림에 관해 살펴보고 자기만의 필터를 만들어본다.
- 한 2시간 본거 같은데 마땅히 적을께 없다 --; 허접 중목되는부분이 많다. --;
2.5. Chapter9 메모리 기반의 I/O 스트림 ¶
2.6. Chapter10 문자 스트림을 사용한 개선된 I/O 기법 ¶
2.7. Chapter11 문자 스트림 필터 ¶
- 바이트 스트림에서 기능을 확장하기위한 필터가 있었듯이 문자 스트림에도 필터가 있다.
- FilterWriter : 모든 문자 스트림 필터의 스퍼클래스로 다른 Writer 객체에 연결되어서 모든 호출 연결된 스트림으로 전달한다.
- FilterReader : 모든 Reader 문자 스트림 필터의 수퍼클래스로, 다른 Reader객체와 연결하여 모든 메소드의 호출을 연결된 스트림으로 전돨한다.
- BufferedWriter : 연결된 스트림에 출력 버퍼링 기능을 제공한다. 모든데이터는 버퍼가 가득 찾거나 flush() 메소드가 호출되거나 close() 메소드가 호출될 때까지 내부 버퍼에 저장되었다가 여러 문자를 한꺼번에 출력하는 write()메소드의 호출을 통해 연결된 스트림으로 출력된다.
- BufferdReader : 연결된 스트림에 입력 버퍼링을 제공하는 FilterReader이다. 데이터는 커다란 덩어리로 한꺼번에 연결된 스트림에서 내부 버퍼로 읽혀지므로 작은 크기의 데이터는 내부 버퍼로부터 효율적으로 읽힐 수 있다.
- LineNumberReader :연결된 스트림의 텍스트를 구성하는 각줄의 번호를 카운팅하는 기능을 초보적으로 나마 제공한다. 이클래스는 BufferedReader의 서브클래스이므로, 연결된 스트림으로서의 버퍼링을 자동으로 제공한다.
- PrintWriter : PrintStream을 대체하는 Writer 클래스로 데이터를 텍스트 형식으로 출력하는 메소드를 제공한다.
- PushbackReader : PushbackInputStream과 마찬가지로 ,푸시백 버퍼를 제공하여 이미 읽은 문자의 복구기능을 제공해 주는 클래스이다.
2.8. Chapter12 메모리 기반의 문자 스트림 ¶
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를 마치며 : 그동안 자바책을 보면서 한번도 깊이 접해보지못한 스트림에관해 배웠다. 재밌었다 ^^;;
- 14장 : 클라이언트 네트워킹
- 15장 : 클라이언트 프로그래밍 실전 예제
- 16장 : 서버 네트워킹
- 17장 : 웹 서버 프로그래밍
- 18장 : 완벽 구현! 클라이언트/서버 인터넷 애플리케이션
- 19장 : URL 클래스의 활용
- 20장 : 데이터그램 네트워킹
- 21장 : 데이터그램 애플리케이션 실전 예제
- 22장 : 멀티캐스트 네트워킹
영현 core java 다볼때 까지 기둘려라. 다음주까지 다 봐주마.. 켈켈켈..
+ 그리고, Java Network 니가 세미나 해줘.. 아니 1대1 강의..?? 캬캬
광식 술먹고 쓰려니깐 잘안써진다 --;
광식 스트림 부분은 그기간에 넘 놀았다. 밀리니 쓰기 힘들다. --; 새롭게 네트웍부터 ..