'My work space'에 해당되는 글 113건

  1. 2008.08.20 Ⅳ. Class Diagram
  2. 2008.08.20 Ⅲ. Use Case Diagram, Use Case 정의서
  3. 2008.08.20 Ⅱ. UML구성요소
  4. 2008.08.20 Ⅰ. UML 개요
  5. 2008.08.20 J2EE , J2SE 한글 API [다운가능]
  6. 2008.08.20 JDK1.4 Logging API의 사용을 통한 Logging
  7. 2008.08.20 프로그래밍에유용한사이트
  8. 2008.08.20 AWT/SWING 성능 비교(기본 출력 기능)
  9. 2008.08.20 소켓(Socket)
  10. 2008.08.20 Swing으로 GUI만들기
2008. 8. 20. 15:06

Ⅳ. Class Diagram

1. Class Diagram 개요

    ① 정의 : 클래스간 정적인 정의와 관계 표현

    ② 작성목적

        * 클래스 식별 및 관계 정의

        * 클래스간 관계를 정의함으로써 시스템 이해용이.

        * 클래스의 오퍼레이션과 속성을 정의함으로써 SW 시스템 설계

        * 일관된 형식으로 분석설계 방식 제공.

    ③ 작성순서

        * 클래스 정의 → 속성, 오퍼레이션 정의 → 클래스간 관계정의 ┐

               ↑__________________________________________________┘

 

2. Class Diagram 구성요소

    ① Class

        

    ② Association : 두 클래스간 일반적 협력 관계

: 양방향 관계

: 화살표는 참조 방향

            ex)

            

    ③ Aggregation : 두 클래스간 전체-부분 관계. 각 클래스가 독립적 생명 주기를 갖는다.

        Composition : 두 클래스간 부분-전체 관계. 부분 생명주기가 전체 클래스의 영향을 받음.

              

    ④ Generalization : 두 클래스가 일반화-특수화 관계. 상속(Inheritance)의 특성을 지님.

               

    ⑤ Dependency : 클래스간 사용관계- 다른 객체를 생성하고 소멸시키는 보다 종속적 관계임.

3. Multiplicy와 특별한 Class 간 관계

    ① Multiplicity(관계수) : 클래스가 관계에 참여하는 개체의 수.

           - Many                                                  - Exactly 5

       

           - Zero or more                                        - one to ten

       

            - exactly 2,3,5

       

    ② Multiple Association(다중연관관계) : 두 클래스 간 두 가지 이상의 Association이 존재.

    

    ③ Reflexive Association : 같은 클래스기리 맺어지는 관계

    ④ Qualifier 연관관계 : 관계수가 복잡한 경우

    ⑤ Association Class(연관 클래스) : Association 관계 에서 고유의 속성이나

                                                       오퍼레이션이 필요한 경우

      

4. 사례




출처

 

http://blog.naver.com/westengirl/140003933502

'My work space > Java' 카테고리의 다른 글

Ⅵ. Collaboration Diagram  (0) 2008.08.20
Ⅴ. Sequence Diagram  (0) 2008.08.20
Ⅲ. Use Case Diagram, Use Case 정의서  (0) 2008.08.20
Ⅱ. UML구성요소  (0) 2008.08.20
Ⅰ. UML 개요  (0) 2008.08.20
2008. 8. 20. 15:05

Ⅲ. Use Case Diagram, Use Case 정의서

1. Use Case Diagram 개요

    ① 정의 : 사용자 관점에서 SW 시스템의 범위와 기능 정의.

                 시스템애 해야할 무엇을 작성. 어떻게는 서술하지 않음.

    ② 목적 - 업무범위 정의

               - 사용자 정의

               - 업무기능 정의

               - 사용자 요구사항 정의

               - 사용자와 개발자간 의사소통 도구

               - 분석, 설계 작업 기준

               - 테스트 기준

    ③ 작성단계

        * 액터식별 → 유즈케이스 식별 →         관계정의            →  유즈케이스 구조화

                    


2. Use Case Diagram 구성요소

    ① Actor : 시스템 외부에 독립적으로 존재하면서        ② UseCase : 사용자 관점의 시스템이

                    시스템과 교류하는 것                                                 제공하는 서비스

                                                                     

    ③ Association : 액터와 유즈케이스간 관계

                

          : 상호교류시..                                             : 커뮤니케이션을 받는 쪽이 화살표를 받음.

    ④ Generalization : 액터끼리, 유즈케이스끼리 관계로 일반화 관계 정의

               

          : 화살표를 받는 쪽이 상위개체.

    ⑤  Include : 한 유즈케이스가 다른 유즈케이스에게 서비스를 요청하는 관계

                      서비스는 반드시 수행되어야 함.                   

                   

    ⑤ Extend : 한 유즈케이스가 다른 유즈케이스에게 서비스를 요청하는 관계

                     but 서비스는 조건에 따라 수행될 수도 안 될 수 도 있다.

                

     ex) 프리즘 시스템

       


3. Use Case 정의서

    : Use Case의 처리내용을 기술한 문서

    

    ① 작성시기 : Use Case Diagram이 만들어진 직후

    ② 구성

        = UseCase명+이벤트흐름{기본흐름+선택흐름}+특별요구사항+사전조건+사후조건+확장조건


※ 사례

           

   *  병원관계자가 원하는 기능

      - 진료비는 진료정보를 입력하면 자동 산정된다

      - 환자는 진료예약을 하고, 환자의 과거 병력과 진료정보는 관리된다.

      - 일반 사용자는 병원정보와 의료진 정보를 조회하고 상담한다.

      - 의료진은 자신의 진료스케쥴을 자동 생성하고 진료내역을 관리하고, 환자정보를 조회 한다.

      - 원무와 직원은 이 시스템을 통해 진료비 청구서를 조회, 발행하고, 진료예약을 확정한다.

  =>


출처http://blog.naver.com/westengirl/140003904775

'My work space > Java' 카테고리의 다른 글

Ⅴ. Sequence Diagram  (0) 2008.08.20
Ⅳ. Class Diagram  (0) 2008.08.20
Ⅱ. UML구성요소  (0) 2008.08.20
Ⅰ. UML 개요  (0) 2008.08.20
J2EE , J2SE 한글 API [다운가능]  (0) 2008.08.20
2008. 8. 20. 15:05

Ⅱ. UML구성요소

Diagram = Things + Relationships


 

----------------------------------------------------------------------------------------

1. Diagram

   ① Usecase Diagram

       * 용도 - 사용자관점에서 논리적인 시스템의 기능 정의

                 - 인수측과 개발측이 이해를 같이하는 도구

                 - 시스템 전체 개발범위 결정

                 - 시스템 분석, 설계 기준

                 - 인수테스트 기준

       * 작성시기

           요구정의→분석→기본설계→상세설계→개발→구현

   ② Class Diagram

       * 용도 - SW의 기본구성단위인 클래스와 그들간의 관계 정의

                 - 정적인 관점에서 클래스 구조 표현

                 - 기본적 데이터 모델링 수행(분석단계)

                 - 객체지향 언어코딩을 위한 설계 사양 제공(설계단계)

                 - 분석에서 설계까지 일관된 형식의 SW시스템 분석, 설계 도구

       * 작성시기

           요구정의→분석→기본설계→상세설계→개발→구현

   ③ Sequence Diagram

       * 용도 - 객체들간 협력 과정을 동적으로 정의한 Diagram

                 - 유즈케이스 단위로 작성

                 - 분석에서 설계까지 일관된 형식의 SW 시스템 분석 설계 도구

                 - 클래스 다이어그램과 병행되며 상호간 일관성 요구됨

       * 작성시기

           요구정의→분석→기본설계→상세설계→개발→구현

   ④ Collaboration Diagram

       * 용도 - Sequence Diagram과 동일함.

                 - 객체와 메시지를 구조적으로 표현.

                 - Sequence Diagram과 의미 손실없이 변환 가능.

       * 작성시기

           요구정의→분석→기본설계→상세설계→개발→구현

   ⑤ State Chart Diagram

       * 용도 - 하나의 객체가 생성되어 소멸 될 때까지의 모든 상태를 분석 표현.

       * 작성시기

           요구정의→분석→기본설계→상세설계→개발→구현

   ⑥ Activity Diagram

       * 용도 - 일(Activity)의 수행 순서와 처리흐름 모델링. 플로우 차트와 용도 비슷.

       * 작성시기

           요구정의→분석→기본설계→상세설계→개발→구현

   ⑦ Component Diagram

       * 용도 - 컴포넌트로 이루어진 구성체계 표현. 정적 구성관계 표현.

       * 작성시기

           요구정의→분석→기본설계→상세설계→개발→구현

   ⑧ Deployment Diagram

       * 용도 - 컴퓨팅 환경인 노드와 그 노드에 배치할 컴포넌트 구성을 나타냄.

       * 작성시기

           요구정의→분석→기본설계→상세설계→개발→구현

   ⑨ Object Diagram

       * 용도 - 특정 조건하에서 주요 객체들의 속성과 객체관계를 분석함으로써

                   클래스 모델의 완전성 검증.

       * 작성시기

           요구정의→분석→기본설계→상세설계→개발→구현

----------------------------------------------------------------------------------------

2. Things

    = Structural Things + Behavioral Things + Grouping Things + Annotation Things

   ① Structural Things

       * Class : 같은 종류의 객체 집합

 

       * 인터페이스 : 오퍼레이션을 선언만 하고 구현하지 못함.

       * Collaboration(협력) : 구현관점에서 어떤 목적을 달성하기 위한 일련의 행위

                 

       * Use Case : 시스템이 제공하는 서비스 혹은 기능단위

                   

       * Active Class : 하나 이상의 프로세스나 쓰레드를 갖는 객체를 파생하는 클래스 기술

                    

       * Component : 시스템에서 독립적인 실행단위 혹은 배포단위로 관리되는 한 묶음의 SW

                     

       * Node : 연산능력이 있는 물리적 요소(컴퓨팅)

                       

   ② Behavioral Things(행위사물)

       * Interaction(교류) : 객체들간 주고받는 메시지

                          

       * State Machine(상태머신) : 객체의 상태와 상태간 허용된 액션 정의

                           

    ③ Grouping Things(그룹사물)

       * Package : UML요소를 그룹으로 묶어놓은 것

                                 

   ④ Annotation Things(주해사물)

       * Note : 주석

                     

----------------------------------------------------------------------------------------3. Relationshhip(관계)

   ① Dependency : 한 쪽사물이 그 역할을 수행키 위해 다른 사물의 도움이 반드시 필요한 경우

                       

   ② Association : 한 쪽 사물에서 상대편 사물 참조.

                       

   ③ Generalization : 상속관계

                       

   ④ Realization : 선언하는 사물과 구현하는 사물간 관계.

                       

----------------------------------------------------------------------------------------

출처

http://blog.naver.com/westengirl/140003904446

'My work space > Java' 카테고리의 다른 글

Ⅳ. Class Diagram  (0) 2008.08.20
Ⅲ. Use Case Diagram, Use Case 정의서  (0) 2008.08.20
Ⅰ. UML 개요  (0) 2008.08.20
J2EE , J2SE 한글 API [다운가능]  (0) 2008.08.20
JDK1.4 Logging API의 사용을 통한 Logging  (0) 2008.08.20
2008. 8. 20. 15:04

Ⅰ. UML 개요

1. UML 이란..?

   : Unified

   : Modeling Language

   : Object Oriented

   : 적용분야에 제한이 없다.

2. UML 특징

   * 가시화 언어 + 명세화 언어 + 구축언어 + 문서화 언어

3. UML 등장의 의의

   * 표기체계의 통합 및 표준화

   * 개발 프로세스와 개발언어에 독립적 표기체계

   * 적용에 제한없는 범용적 표기체계

----------------------------------------------------------------------------------------4. 모델링

   * 모델 : 간소화 시켜놓은것.

   * 목적 - 시스템의 시각화

             - 시스템의 구조나 행위 명시

             - 시스템 구축 안내 템플릿 제공

             - 결정사항을 문서화

   * 원칙 - 작성할 모델의 적절한 선택

             - 다양한 각도에서 작성 가능

             - 실체의 정확한 반영

             - 하나의 모델은 충분치 않음.

----------------------------------------------------------------------------------------

5. 객체지향

   * 객체 : 현실에 존재하는 실체가 인간의 사고과정을 통해 머리속에 정리된 개념

   * 객체의 조건 = 상태 + 행위 + 식별자

   * 클래스 : 유사한 특성을 가진 객체들의 모임

               = Attribute + Operation

   * 객체지향의 특성

        - 캡슐화 : 속성과 오퍼레이션의 객체내 결합. 정보은폐가능.

        - 추상화 : 실체의 관심부분만 취하는 방식. 다양성을 가짐.

        - 상   속 : Generation 과 Specialization으로 중복 제거.

        - 다형성 : 동일한 외부 명령에 대해 각 객체가 서로 다른 방식으로 수행.

                       고수준의 추상성 제공, 외부에서 객체의 오퍼레이션 접근용이. 재사용성 증대.

   * 객체지향의 장점

        - 실세계를 정확히 반영

        - 하나의 패러다임

        - 재사용성

        - 높은 안정성

   * 객체지향의 단점

        - 전문가 부족

        - 분석, 설계, 구현 모두가 적용되어야 의미 있음.

        - 다소간의 시스템 성능 저하

출처http://blog.naver.com/westengirl/140003902164

2008. 8. 20. 15:03

J2EE , J2SE 한글 API [다운가능]

ico-file j2ee한글api_1.3.zip
ico-file j2se한글api.zip

ejb interface 찾아보는데 j2se에서 한참동안 찾고 허무해졌다는....


다운받을 수 있게 올려놨습니다


덤으로 j2se 5.0 한글도 올려놨습니다


초보라서 아직까진 한글로 보고 있습니다 ..

'My work space > Java' 카테고리의 다른 글

Ⅱ. UML구성요소  (0) 2008.08.20
Ⅰ. UML 개요  (0) 2008.08.20
JDK1.4 Logging API의 사용을 통한 Logging  (0) 2008.08.20
프로그래밍에유용한사이트  (0) 2008.08.20
AWT/SWING 성능 비교(기본 출력 기능)  (0) 2008.08.20
2008. 8. 20. 15:01

JDK1.4 Logging API의 사용을 통한 Logging

▩ JDK1.4 Logging API의 사용을 통한 Logging

출처: http://www.nulunggi.pe.kr/board/board/edit.asp?ref=1768&number=1825&page=1&txtrCount=20&tableName=board&code=D6

   - 개발시 발생하는 에러외에 운영과정에서 발생하는 버그를 찾는 데 도움을 줌
   - 시스템이 운영되는 과정에서 발생하는 문제를 기록해 두었다가 복구용으로 사용함
   - 남겨야하는 모든 기록은 전부 남겨야 한다.
   - 불필요한 너무 많은 로그는 남기지 않는다.
   - 특히 로그메세지는 특정 사용자와 관련되어 있는 경우 아이디가 반드시 기록되도록 한다.
   -

1. 기본적인 Console 로그
>>>>> jdk14Logger.java
import java.util.logging.Logger;

public class Jdk14Logger1
{
    public static void main(String args[]){
        Logger.global.info("프로그램을 실행 했습니다.");
    }
}



2. Log Level
   - Level.SEVERE: 프로그램이 복구할 수 없는 치명적인 에러, 즉시 조치 필요
   - Level.WARNING: 심각한 에러이지만 즉각적인 처리를 하지 않아도 되는 경우
   - Level.INFO: 프로그램 실행 정보를 기록
   - Level.CONFIG: 프로그램 환경 정보 기록
   - Level.FINE, FINER, FINEST: 프로그램의 흐름을 추적할 때 사용(디버깅)
   - Level.ALL: 모든 로그 레벨을 기록
   - Level.OFF: 모든 로그 레벨을 기록하지 않음

   - ConsoleHandler의 기본 로그 레벨은 INFO임

>>>>> LoggerTest.java: Level의 지정
import java.util.logging.Logger;
import java.util.logging.Level;

public class Jdk14Logger2 {

    public static void main(String[] args) {
        Logger.global.setLevel(Level.WARNING);
       
        Logger.global.info("Start Program");
        Logger.global.config("Configuration");
        Logger.global.fine("Fine Level");
        Logger.global.warning("Warning Level");
        Logger.global.finer("Finer Level");
        Logger.global.severe("Severe Level");
        Logger.global.info("info Program");
    }
}



3. Logger Method
   - servere(String msg)
   - warning(String msg)
   - info(String msg)
   - config(String msg)
   - fine(String msg)
   - finer(String msg)
   - finest(String msg)

   - log(Level, String msg)
   - log(Level, String msg, Object param1)
   - log(Level, String msg, Throwable thrown)
   - logp(Level, String sourceClass, String sourceMethod, String msg)



4. JDK 1.4는 로거의 계층을 트리구조로 관리함

                 global
                   │
           ┌───┴───┐
           │              │
         visit            sky
           │              │
   ┌───┴───┐      │
   │              │      │
  edit            write   visit


Logger globalLogger = Logger.global;
Logger logger1 = Logger.getLogger("visit");  
Logger logger2 = Logger.getLogger("visit.edit");
Logger logger3 = Logger.getLogger("visit.write");
Logger logger4 = Logger.getLogger("sky.visit");



5. 로깅 API의 구조
   - Logger의 로깅 메소드가 호출되면 LogRecord 객체가 생성되고 그 객체는
     Logger에 등록되어 있는 Handler에 전달된다.
     LogRecord를 전달받은 핸들러는 그 핸들러가 이용하는 저장 방법에 따라 로그 데이터를
     기록한다.

   - LogRecord --> Logger:Filter --> Handler:Filter --> File, Console, DB에 출력함
                                                     │
                    │
                    └ Formatter



6. Jdk1.4에 등록된 Handler
   - MemoryHandler  : 메모리에 로그 데이터 저장
   - FileHandler    : 파일에 저장
     . /: 경로 구분자
     . %t: 시스템의 임시 디렉토리
     . %h: 현재 사용자의 홈 디렉토리
     . %g: 순환 로그의 구분에 필요한 문자
     . %u: 파일명 충돌을 피하기 위해 사용되는 고유숫자
     . %%: %문자 표현

   - SocketHandler  : 특정 서버로 전송
   - ConsoleHandler : 콘솔 화면에 출력
   - StreamHandler  : 이 클래스를 상속하여 새로운 핸들러 구현




▩ Logging API의 실습

1. FileHandler에서 XMLFormater의 사용

>>>>> Jdk14Logger3.java
import java.util.logging.Logger;
import java.util.logging.FileHandler;
import java.util.logging.Level;

public class Jdk14Logger3 {
    public static void main(String[] args) throws java.io.IOException {
        Logger jdk14Logger = Logger.getLogger("nulunggi.logger");
        jdk14Logger.setUseParentHandlers(false); 
        jdk14Logger.setLevel(Level.WARNING);
       
        FileHandler handler = new FileHandler("%h/java%u.log", 64*1024,3,true);
       
        jdk14Logger.addHandler(handler);
       
        jdk14Logger.severe("시스템에 심각한 문제가 발생했습니다.");
        jdk14Logger.warning("데이터베이스 접속에 실패 했습니다.");
    }
}



C:\Documents and Settings\Administrator폴더에 java0.log.0 파일이 생성되어 있습니다.



2. FileHandler에서 SimpleFormater의 사용

>>>>> LoggerFileText.java
import java.util.logging.Logger;
import java.util.logging.FileHandler;
import java.util.logging.SimpleFormatter;
import java.util.logging.Level;

public class Jdk14Logger4 {

    public static void main(String[] args) throws java.io.IOException {
        Logger jdk14Logger = Logger.getLogger("nulunggi.logger");
        jdk14Logger.setUseParentHandlers(false);
        jdk14Logger.setLevel(Level.FINE);
       
        FileHandler handler = new FileHandler("%h/java%u.log", 64*1024,3,true);
        jdk14Logger.addHandler(handler);
       
        SimpleFormatter formatter = new SimpleFormatter();
        handler.setFormatter(formatter);
       
        jdk14Logger.severe("시스템에 심각한 문제가 발생했습니다.");
        jdk14Logger.warning("데이터베이스 접속에 실패 했습니다.");
    }
}



3. 설정 파일: jre/lib/logging.properties
############################################################
#      Default Logging Configuration File
#
# You can use a different file by specifying a filename
# with the java.util.logging.config.file system property. 
# For example java -Djava.util.logging.config.file=myfile
############################################################

############################################################
#      Global properties
############################################################

# "handlers" specifies a comma separated list of log Handler
# classes.  These handlers will be installed during VM startup.
# Note that these classes must be on the system classpath.
# By default we only configure a ConsoleHandler, which will only
# show messages at the INFO and above levels.
handlers= java.util.logging.ConsoleHandler

# To also add the FileHandler, use the following line instead.
#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler

# Default global logging level.
# This specifies which kinds of events are logged across
# all loggers.  For any given facility this global level
# can be overriden by a facility specific level
# Note that the ConsoleHandler also has a separate level
# setting to limit messages printed to the console.
.level= INFO

############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################

# default file output is in user's home directory.
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter

# Limit the message that are printed on the console to INFO and above.
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter


############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################

# For example, set the com.xyz.foo logger to only log SEVERE
# messages:
visit.level = WARNING




▩ Log4J 활용하기
   - http://logging.apache.org/log4j/docs/index.html
   - Download: http://jakarta.apache.org/site/binindex.cgi
   - jakarta-log4j-1.2.8\dist\lib안에 있는 log4j-1.2.8.jar 파일을
      C:\j2sdk1.4.2_03\jre\lib\ext, D:\resin-2.1.11\lib폴더에 복사합니다.

1. Log Level
   - Level.FATAL: 치명적인 시각한 에러 발생시 사용
   - Level.ERROR: 어플리케이션이 수행 가능한 정도의 에러 발생시 사용
   - Level.WARN: 시스템에 문제를 일으킬수 있는 정도의 에러 발생시 사용
   - Level.INFO: 어플리케이션의 정보를 기록할때 사용
   - Level.DEBUG: 어플리케이션의 상태에 대한 상세 정보를 나타낼 때 사용


2. 로그 기록 Method
   - FATAL 로그 메시지 기록
     . fatal(Object message)
     . fatal(Object message, Throwable t)
   - ERROR 로그 메시지 기록
     . error(Object message)
     . error(Object message, Throwable t)
   - WARN 로그 메시지 기록
     . warn(Object message)
     . warn(Object message, Throwable t)
   - INFO 로그 메시지 기록
     . info(Object message)
     . info(Object message, Throwable t)
   - DEBUG 로그 메시지 기록
     . debug(Object message)
     . debug(Object message, Throwable t)


3. Console Log의 실습
   - BasicConfigurator.configure()은 기본적으로 콘솔 로그를 포함함

>>>>> log4jTest1.java
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
import org.apache.log4j.BasicConfigurator;

public class log4jTest1 {

    public static void main(String[] args) throws java.io.IOException {
        BasicConfigurator.configure();
       
        Logger logger = Logger.getLogger("visit");
        logger.setLevel(Level.INFO);
       
        Logger barlogger = Logger.getLogger("visit.log4jTest1");
       
        logger.info("방명록 테스트 시작.");
        logger.debug("DEBUG 레벨 로그.");
       
        barlogger.info("log4jTest1 로그 기록");
        barlogger.debug("log4jTest1 DEBUG 레벨 로그");

    }
}



4. PatternLayout의 변환 캐릭터
   - C: 로그 메시지를 기록하려는 클래스의 완전한 이름 출력
   - d: 로그 메시지를 기록한 시간을 기록한다.
   - p: 로그 메시지의 우선순위 출력
   - m: 로그메시지 자체
   - M: 로그메시지를 기록하려는 메소드의 이름
   - n: 플랫폼의 라인 구분자를 출력한다.
   - %: %%는 '%'를 출력한다.


5. Appender의 종류
   - org.apache.log4j.ConsoleAppender: 콘솔에 로그메시지를 출력한다.
   - org.apache.log4j.FileAppender: 파일에 로그메시지를 기록한다.
   - org.apache.log4j.RollingFileAppender: 파일에 로그메시지를 기록하고, 파일이 일정 크기가 되면 다른이름으로 저장하고
     , 새롭게 로그 메시지를 기록하기 시작한다.
   - org.apache.log4j.DailyRollingFileAppender: 파일에 로그 메시지를 기록하며, 하루 단위로 로그 파일을 변경한다.
   - org.apache.log4j.net.SMTPAppender: 로그메시지를 이메일로 전송한다.
   - org.apache.log4j.nt.NTEventLogAppender: NT의 이벤트 로그 시스템에 로그메시지를 전송한다.



6. 속성 파일을 이용한 로그의 기록
>>>>> log4j.properties
log4j.rootLogger=INFO, console

log4j.logger.visit.bean=DEBUG, R
log4j.additivity.visit.bean=false

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.SimpleLayout

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=d:/temp/java/test.log
log4j.appender.R.MaxFileSize=64KB
log4j.appender.R.MaxBackupIndex=3
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss} %C{1}.%M - %m%n


속성의 해설:
- 루트로거의 루트는 visit이다.
- 루트로거는 console Appender를 사용한다.
- console Appender는 SimpleLayout를 상용한다.
- visit.bean의 레벨은 DEBUG이다.
- visit.bean의 레벨의 로거는 상위 레벨의 Appender를 상용하지 않는다.
- visit.bean은 RollingFileAppender를 사용한다.
- RollingFileAppender는 D:\temp\java 폴더에 기록한다.
- RollingFileAppender가 기록하는 최대 로그 파일의 크기는 64Kb로 한다.
- RollingFileAppender는 최대 3개의 백업 로그를 만든다.
- RollingFileAppender는 PatternLayout을 사용한다.
- PatternLayout은 [%-5p] %d{yyyy-MM-dd HH:mm:ss} %C{1}.%M - %m%n 을 사용한다.


속성파일의 사용은 PropertyConfigurator.configure("log4j.properties")을 추가한다.

>>>>> log4jTest3.java
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
import org.apache.log4j.PropertyConfigurator;

public class log4jTest3 {

    public static void main(String[] args) {
        PropertyConfigurator.configure("log4j.properties");
       
        Logger rootLogger = Logger.getRootLogger();
        rootLogger.info("프로그램 시작");
       
        Logger mailLogger = Logger.getLogger("visit.bean");
       
        mailLogger.info("테스트 시작.");
        mailLogger.debug("DEBUG 레벨 로그.");
       
        mailLogger.info("visit 로그 기록");
        mailLogger.debug("visit LOG DEBUG 레벨 로그");
       
        rootLogger.info("프로그램 끝");
    }
}




▩ 방명록에 Log4j적용하기
   - 자료실 325번 참고

>>>>> log4j.properties
log4j.rootLogger=INFO, console

log4j.logger.visit.bean=DEBUG, R
log4j.additivity.visit.bean=false

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.SimpleLayout

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=D:/resin-2.1.11/doc/jvisit_100_mysql_bean/logging/visit.log
log4j.appender.R.MaxFileSize=64KB
log4j.appender.R.MaxBackupIndex=3
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss} %C{1}.%M - %m%n



>>>>> Log4j를 적용한 VisitMgr.java 빈즈
package visit;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
import org.apache.log4j.PropertyConfigurator;

public class VisitMgr {
    private final String JDBC_DRIVER = "org.gjt.mm.mysql.Driver";
    private final String JDBC_URL = "jdbc:mysql://localhost:3306/mysqldb?useUnicode=true&characterEncoding=euc-kr";
    private final String USER = "nulunggi";
    private final String PASS = "123";

    Logger rootLogger = Logger.getRootLogger();
    Logger visitLogger = Logger.getLogger("visit.bean");

    public VisitMgr(){
        PropertyConfigurator.configure("D:/resin-2.1.11/doc/jvisit_100_mysql_bean/logging/log4j.properties");   
        rootLogger.info("빈이 호출되었습니다.");
        visitLogger.info("VisitMgr빈의 생성자가 호출되었습니다.");

        try{
            Class.forName(JDBC_DRIVER);
        }catch(Exception e){
            visitLogger.fatal(USER + "계정에 대한 MySQL JDBC 드라이버 로딩 실패");
            System.err.println("Error: JDBC 드라이버 로딩 실패");
        }
    }
   
    public Vector getVisitList(){
        visitLogger.info("getVisitList()메소드가 호출되었습니다.");
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        Vector recList = new Vector();
        String strQuery = "SELECT num,wname,wcontent,reg_date,password FROM visit ORDER BY num DESC";

        try{
            conn = DriverManager.getConnection(JDBC_URL, USER, PASS);

            visitLogger.info("Mysql mysqldb 데이터베이스 접속되었습니다.");
           
            stmt = conn.createStatement();
            rs = stmt.executeQuery(strQuery);
            while(rs.next()){
                VisitBean recBean = new VisitBean();
                recBean.setNum(rs.getInt("num"));
                recBean.setWname(rs.getString("wname"));
                recBean.setWcontent(rs.getString("wcontent"));
                recBean.setReg_date(rs.getString("reg_date"));
                recBean.setPassword(rs.getString("password"));
               
                recList.add(recBean);   
            }
        }catch(Exception e){
           
            visitLogger.error(strQuery + "를 실행하는 중 에러가 발생했습니다.");
           
            System.out.println("Exception:" + e);
        }finally{
            if(rs != null) try{rs.close();} catch(SQLException e){}
            if(stmt != null) try{stmt.close();} catch(SQLException e){}
            if(conn != null) try{conn.close();} catch(SQLException e){}
            System.out.println("getVisitList() 메소드가 호출되었습니다.");
        }
        return recList;
    }
}



'My work space > Java' 카테고리의 다른 글

Ⅰ. UML 개요  (0) 2008.08.20
J2EE , J2SE 한글 API [다운가능]  (0) 2008.08.20
프로그래밍에유용한사이트  (0) 2008.08.20
AWT/SWING 성능 비교(기본 출력 기능)  (0) 2008.08.20
소켓(Socket)  (0) 2008.08.20
2008. 8. 20. 15:01

프로그래밍에유용한사이트

프로그래밍에 유용한 사이트

 

 

자바 뉴스그룹/Java Community

  comp.lang.java.programmer

  국내

  han.comp.lang.java

  Java Lobby (A Java Developers' community)

 

국내 자바 사이트

  JavaCafe.or.kr 사이트

  yoonforh의 자바 묻고 답하기 게시판

  김덕태 님의 자바 1.1 한글 관련 내용

  한국 자바 개발자 컨퍼런스

  자바 문서 한글화 사이트(자바 문서 한글화에 참여할 뜻있는 분들을

                                    기다리고 있습니다.)

  김필호 님의 자바와 한글 게시판 (유료 자바 게시판이며 유료인만큼

  답변이 신속, 성실하게 올라옵니다.)

  김필호 님의 자바 Q&A 게시판

  강신동 님의 Korea Java Developer Connection

  지니에 흥미를 가지고 있는 그룹

  Whang's Java List Version 2.0

  Java FAQ - Korean Version

  광운대 자바랜드(JavaLand:자바네 동네)

  홍종진 님의    자바의 한글 처리 문제에 관한 리소스

  이경하 님의    자바 페이지

 

자바 온라인 매거진

  JavaWorld - IDG's magazine for the Java community

  Java Developer's Journal

  Javology: Contents

 

자바 리소스 디렉토리

   The Community Resource for Jini™ Technology

   Dr.Dobb's Java

   Java Directory of dmoz-open directory project  

   JavaShareWare.Com

   KPCB: Keiretsu

   Gamelan: Earthweb's Java Directory

   JARS Java Resource Listings

   artima.com - a resource for Java and Jini developers

   Jini Links

 

자바 기술

  Threads/Concurrency

      package util.concurrent (by Doug Lea)

      (Book) Concurrent Programming in Java

   JINI

      The JINI COMMUNITY

      Jan Newmarch's Guide to JINI Technologies(A tutorial)

      지니에 흥미를 가지고 있는 그룹(Jini Korea Interesting Group)

    JNDI

      Java(TM) Naming & Directory Interface (JNDI(TM))

    Internationalization

      Writing Global Programs

    RMI

      rmi-users.logfile by thread

    JNI

      Frequently Asked Questions - JavaTM 2 SDK v1.2 and JNI

    JDBC

     JDBC Frequently Asked Questions

     http://splash.javasoft.com/jdbc/jdbc.drivers.html

     George Reese's Java Pages(JDBC-mSQL 홈페이지)

     The JDBC(tm) database access API.

     MsqlJava(mSQL.class) Home Page

     오러클 JDBC 드라이버 다운로드

    자바 빈즈

      JavaBeans - Component APIs for Java

      Java Beans White Paper자바 빈즈 개발자를 위한 Coffee Grinder

      BeanContext Examples

      BeanContext Development Kit (BcDK) Homepage

      Java 1.2 Unleashed chapter 29 - Glasgow Developments

    자바 컴파일러

      IBM 사의 Jikes 컴파일러

      GCJ, The GNU Compiler fo Java Programming Language

    자바 역컴파일러

      Jad - the fast JAva Decompiler

      IceBreaker : A "Visual" Java decompiler/disassembler

      Mocha, the Java Decompiler

    자바 C 번역기

      Toba: A Java-to-C Translator

    오피스 웨어

       ThinkFree Office(trying to be MS Office compatible)

       로터스 e_Suite

       Download Marimba Software

       Unixoid Shell of Java(자바 셸)

     메일 프로그램

       피카소 메일

     자바 파운데이션 클래스 - Swing

       Java Foundation Classes

       Swing by Matthew Robinson and Pavel Vorobiev -

       Netscape IFC: Overview

       Netscape DevEdge - IFC

       마이크로소프트의 자바 사이트(AFC)

     자바 Plugins

       Java Plug-in Product Homepage

       Java Plug-in 1.2 Software FAQ

       JAVA PLUG-IN SCRIPTING (자바 플러그인을 스크립트와 연동)

     자바 Collections API

       Download JDK 1.1 Collections Package

     Reference objects

       a Javaworld article

       Reference Objects and Garbage Collection

       Package summary of java.lang.ref

       Chapter 9 of Inside the Java 2 VM Garbage Collection

    자바 개발 환경

        시맨텍 까페

        비주얼 까페 팁 페이지

        시맨텍 비주얼 까페

        JBuilder Home page

        썬 자바 워크숍

        넷빈즈

        JDE - Java Development Environment for Emacs

       

        마이크로소프트 (비주얼 J++/C++)

        Visual J++ Web site

        Using MSVC for Java

        Using JDK1.1 in Visual J++

        Microsoft SDK for Java Download

    자바 CGI

       Java CGI HOWTO: Executing a Java CGI Program

       Java CGI HOWTO

    자바 웹 서버/JSP/서블릿

       Jeeves Home Page

       The JSDK-Apache Project

       The JavaServer Pages

       The Jakarta Project(tomcat)
       
Tomcat을 Apache 서버에 연결시키는 HOWTO

       GNUJSP

       allaire 사의 JRun

       Java Servlet API(Sun)

       Hrl's Servlet Express

       New Atalanta Comm.'s ServletExec

       The X- Jeeves Server and Servlets FAQ

    Security

       Frequently Asked Questions - Applet Security

       Signed Applet Example (JDK 1.1.x)

       아래의 빈번한 질문과 답 사이트에 좀더 많은 정보가 있습니다.

    Performance / Benchmark

       Java Performance Tuning

       Jack Shirazi's Java Performance Tuning website

       Java Benchmark

       Volano Report

       Java Versus C/C++ Benchmarks

       Java Memory Management Performance

    자바 버그

       The Unofficial Java Spec Report

    XML 관련

        REC-DOM-Level-1-19981001 Java Language Binding

        Working with XML - The JavaTM Api for XML Parsing (JAXP)

    UML

        OMG UML 1.3 specification

        UML 툴

        플라스틱 소프트웨어(국산)

        Together/J(free whiteboard version avail.)

        Rational Rose

        Argo/UML(free and open source)

 

 자바 튜토리얼

   JDC Training and Tutorials

   Server-side computing with XML, , JDBC, Swing and Servlets

   JRE Usage Example

   Programming in Java - A Tutorial by David Mitchell

   자바 1.1 이벤트 모델 요약 설명

   Java Documentation in Windows Help Format

  ->추천:윈도우 help 형식으로 된 자바 도큐먼트

   yoonforh의 자바 튜토리얼

   Trail Map: The Java Tutorial     추천:자바 공식 튜토리얼

   자바 클라이언트/서버 강의

   Be a Java Master with Examples

   The Java Developer: How Do I?

   Java Table of Contents by Richard G Baldwin

   넷스케이프의 ViewSource

   Enterprise JavaBeans Tutorial

 

자바 빈번한 질문과 답(FAQ)

  SUNSITE's JAVA Frequently Asked Questions

                                (FAQ list of newsgroup comp.lang.java)

   The Java(TM) FAQ  (a good FAQ also published as a book)

   자바 프로그램을 윈도우 NT의 서비스로 만드는 방법

   (1) 링크 모음

   (2) JNI 사용하여 구현한 예

    애플릿 서명 예제 - 자바 홈페이지의 보안 문제 페이지 참고

   (1) JDK 1.1.x의 경우

   (2) JDK 1.2.x의 경우

   넷스케이프 사의 서명 도구 페이지

   VeriSign 사의 객체 서명 FAQ

   익스플로러의 자바 서명(Trust-Based Security for Java)

   익스플로러의 자바 서명 FAQ

   Microsoft Java VM version check

 

자바 공개 소스

   Tim Macinta's Java Swapware

   Metrochat

   LazloFont

   How to access a RS-232 port from Java?

   JavaChat 1.0, a distributed Java applet

   Jim Buzbee's Hershey Font Page

   The Java Cup International Contest Winners Circle

   Simple Java Servers

   Java Distributed TCP/IP Message Handling System

   Radu Sion의 소스

   Rich Burridge Home Page

   Joerg Meissner - priv@te szene - JAVA(CreditRoll.java)

   Typewriter Applet

 

자바 포팅 이슈

   Java-Linux

   jGuru Java on Linux FAQ

   Platforms Supporting Java

   IBM 자바 개발 센터

   IBM's Java-related Technology

   KAFFE - A virtual machine to run Java(tm)* code

   alphaWorks

   OSF Java Program Page

   넷스케이프의 JDK 1.1.x 지원

 

썬의 자바 공식 페이지

   자바 홈페이지

   Documentation Index

   White Papers

   Using HotJava(tm)

   Java(tm) IDL

   Java API Overview

   Java: The Inside story

   Java Coding Conventions(자바 코딩 관례)

   Examples of Using the JDK 1.1 AWT

   Java Platform Debugger Architecture

   JIMI Software Development Kit - a class library for managing

 

자바 스크립트

   JavaScript Developer Central(DevEdge Online)

   JavaScript Documentation

   Microsoft Scripting Technologies(JScript and VBScript)

   WEBFX Javascript Examples

   JavaScript Library

   The JavaScript Index v2.0

   Squatt Java/JavaScript Net-Zine

   About Kyle's JavaScript Navigator Window

오픈지엘 - 오픈지엘 공식 사이트, 생각외로 뉴스가 잘 올라온다.
NeHe Tutorial - OpenGL Tutorial. 내용도 좋지만, 각 플랫폼, 언어별로 구현된 소스가 유용.
OpenGL man page - OpenGL MAN 페이지. 일종의 매뉴얼.
OpenGL Manual - SGI 의 OpenGL 1.2 매뉴얼
GL4Java - 자바를 위한 OpenGL
OpenGL Win32 Tutorial - OpenGL Win32 Toturial
GLUT3 - glut3 소스 및 다운로드.
glut for win32 - Glut for Win32 DLL Download
OpenGL Gamedev - OpenGL Gamedev FAQ & Mailing list
cannon_smash - OpenGL 로 만든 오픈소스 탁구게임
OpenGL FAQ - OpenGL FAQ
OpenGL Reference Manual - 온라인북
OpenGL Programming Guide - 온라인북
OpenGL 수퍼 바이블 - 온라인북
OpenGL 튜토리얼 링크 - OpenGL 튜토리얼 링크
OpenGL 게임개발 FAQ - OpenGL 게임개발 FAQ
GLVelocity - OpenGL 관련 소스 및 뉴스, 토론 등등
DelphiGL - Delphi 로 하는 OpenGL
Yindo - 차세대 웹 애플리케이션
Dip2K's OpenGL - 여러 GL 관련 예제가 있는 국내 OpenGL 관련 사이트
GLScene - OpenGL Solution for Delphi
FLTK - OpenGL 그래픽 유저인터페이스 라이브러리(LGPL)
Quesa - Apple Quick Draw 3D Open-source Implementation
GLdomain - 파티클, 그라비티 등에 관한 튜토리얼
게임튜토리얼 - 오픈지엘 튜토리얼 및 MP3 라이브러리, 쓰레드 예제 등등이 있다.
Delphi3D - 델파이와 OpenGL를 사용한 최신 그래픽 기술에 관한 정보
DirectX Dev - Developer-only Forum
DirectX8 FAQ - Microsoft DirectX 8 개발자 FAQ
DirectX 개발 - DirectX Developer Center (MSDN)
XBOX - Microsoft XBOX
Mr.Snow's column - DirectX8 튜토리얼
Gamedev DirectX - Gamedev.net's DirectX resources
DrunkenHyena - Direct3D 8.0 Tutorial
Meltdown2001 - DirectX Meltdown2001 presentation
ShaderStudio - Vertex/Pixel Shader 를 쉽게 쓸 수 있는 툴.
Pixel/Vertex Shader - 톰스하드웨어의 픽셀/버텍스 쉐이더에 대한 간단한 정리
GDC2002-DirectX - Game Developer's Conference 2002 - MS DirectX Tutorial
STEEL 프로그래밍 리소스 - 200여개의 그래픽 관련 문서 및 튜토리얼 모음
그래픽스문서찾기 - 다운로드는 안되고 문서명만 검색되네.
파일포맷 - 모든 파일 포맷에 대해서.
게임프로그래밍뉴스그룹 - comp.games.development.progrmming.algorithms
GPGStudy.com - Game Programming Gems 스터디 사이트
KGDA - 한국 게임 개발자 협의회
FlipCode - 게임개발관련 뉴스와 자료들
GameDev.Net - game developer network
가마수트라 - game developer webzine.
nVidia Developer - nVidia 사의 개발자 네트워크
ATI Developer - ATI 사의 개발자 네트워크
Matrox Developer - 매트록스 사의 개발자 네트워크
게임-디벨로퍼 - 게임 개발 관련 자료 검색 전용
쿼터니온 - 가마수트라의 쿼터니온 설명
문서들 - 가마수트라의 프로그래밍 관련 문서
gdconf - 게임 디벨로퍼 컨퍼런스
디벨로퍼 코너 - 개발자들이 떠드는 곳
인텔 - 개발자 네트워크 게임부문
게임도큐먼트 - 심형근님의 게임개발 관련 각종 문서들
게임튜토리얼 - 게임관련 튜토리얼, 문서, 토론 등등
씽크존 - 가상 온라인 월드 개발자 네트워크
Genesis3D - 소스가 공개된 게임엔진. 유명.
Jet3D - Genesis3D를 기반으로 하는 차기 버전(소스공개)
타이탄프로젝트 - 퀘이크3의 맵을 읽는 엔진(소스공개)
AfterShock - GPL 퀘이크 렌더러
PolyCount - 퀘이크3/2, 언리얼, 하프라이프 등의 모델데이타.
소스포지의 3D 파운드리 - 소스포지의 공개된 여러 3D 관련 프로젝트 및 컨텐츠
3D Engine List - 3D Engine List - 우와 많다.
DDG Toolkit - Digital Dawn Graphics Toolkit (C++ OpenGL Terrain Toolkit)
OpenFX - 오픈소스 공개 모델러, 렌더러, 애니메이터(게임엔진아님)
FLY3D - FLY3D 게임 엔진. 책도 있음.
Crystal Space - 크리스탈 스페이스-멀티플랫폼 3D 게임 엔진
매직소프트웨어 - 3D Game Engine Design 이라는 책 소스 및 유용한 공개코드
Nevrax - GPL 게임 엔진(AI, 3D, 네트웍 포함. 베이어패치 및 아웃도어용)
OGRE - 객체지향 그래픽 렌더링 엔진(베지어패치 및 퀘이크 렌더러 등)
RadonLabs - Nebula Device 라는 공개엔진. Nomads 라는 게임에 사용.
NeoEngine - 네오엔진. 멀티 플랫폼 LGPL 게임엔진
크리스 헤커 - 크리스 헤커의 게임물리학 및 텍스쳐매핑관련 PDF 문서가 있다.
피터 린드스트롬 - 꽤 읽어봄직한 논문들
UNC GEOM - UNC 의 물리시뮬레이션, 기하학관련 리서치 그룹
casManG's 3D 게임 아트 - 3D 게임관련 모델링 튜토리얼 자료 많다.
ingava - Q3A Prgramming/Modeling Tutorial
Motion - 캐릭터 애니메이션에 관한 자료 및 문서
MathEngine - 실시간 물리엔진, 데모
Art Of Assembly - Art Of Assembly : 어셈블리 책 - 웹에 책 내용 다 있음.
게임인공지능 - 게임관련 인공지능
블랙북 - 마이클 애브래쉬의 블랙북 PDF
게임 모델링 툴 링크 - 모델링 툴, 스키닝 툴, 튜토리얼 및 리소스 링크
Creative - 크리에이티브사의 게임 개발 관련 자료
Amit's Link - Amit's Game Programming Information
리스텍 - 리스텍(lithtech) 게임엔진
NetImmerse - NDL사의 NetImmerse 엔진
Audiere - 오디에르. ogg, wav, mod, s3m 등을 지원하는 오디오 라이브러리(LGPL)
GDZine - 게임 개발자를 위한 웹진
Torque엔진 - Tribes 2 에 쓰였다는 Torque 게임 엔진. 개발자 당 $100 이란다.
HighEnd3D - 하이엔드 쓰리디. 마야, XSI, Shake 커뮤니티
씨쥐링크 - 컴퓨터 그래픽 관련
3D Links - 3D 관련 링크 및 뉴스
디지탈 프로듀서 - 디지털 영상 편집 및 3D 관련 웹진. 공짜 3D 모델도 있음.
아발론.뷰포인트 - 뷰포인트사의 공개 모델링 데이타들이 있는 곳.아발론
디지탈에이젼트 - 실사와 비슷한 3D 캐릭터가 말을 한다.(국내)
모델뱅크 - 뷰포인트사의 모델뱅크-상용
Steven Stahlberg 갤러리 - 여자 3D 캐릭터 죽~인다
3D Artisan - 국내 3D 관련 잡지
드림모션 - 국내 모션캡쳐 장비 회사
OpenEYE - 3DS MAX 사용자 그룹
3D 캐릭터 - 나잘난박사의 이상호님 홈
더-포즈 - Poser 애니메이션을 판다.
포져 - 3D 인체 포즈 및 애니메이션 툴. 훌륭...짝짝짝.
3D필름메이커 - 3D 영상 및 컨텐츠 개발 관련
밀크쉐이프3D - 쉐어웨어 로우 메쉬 에디터, 애니메이터(하프-라이프모델 지원빵빵)
안드로이드월드 - 안드로이드 관련 정보
소다플레이 - 마치 애완동물을 괴롭히는 것 같은...
메타모션 - 실시간 모션캡쳐 시스템
제니류님의 홈 - 마야 3D 케릭터 모델링과 애니메이션
CGLand - 다수의 CG 갤러리 및 링크
Digital Art Zone - Poser Map & Model 파는 곳
Motion Analysis - Motion Analysis : Motion Capture System/Software
Zygote - 상용 3D 모델 데이타
Famous3D - Facial motion-capture 솔루션
3D Artists - 세계적인 3D Artists 들의 작품 감상 및 포럼
소아나라 - 3D 아티스트. 실사와 거의 흡사한 이미지. 국산.
Kludge3D - 3D Modeling Tool (LGPL)
니트정보통신 - FilmBox, Toonz, Vicon 등의 디스트리뷰터
GMAX - 게임 MOD 개발용 gmax (공짜)
HCIKorea - 인간과 컴퓨터 상호작용 연구회
JoyCG - 여러 아티스트들의 3D 작품을 구경하고 싶을 때
KBS 기술연구소 - 방송에 관계된 여러 기술 정보
모캡코리아 - 모션캡쳐관련 서비스
Terragen - 공개용 지형 생성 툴
두모션 - 국산 기계식 모션캡쳐 시스템
Quest3D - 실시간 3D 멀티미디어 툴
소프트 쉐도우 - Michael Herf & Paul Heckbert 의 소프트쉐도우에 관한 페이지
쉐도우 - 쉐도우에 관한 여러가지 자료
Jeff Lander - Jeff Lander의 게임개발관련 문서
리얼타임렌더링 - 리얼타임렌더링책선전 및 각종 링크
Math3D - The 3D Computer Graphics Math Library Homepage
New York Univ. - New York Univ. Media Research Lab
Red3D - Non-photorealistic Rendering Links
쿼터니온 - 쿼터니온링크
SIGGRAPH PROCEEDINGS - ACM Digital Library(SIGGRAPH Proceedings Listing)
WhyQuat - Do you really need quaternion?
Nurbs++ - C++ Nurbs Library
매직소프트웨어링크 - 매직소프트웨어의 그래픽관련 링크
gdconf 2000 - Game Devel. Conf. 2000 procedings
gdconf 2001 - Game Devel. Conf. 2001 procedings
CFXWEB - 데모와 게임 개발에 관한 문서, 소스 및 갤러리
I_COLLIDE - 인터액티브하며 정확한 충돌 감지 라이브러리
ACM JGT - Journal of Graphics Tools
RTRT - RealTime RayTracer
피에르의 링크 - 3D, 수학, 물리관련 각종 링크
GeometricModeling - On-Line Geometric Modeling Notes. 맘에드는 주제들.
Heriot-Watt - Heriot-Watt University Graphics Notes. 설명양호.
미시간주립대 - 미시간주립대 그래픽스 노트. 프레젠테이션
Don Lancaster's Guru's Lair - Cubic Spline Library (PDF 서비스)
Paul Bourke - Curve 및 그래픽스 관련 노트 및 C 소스코드
Journal of Graphics Tools - 실제 현장에 바로 응용할 수 있는 그래픽스 연구
RayTracing - RayTracing Tutorial
TomasMöller - Real Time Rendering 의 저자
CassEveritt - nVidia 사 개발자, Per-Pixel Lighting 관련 연구
DavidBarraff - 현 Pixar (전 CMU). 강체시뮬레이션관련
Jos Stam - Alias|Wavefrot 사 근무. FFT 에 기반한 간단한 Fluid Solver
efg's 링크 - 시뮬레이션과 모델링에 관한 링크모음
그래픽스젬스 - 차례 및 소스 다운로드
BOID - BOID(새들의 무리?) 관련 정보(인공지능)
NatureWizard - 그래픽으로 자연을 표현하기 위한 정보들
오픈넙스 - 공개용 넙스(NURBS) 파일 포맷
Jan Kautz - BRDF, Shadow Bumpmap, Realtime Bumpmap 등등
ColDet - 공개 충돌 검사 라이브러리
University of Leeds - 여러가지 그래픽스 관련 기본적인 튜토리얼.
스탠포드대학 - 컴퓨터 그래픽스를 위한 수학적 방법(웨이블릿, 몬테카를로...)
Water - Rendering and Animation of Liquid
인텔3D 문서 - 인텔의 3D 소프트웨어 개발 관련 문서들
GTS - GNU Triangulated Surface Library
LargeModels - 공짜로 다운받는 무지 큰 3D 모델 파일들.
GDAlgorithm - Game Development Algorithm 메일링 리스트
PocketMovies - PocketMovies
Projectmessiah - Projectmessiah
Anzovin Studio - Anzovin Studio
AtomFilims - AtomFilims
4CSCG - 컴퓨터 그래픽 아트 관련
PepeLand - Daniel Martinez Lara
M. Gleicher 의 홈페이지 - 캐릭터 애니메이션 수업 및 모션 에디팅 논문 자료
캐릭터 애니메이션 강의자료 - 위스콘신
Thalmann - Thalmann's Home
CG KAIST - KAIST COMPUTER GRAPHICS LAB
Motion Editing Lecture - KAIST Motion Editing & Manipulation Class
서울대 그래픽스 랩 - 서울대 대학원 그래픽스 & 미디어 랩
Postech VR lab - 포항공대 VR 랩
H-Anim - Humanoid Animation Working Group
Virtual Humans - ben's Virtual Humans Page
Bio Virtual - 3차원 얼굴 뷰어
모션캡쳐 - 모션캡쳐 리서치
한국생산기술연구원 - 메카트로닉스 연구실(로봇관련정보)
Robotics - Mathematical Methods for Robotics and Vision
Linear Algebra - Computation Methods in Linear Algebra
MotionEditing Web - M.Gleicher 의 모션에디팅 메일링리스트
애니큐브 - 자신의 아바타를 만든다.
Heloli.com - 멋진 일본 캐릭터 애니. 카툰렌더링. 치마펄럭. 머리약간 펄럭.
경사면 걷기 - 경사면에서 걷기동작 생성에 관한 논문
스프링인간 - 플래쉬로 만든 고무줄 꼭두각시
DX8스키닝 - DX8 버텍스 쉐이더에 대한 간단설명 및 스키닝 등에 대한 상세한 설명
게임데브넷 - Character Animation with DirectX 8.0
캐릭터애니관련책 - Programming Dynamic Character Animation
CoderCorner - Pierre Terdiman의 Realtime Cloth, Flexporter, Z-Collide 등등 구경
Advanced Character Physics - Thomas Jakobsen의 GDC 2001 강연자료
ESC - 가상 나이트클럽.
메타휴먼 - 메타휴먼? 재미있는 프로젝트들을 연구하는 그룹.
Cal3D - 공개 캐릭터 엔진
Watt - 3D게임, 실시간렌더링 및 캐릭터 애니 강연자료
Expression - 공개 페이셜 애니메이션 툴킷(TTS, 맥스익스포터, 스크립팅)
LinuxGames - 리눅스게임에 관한 뉴스
리눅스 게임 톰 - 리눅스 게임에 관한 많은 뉴우스들.
OpenAL - Loki 사의 오디오 라이브러리
SDL - 쓸만한 멀티플랫폼 멀티미디어 라이브러리
인드리마 오픈소스 프로젝트 - 인드리마 콘솔을 위한 오픈소스 프로젝트 네트워크
Broodcast2000 - 리눅스시스템을 위한 실시간, 비선형 오디오 비디오 편집기 (소스공개)
Inovation3D - 오픈소스 3D 모델링 툴, 키프레임 애니메이션과 본도 지원(간단하게...)
Linux Game Dev. in GDC2001 - Linux Game Dev. in GDC2001
리눅스3D - 리눅스 3D 게임 뉴스
리눅스 3D (org) - 리눅스 3D 뉴스
LinuxVideo - Linux Video and DVD Project
인드리마 개발자 네트워크 - 리눅스 게임 콘솔 인드리마 개발자 네트워크
g-Matrix - kaswan 님의 게임 프로그래머를 위한 3차원 엔진 만들기
울트라 감자 - 뜨거운 감자 김성수님의 개인 홈 - 3D 의 몇몇 강좌와 게시판이 있슴당.
ALTOZ - 인공생명을 연구하는 (주)오즈 인터미디어의 인공생명팀
허영준씨개인홈 - 캐릭터 애니메이션에 관한 자료
GTC - 성균관대학교 게임 기술 개발 지원 센터
RedPixel - ACE, STL, Lua, OpenGL 등에 대한 정보.
Kano - 실시간그래픽스에 관심있는 일본개발자. GPG 일본판 번역자
Ádám Moravánszky - ShaderX 에 Bump Mapped BRDF Rendering 파트집필
Thomas Jakobsen - Game Engine, Physics, Character Animation, Denmark
Pion - 파연님 개인홈. 게임 개발 및 번역.
Cass Everitte - nVidia 사에서 일하는 카스 에버릿. 몇몇 오픈지엘 예제
Hoppe - 메쉬 최적화 및 기타 유용한 자료들. MS 사 댕김.
Newtype - MaxScript, D3D 등등의 여러 개발관련 정보.
Kaliver - 이주형님 개인홈. ASE Viewer 및 Qu Engine
쥐그라운드 - 게임 그라운드. 게임에 관련된 여러가지 정보들.
브렌더 - 최고의 공개 3D 모델러/애니메이터
demonews - 3D 게임 데모 정보
DPlayer - 댄스 플레이어. 무지 보기 좋다..
게임스팟 - 게임스팝 - 게임관련웹진
게임디벨로퍼코리아 - 게임디벨로퍼지 한국판
뷰포인트 - 뷰포인트사의 웹3D (메타스트림)
iWorld3D - 국내 Web3D 개발업체
와일드 탄젠트 - Web3D, Web Streaming, ....
sumea - 환상적인 자바 3D 영상
WEB3D 콘소시움 - 웹3D 콘소시움
Blaxxun3D - X3D 포맷을 지원하는 자바로 만든 3D 클라이언트
펄스3D - 꽤 괜찮은 캐릭터 애니메이션
슈퍼스케이프 - 워크맨 등의 가전제품에 써먹을만한...질은 별루...
샤우트3D - 자바 기반으로 만들어짐. 툴킷도 제공
사이코어 - Cult3D, CultEffect, PuppetTime 등의 프로덕트
드림스케이프 - 국내 웹3D 관련
GIBLE3D - 국내 웹 3D 뷰어 개발 업체
QEDSoft - 3D 웹 에이전트
오락닷컴 - 실시간 스트리밍 3D 춤 강좌 서비스
디지털에이전트 - 3D 캐릭터가 채팅 내용을 따라 읽어주는 등...
리눅스사랑넷 - 리눅스사용자라면 꼭 가봐야 할 사이트
KLDP - 리눅스사용자라면 꼭 가봐야 할 사이트
리눅스시스템관리 - 리눅스 시스템 관리자를 위한 홈페이지
Debian-KR 메일링 리스트 - 데비안-KR 메일링 리스트 아카이브
Trinux - 디스켓 3장에 들어가는 리눅스
linux-firewall - linux-firewall
certcc.or.kr - 한국정보보호센터
쉘프로그래밍 - 쉘프로그래밍매뉴얼
SAINT - 보안분석툴
securityfocus.com - 보안관련정보
정규표현식설명 - 정규표현식에 대한 설명
Thinkpad Tool - Thinkpad Notebook Linux Configuration Tool
네트워크프로그래밍 - BeeJ's Guide to Network Programming
webalizer - 웹 로그 분석툴
MRTG - 서버 네트워크 통계 프로그램
VirtualPC - 윈도우에서 리눅스를 깔 수 있다는
IBM Linux - 한국 IBM의 리눅스 기술문서 번역 및 자료
Linux C - Linux C 프로그래밍에 관한
헤커되기 - 헤커가 되는 법(에릭.S.레이몬드)
데비안사용자 - 국내 데비안 사용자 그룹
리눅스 가제트 - 리눅스관련 웹진
프렉 - 헤킹관련 웹진
CygWin - GNU + Cygnus + Windows
GNU GPL FAQ - GPL 에 관련된 빈번한 질문과 답
phpBB - PHP, MySQL 로 만드는 커뮤니티. 디자인이 깔끔.
KTUG - Korea TeX Users Group
KLDP 닷넷 - 소스포지와 같은 국내의 오픈소스 프로젝트 서비스 제공
Emacs-KR 홈페이지 - 최고의 에디터인 Emacs 의 사용자 모임
Emacs 설치 - 이맥스 윈도우즈용/유닉스용 설치에 관한...
정재목씨의 Emacs - 정재목씨의 Emacs 관련 페이지
NT Emacs - Windows 95/98/NT 용 Emacs 설명
Elisp Manual - Emacs Lisp Programming
Elisp intro page - Elisp Introduction & link
Elisp Reference - Elisp Reference Manual
VisEmacs - Visual Studio 내장 에디터로 Emacs 를 사용하게 해 줌
Doxygen - C++ 개발 문서화 도구
HeaderDoc - C/C++ 헤더파일을 HTML 로 문서화(펄)
CVS Home - 버젼 컨트롤 시스템
RCS - GNU Revision Control System
CS-RCS - 윈도우용 RCS. 1인용은 공짜
ViewCVS - CVS 레파지터리를 웹상에서 보기
ActiveState - ActivePerl, ActiveTCL 등등
Cetus링크 - 프로그래밍관련 방대한 링크
ZipArchive - C++ Zip 압축 라이브러리(소스동봉, zlib 사용)
zlib - zip 라이브러리
Data Compression Lib - 데이터 압축 관련 정보(인덱스, 링크, 소스)
GNU Win32 - Win32 용 각종 GNU 라이브러리 소스(libjpeg, crypt, freetype, zlib 등등)
루아 - 엘레강트하고, 심플하며, 빠르고, 가벼우며, 확장성이 용이한 스크립트 언어
공개 컴파일러들 - 각종 언어에 대한 공개 컴파일러 목록
CGShaders - C for Graphics. 사용자그룹을 가장한 공식홈
UPX - 실행 프로그램 압축 유틸리티. 여러분의 프로그램이 작아집니다.
oggvorbis - 오그 보비스 플러그인, SDK 및 소스 다운로드
ACM - The ABCs of Writing C++ Classes
Guru of the Week - Guru of the Week
STL - Standard C++ Library Tutorial 한글
STL - Standard C++ Library (SGI)
STL - Visual C++ 의 STL Sample
C++ FAQ - C++ FAQ
MSJ - Microsoft Systems Journal
VC++ STL Reference - VC++ STL Reference
Thinking in C++ - Thinking in C++ 온라인 북
코드 구루 - 코드 샘플이 많은 개발관련 사이트
OpenIL - Open Image Library
Win32ASM - Iczelion's Win32 Assembly Homepage
Priority Que & STL - by Mark Nelson (Dr. Dobb's Journal)
STLPort - 범용, 공개, 오픈소스 STL
데이타 압축 - 데이타 압축 관련 링크 모음
C++ Optimize - C++ 최적화 방법에 대한 내용
STL newbie - STL 초보자를 위한 문서
코드프로젝트 - 다양한 장르의 프로그래밍 강좌
MTL - Matrix Template Library
몇몇책들 - Effective C++, More Effective C++, Design Patterns
CPlusPlus - C++ Tutorial
AssemRef - Assembler Programmer's Reference
공짜 C/C++ 컴파일러들 - 공개 C/C++ 컴파일러들에 대한 상세한 목록
어셈러브 - 국내 어셈블리 관련 홈페이지
C++ Online Books - C++ 관련 공짜 온라인 북 링크
STL Document - RogueWave Software 의 STL 튜토리얼 및 레퍼런스
Blitz++ - 객체지향 공학용 수치계산 라이브러리(C++)
행렬 라이브러리 비교 - C/C++ 용 행렬 라이브러리 비교평가
Math Fun Facts - 수학의 재미있는 사실들
AKROWNE's Home - 수학관련 유용한 정보(책 미러 많다)
Math of DFD - Mathematics of DFD(Discrete Fourier Transform)
그리스문자 읽는법 - 그리스 문자를 읽는 방법
Numerican Recipes in C - Numerican Recipes in C 온라인 북
Mech-World - 기계공학관련(동역학,수치해석) 강의노트 및 관련정보
Forgodot - 미적분학 원격 강의
NetLib - 수학관련 문서 및 소프트웨어 모음집
MathBook - Online Books and Lecture Notes in Mathematics
물리의 이해 - 경상대학교의 물리학 노트. 플래쉬 및 자바애플릿.
수학사랑 - 수학교사들의 연구단체
대한 수학회 - 대한민국 수학 학회.
PlanetMath - Wikipedia+MathWorld+Slashdot
MathWorld - 수학 백과 사전. 방대한 자료 상세한 설명.
GIF math - 각종 수학 식에 대한 GIF 이미지 모음
Physically Based Modeling - (Online Siggraph Course notes)
Rigid-Body Link - Rigid-Body Link
RigidTutorial - Rigid Body Simulation Tutorial
ODE - Open Dynamics Engine, 공개 다관절 강체 동역학 엔진
Gene's RealtyRoad - ODE 로 만든 사람 계단에서 굴러 떨어지기
Dynamo - Dynamic Motion library
3DPhysics - 3D Physics 관련 설명
옥스포드다이나믹스 - 자동차 시뮬레이션 라이브러리. (상용)
BuggyDemo - ODE 를 사용한 3D 자동차 시뮬레이션 데모. 소스 제공
TJ의 리소스 - Thomas Jakobsen의 인터액티브 물리 시뮬레이션 관련 리소스들
하복 - 하복(havok) 물리 엔진(상용)
Math 엔진 - 물리 엔진 까르마(Karma) (상용)
GamePhysics Book - David H. Eberly 의 게임 피직스 북. 아직 출간 안됨.
SOLID - 상용 3D 충돌 라이브러리. 개인사용은 공짜.
OpCode - 삐에르 테디맨의 공개 충돌 라이브러리. RAPID나 SOLID와 비슷한.

출처 블로그 > 눈먼소리새
원본 http://blog.naver.com/blindbird/100002752311

'My work space > Java' 카테고리의 다른 글

J2EE , J2SE 한글 API [다운가능]  (0) 2008.08.20
JDK1.4 Logging API의 사용을 통한 Logging  (0) 2008.08.20
AWT/SWING 성능 비교(기본 출력 기능)  (0) 2008.08.20
소켓(Socket)  (0) 2008.08.20
Swing으로 GUI만들기  (0) 2008.08.20
2008. 8. 20. 15:00

AWT/SWING 성능 비교(기본 출력 기능)

AWT/SWING 성능 비교(기본 출력 기능)

JLab 편집실 jini (허원진)

그동안 많은 분들이 SWT/SWING 간의 성능차에 대해서 궁금해 했습니다. 이번에 제이렙에서 GUI 전반에 관한 테스트 기사를 분비했습니다.자바 어플리케이션의 경우 특성상 절대적 수치 측정이 불가능합니다. 필자는 표본공간의 원소 개수를 늘려서 표본 산출로 얻어지는 결과에 대해서 신뢰도를 높였습니다. 이번 테스트의 목적은 인터페이스 표현 성능을 비교하기 위해서 입니다. 콘트롤과는 무관함을 알립니다.

기본 그래픽 출력 비교

채워진 사각형과 텍스트 출력을 이용 SWING/SWT간의 기본 성능 테스트 해보았습니다. 코딩 방식의 차이로 테스트에 불공정이 없도록 신중히 코드를 선택했습니다. SWING/SWT 모두 GUI 제출력을 위한 메소드를 지원하나 테스트 중에 이 메소드의 요청을 모두 수용하지 않는다는 것을 알았습니다. 다시 말해서 100번 다시 그리기 요청을 한다고 100 다시 그리는 것이 아닙니다.

사용된 소스

SwingGraphicTest.java

import java.awt.Color;

import java.awt.Graphics;

import java.awt.HeadlessException;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

 

import javax.swing.JFrame;

 

/*

 * Copyright 2001 JLab wonjin.heo

 * 이 프로젝트는 JPL 라이센스를 적용합니다.

 * 자세한 내용은 www.jlab.net나 프로젝트 팩키지 안의 license.txt를 보십시요

 */

 

/**

 * SwingGraphicTest <br>

 *

 * @author jini

 */

public class SwingGraphicTest extends JFrame {

     Color color = new Color(0, 0, 0);

     Color color2 = new Color(255, 255, 255);

     static boolean first = true;

     /**

      * @throws java.awt.HeadlessException

      */

     public SwingGraphicTest() throws HeadlessException {

          super("Swing Test");

          setSize(1024, 768);

          show();

 

     }

 

     public static void main(String[] args) {

          SwingGraphicTest main = new SwingGraphicTest();

 

          main.addWindowListener(new WindowAdapter() {

              public void windowClosing(WindowEvent e) {

                   System.exit(0);

              }

          });

 

     }

 

     public void paint(Graphics g) {

          long time = System.currentTimeMillis();

          if(first)for (int i = 0; i < 12000; i++) {

              g.setColor(color);

              g.fillRect(0, 0, 1024, 768);

              g.setColor(color2);

              g.drawString("test", 10, 40);

          }

          first = false;

          System.out.print(System.currentTimeMillis() - time);

 

     }

}

 

SWTGraphicsTest.java

import org.eclipse.swt.SWT;

import org.eclipse.swt.graphics.Color;

import org.eclipse.swt.graphics.GC;

import org.eclipse.swt.widgets.Display;

import org.eclipse.swt.widgets.Event;

import org.eclipse.swt.widgets.Listener;

import org.eclipse.swt.widgets.Shell;

 

/*

 * Copyright 2001 JLab wonjin.heo

 * 이 프로젝트는 JPL 라이센스를 적용합니다.

 * 자세한 내용은 www.jlab.net나 프로젝트 팩키지 안의 license.txt를 보십시요

 */

/**

 * SWTGraphicsTest.java 2003-02-20

 *

 * @author wonjin

 */

 

public class SWTGraphicsTest {

static boolean first = true;

     public static void main(String[] args) {

          final Display display = new Display();

          final Color color = new Color(display, 0, 0, 0);

          final Color color2 = new Color(display, 255, 255, 255);

          Shell shell = new Shell(display);

          shell.setText("SWT Test");

 

          /* Paint 리스너 등록 */

          shell.addListener(SWT.Paint, new Listener() {

              public void handleEvent(Event e) {

                   GC gc = e.gc; //그래픽 컨택스트 생성

                   long time = System.currentTimeMillis();

                   if(first)for (int i = 0; i < 12000; i++) {

                        gc.setBackground(color);

                        gc.fillRectangle(0, 0, 1024, 768);

                        gc.setForeground(color2);

                        gc.drawString("test", 0, 20);

                   }

                   System.out.print(System.currentTimeMillis() - time);

                   first = false;

              }

          });

          shell.setSize(1024, 768);

          shell.open();

 

          while (!shell.isDisposed()) {

              if (!display.readAndDispatch())

                   display.sleep();

          }

          display.dispose();

     }

}

 

 

결과

결과는 테스트 소스를 10000번 테스트한 결과를 종합해서 평균을 산출했습니다. 따라서 테스트를 위해서 120000000(일억 2천만)개의 표본을 얻었습니다. 이 결과를 보면 SWT가 기본 출력에서 26%의 성능이 앞서갑니다.

SWING SWT
9547 7109

표1 기본 출력 테스트 결과

 

폰트 출력 비교

폰트를 이용한 출력의 경우 SWT, SWING간의 폰트 크기 기준의 문제로 크기가 다릅니다. SWING은 픽셀 크기, SWT는 네이티브 플랫폼에 정의된 크기(트루 폰트, 고정 폰트) 입니다. 차이로 인해서 비교의 공정을 위해서 서로 비슷한크기의 폰트로 출력했습니다.

사용된 소스

SwingFontTest.java

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.HeadlessException;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

 

import javax.swing.JFrame;

 

/*

 * Copyright 2001 JLab wonjin.heo

 * 이 프로젝트는 JPL 라이센스를 적용합니다.

 * 자세한 내용은 www.jlab.net나 프로젝트 팩키지 안의 license.txt를 보십시요

 */

 

/**

 * SwingFontTest <br>

 *

 * @author jini

 */

public class SwingFontTest extends JFrame {

     Color color = new Color(0, 0, 0);

     Color color2 = new Color(255, 255, 255);

     static boolean first = true;

     /**

      * @throws java.awt.HeadlessException

      */

     public SwingFontTest() throws HeadlessException {

          super("Swing Test");

          setSize(1024, 768);

          show();

 

     }

 

     public static void main(String[] args) {

          SwingFontTest main = new SwingFontTest();

 

          main.addWindowListener(new WindowAdapter() {

              public void windowClosing(WindowEvent e) {

                   System.exit(0);

              }

          });

 

     }

 

     public void paint(Graphics g) {

          long time = System.currentTimeMillis();

          if (first)

              for (int i = 0; i < 12000; i++) {

                   g.setFont(new Font("바탕", 0, 30));

                   g.drawString("바탕"+i, 10, 50);

 

                   g.setFont(new Font("굴림", 0, 30));

                   g.drawString("굴림"+i, 10, 80);

 

                   g.setFont(new Font("궁서", 0, 30));

                   g.drawString("궁서"+i, 10, 110);

              }

          first = false;

          System.out.println(System.currentTimeMillis() - time);

 

     }

}

 

 

SWTFontTest.java

import org.eclipse.swt.SWT;

import org.eclipse.swt.graphics.Color;

import org.eclipse.swt.graphics.Font;

import org.eclipse.swt.graphics.GC;

import org.eclipse.swt.widgets.Display;

import org.eclipse.swt.widgets.Event;

import org.eclipse.swt.widgets.Listener;

import org.eclipse.swt.widgets.Shell;

 

/*

 * Copyright 2001 JLab wonjin.heo

 * 이 프로젝트는 JPL 라이센스를 적용합니다.

 * 자세한 내용은 www.jlab.net나 프로젝트 팩키지 안의 license.txt를 보십시요

 */

/**

 * SWTFontTest.java 2003-02-20

 *

 * @author wonjin

 */

 

public class SWTFontTest {

     static boolean first = true;

     public static void main(String[] args) {

          final Display display = new Display();

          final Color color = new Color(display, 0, 0, 0);

          final Color color2 = new Color(display, 255, 255, 255);

          Shell shell = new Shell(display);

          shell.setText("SWT Test");

 

          /* Paint 리스너 등록 */

          shell.addListener(SWT.Paint, new Listener() {

              public void handleEvent(Event e) {

                   GC gc = e.gc; //그래픽 컨택스트 생성

                   long time = System.currentTimeMillis();

                   if (first)

                        for (int i = 0; i < 12000; i++) {

                             gc.setFont(new Font(e.display, "바탕", 20, SWT.NORMAL));

                             gc.drawText("바탕"+i, 10, 10,true);

 

                             gc.setFont(new Font(e.display, "굴림", 20, SWT.NORMAL));

                             gc.drawText("굴림"+i, 10, 40,true);

 

                             gc.setFont(new Font(e.display, "궁서", 20, SWT.NORMAL));

                             gc.drawText("궁서"+i, 10, 70,true);

                        }

                   System.out.println(System.currentTimeMillis() - time);

                   first = false;

              }

          });

          shell.setSize(1024, 768);

          shell.open();

 

          while (!shell.isDisposed()) {

              if (!display.readAndDispatch())

                   display.sleep();

          }

          display.dispose();

     }

}

결과

첫 번째 결과는 테스트 소스를 10000번 테스트한 결과를 종합해서 평균을 산출했습니다. 따라서 테스트를 위해서 120000000(일억 2천만)개의 표본을 얻었습니다. 두 번째 결과는 최초 출력 시에 걸린 시간입니다. SWING의 경우 최초 폰트 로딩 시간이 필요합니다. 하지만 SWT는 이와 같은 과정이 필요 없습니다. 로딩 시간을 제외 하고도 SWT가 성능이 앞서는 것을 알 수 있습니다.여러 폰트 사용시에 출력은 SWT가 28%의 성능이 앞섭니다.

SWING SWT
12547 9037
828 0

표2 폰트 출력 테스트 결과

다음 기사에서는 메모리 사용량과 컨트롤을 비교해 보겠습니다.


www.jlab.net

컨텐츠는 JPL에 의해서 보호 받습니다. 오탈 자나 건의는 이곳에 해주십시오

출처 카페 > 자바사랑 [java/swin.. / 힌둥이
원본
http://cafe.naver.com/javalove/402

'My work space > Java' 카테고리의 다른 글

JDK1.4 Logging API의 사용을 통한 Logging  (0) 2008.08.20
프로그래밍에유용한사이트  (0) 2008.08.20
소켓(Socket)  (0) 2008.08.20
Swing으로 GUI만들기  (0) 2008.08.20
AWT란  (0) 2008.08.20
2008. 8. 20. 14:58

소켓(Socket)

1.소켓(Socket)
(1) socket이란?
    정규 유닉스 파일 기술자를 이용하여 다른 프로그램과 정보를 교환하는 방법을 의미한다.
(2) 소켓의 종류
   1) 스트림소켓(Stream socket) : 양측을 신뢰성있게 연결해 주는 소켓이다. 보통 SOCK_STREAM이라
                                지칭되며 이 소켓을 통할 경우 전송순서를 정확히 유지하고 에러
                                까지 교정된다. TCP 프로토콜을 이용한다. 대표적으로 이 소켓을
                                이용하는 것이 텔넷이다. 입력한 모든 글자는 순서대로 전달이
                                되어야 하는 경우에 사용된다.
   2) 데이타그램소켓(Datagram socket) : 비연결소켓이라고도 하고 SOCK_DGRAM이라 지칭된다. 신뢰도
                                     가 떨어지며 패킷들의 순서가 바뀌어서 도착할 수 있다. UDP
                                     프로토콜을 이용한다.
   3) raw소켓(raw socket) : IP와 ICMP 프로세스의 액세스를 제공하는 소켓이다.
(3)소켓주소
   1)소켓주소 : 소켓주소(socket address)를 구성하는 정보를 포함한 데이터 구조에의 포인터를
              참조하고 소켓주소는 통신 링크의 한 종단점을 규정한다.
   2)include문장에 의해 이들 식별자와 데이터 구조가 응용프로그램에 유용해진다.
     #include<sys/types.h>
     #include<sys/sockets.h>
   3)소켓주소의 데이터구조
     ㄱ. 패밀리(family) : 사용되는 프로토콜 패밀리를 식별하는 16비트 정수값이고 AF_INET식별자
     ㄴ. 포트(port) : 프로세스에 할당된 포트 번호를 식별하는 16비트 정수값
     ㄷ. 주소(address) : 프로세스가 실행되고 있는 호스트의 이진 형식 인터넷주소를 포함하는
                       32비트 정수값
   4)소켓 주소 데이터 형 정의 및 데이터 구조 형식
     ㄱ. 무부호 정수 데이터형
        u_char : 캐릭터 형식의 무부호(unsigned)정수
        u_short : 이진 형식의 16비트 무부호정수
        u_long : 이진 형식의 32비트 무부호정수
     ㄴ. 인터넷 주소의 데이터 구조 정의
        struct in_addr {
          u_long s_addr;
        }
     ㄷ. 소켓 주소의 데이터 구조 정의
        struct sockaddr_in {
          short sin_family; /* AF_INET */
          u_short sin_port; /* 16-bit port number */
                            /* network byter order */
          struct in_addr sin_addr; /* 32-bit internet address */
                                   /* network byte ordered */
          char sin_zero[8]; /* unused */
   5)종단점 식별자
     ㄱ. 로컬 호스트 프로세스의 종단점 주소를 정의
        로컬 인터넷주소
        로컬 포트번호
     ㄴ. 원격 호스트 프로세스의 종단점 주소를 정의
        원격 인터넷 주소
        원격 포트 번호
(4) 소켓 시스템 호출
   1) accept : TCP를 이용한 연결형 응용 프로토콜에서 서버가 클라이언트로부터 연결 요청이 들어
             오기를 기다리게 하기 위하여 서버 프로세스에 의해 이용
   2) bind : 종단점 식별자(인터넷 주소 및 포트번호)를 개방 소켓의 정수 기술자와 관련짓는데
            이용
   3) close : 파일 기술자를 닫는 것과 유사한 방법으로 소켓 기술자를 닫는데 이용
   4) connect : TCP를 이용한 연결형 응용 프로토콜에서 서버와의 TCP연결을 설정하기 위해 클라이
             언트 프로세스에 의해 이용
   5) gethostbyaddr : 인터넷 주소가 주어진 호스트에 대한 정보를 얻는데 이용
   6) gethostbyname : 호스트이름이 주어진 원격 호스트의 인터넷 주소를 얻는데 이용
   7) gethostid : 로컬 호스트의 인터넷 주소를 얻는데 이용
   8) gethostname : 로컬호스트의 이름을 얻는데 이용
   9) getpeername : 원격 프로세스와 관련된 종단점 주소(인터넷 주소 및 포트번호)를 얻는데 이용
   10)getsockname : 주어진 소켓과 관련된 이름을 얻는데 이용
   11)getprotobyname : 프로토콜의 이름이 주어진 프로토콜과 관련된 정수값을 얻는데 이용
   12)getservbyname : 서비스의 이름이 널리 알려진 TCP/IP응용계층 서비스와 관련된 정수값을
                     얻는데 이용
   13)getsockpot : 소켓과 관련된 파라미터의 목록을 얻는데 이용
   14)listen : TCP를 이용한 연결형 응용 프로토콜에서 서버가 TCP연결을 설정하기 위해 클라이언트
              로부터 요청을 기꺼이 허락한다는 것을 나타내기 위하여 서버 프로세스에 의해 이용.
   15)read : 소켓으로부터 들어오는 데이터를 받아들이는데 이용
   16)ready: 연속적인 버퍼로 데이터를 받아들이는데 read의 대안으로 이용
   17)recv : 추가의 flag인자를 사용하며, 소켓으로부터 들어오는 데이터를 받아들이는데 read 대안
            으로 이용
   18)recvfrom : UDP를 이용한 비연결형 응용 프로토콜에서 데이터그램 소켓으로부터 사용자 데이터
                그램을 수신하고 송신측의 소켓 주소를 얻는데도 이용
   19)recvmsg : UDP를 이용한 비연결형 응용 프로토콜에서 데이터그램소켓으로부터 사용자의 데이터
               그램을 수신하는데 이용한다. 버퍼는 사용자 데이터그램의 헤더뿐만 아니라 사용자
               데이터그램의 데이터 부분도 포함한다.
   20)select : 프로세스가 다중 I/O이벤트중의 어떤 하나가 완료되기를 기다리게 하는데 이용한다.
   21)send : 추가의 flag인자를 사용하며, 소켓을 통해 데이터를 보내기 위해 write대안으로 이용
   22)sendmsg : 사용자 데이터그램을 데이터그램 소켓을 통해 보내는데 UDP를 이용한 비연결형 응용
               프로토콜에서 이용한다. 버퍼는 사용자 데이터그램의 헤더뿐만 아니라 사용자 데이터
               그램의 데이터부분도 포함한다.
   23)sendto : 데이터그램 소켓을 통해 데이터를 보내고, UDP를 이용한 비연결형 응용 프로토콜에서
              원격 프로세스의 소켓주소를 규정하는데 이용한다. sentto시스템 호출은 데이터가
              전달될 때 연관이 설정되게 한다.
   24)setsockopt : 소켓과 관련된 파라미터들의 값을 설정하는 데 이용
   25)shutdown : TCP를 이용한 연겷형 응용프로토콜에서 설정된 TCP연결의 한 종단을 닫는데 이용
   26)socket : 소켓 데이터구조를 초기화하고, 통신에 사용되는 전달계층의 프로토콜을 식별하며,
              후속 socket시스템 호출이 소켓을 참조하는데 사용할 수 있는 정수 기술자를 얻는
              데 이용한다.
   27)write : 소켓을 통해 데이터를 보내는데 이용한다.
   28)writev : 불연속적인 버퍼로부터 데이터를 보내기 위해 write의 대안으로 이용한다.
(5)응용프로토콜
   1)비연결형 응용프로토콜
    ㄱ. 서버시스템호출
       a. 서버는 클라언트 프로세스와 서버 프로세스간의 통신을 지원하기 위해 생성되어야 하는
         5튜플(tuple)연관에 프로토콜 정보를 채우기 위해 socket시스템호출을 수행한다. 비연결
         응용에서는 socket시스템 호출이 UDP의 이용을 지정한다.
       b. 서버는 서버의 반연관을 형성하는 정보의 나머지 부분을 채우기 위해 서버의 소켓주소를
         지정하는 bind시스템 호출을 수행한다. 서버의 반연관은 프로토콜 식별자, 서버가 동작하는
         호스트의 인터넷 주소, 서버가 이용하는 포트 번호로 구성된다.
       c. 서버는 클라이언트로부터 들어오는 데이터를 서버가 받도록 하는 recvfrom시스템호출을
         수행한다. recvfrom시스템 호출은 서버 프로세스의 서비스를 이용하고자 원하는 클라이언
         트로부터 데이터가 도착할 때까지 서버를 대기시킨다.
       d. 클라이언트로부터 사용자 데이터그램이 들어오면 서버는 필요한 절차를 수행한다. 들어
         오는 사용자 데이터그램에 포함된 헤더정보는 클라이언트 호스트에서 클라이언트 프로세스
         에 의해 이용되는 클라이언트 호스트의 인터넷 주소와 포트번호를 포함한다. 이 정보는
         클라이언트 프로세스와 서버 프로세스 사이의 5튜플 연관을 완성하는데 필요한 최종 2가지
         정보를 서버에게 제공한다.
       e. 서버는 각기 사용자 데이터그램을 클라이언트로 되돌려 보내는 하나 혹은 그 이상의
         sendto시스템 호출을 실행하는 것으로 응답한다. sendto시스템 호출은 위 단계 4에서
         결정된 클라이언트 소켓주소를 참조한다.
    ㄴ. 클라이언트 시스템호출
       a. 클라이언트는 자체의 반연관을 위한 프로토콜 정보를 채우기 위해 socket시스템호출을
         수행한다. 비연결 응용에서는 socket시스템 호출은 UDP의 이용을 지정한다.
       b. 클라이언트는 클라이언트의 반연관을 형성하는 정보의 나머지 부분을 채우기 위해 클라이
         언트의 소켓주소를 지정하는 bind시스템호출을 수행한다. 클라이언트 프로세스는 일반적
         으로 클라이언트의 인터넷주소와 사용되고 있지 않는 임시포트번호를 제공하도록 네트워킹
         소프트웨어에게 요청한다.
       c. 그리고 나서 클라이언트는 사용자의 데이터그램을 서버에 송신하기 위해 sendto시스템
         호출을 수행한다. 클라이언트는 서버의 소켓 주소를 알아야 하고, 이 소켓주소는 sendto
         시스템 호출에 참조되어야 한다.
       d. 만약 클라이언트가 서버로부터 데이터를 수신하기를 원한다면 데이터가 서버로부터 도착할
         때까지 클라이언트를 대기하게 하는 recvfrom시스템 호출을 수행한다.
       e. 클라이언트가 서버와의 대화를 끝낸 후, 이 과정을 종료한다.
(참고) 튜플(tuple)
   LISP,Python, Linda등과 같은 프로그래밍 언어에서의 튜플은 정렬된 값들의 세트이다. 각 값들의
  구분자로는 특정 언어의 규칙에 따라 다소 다르지만, 대체로 콤마가 쓰인다. 데이터 형식으로서
  사용되는 튜플은 한 프로그램에서 다른 프로그램으로 스트링 매개변수를 전달하거나 관계형 데이타
  베이스 내의 일련의 속성 값들을 표현하는 것이 보통이다. 일부 언어에서는 튜플이 괄호나 꺽쇠
  묶음 또는 다른 구분자 내에 들어있는 다른 튜플로 포개어질 수 있다. 튜플은 서로 다른 데이터
  형식을 갖는 속성들을 포함할 수 있다. 아래의 서로 다른 데이터 형식을 갖는 튜플의 예이다.
    17,*,2.29,Seven
  위의 예는 네개의 값을 가지고 있기 때문에 4-튜플이라고도 불린다. n-튜플은 확정되지 않았거나,
  값의 개수는 정의되지 않는 튜플을 말한다.
                   
   2)연결형 응용 프로토콜
    ㄱ. 서버 시스템 호출
       a. 서버는 클라이언트 프로세스와 서버 프로세스간의 통신을 지원하기 위해 생성되어야 하는
         5튜플(tuple)연관에 프로토콜 정보를 채우기 위해 socket시스템 호출을 수행한다. 연결형
        응용에서는 socket시스템호출이 TCP의 사용을 지정한다.
       b. 서버는 서버의 반연관을 형성하는 정보의 나머지 부분을 채우기 위해 서버의 소켓주소를
         지정하는 bind시스템 호출을 수행한다. 서버의 반연관은 프로토콜 식별자, 서버가 동작하는
         호스트의 인터넷 주소, 서버가 이용하는 포트번호로 구성된다.
       c. 서버는 TCP연결의 설정을 위해 클라이언트로부터의 요청을 기꺼이 허락한다는 것을 지시
         하는 listen시스템 호출을 수행한다.
       d. 서버는 TCP연결의 설정을 위한 요청이 클라이언트로부터 수신될 때까지 서버를 대기하도록
         하는 accept시스템 호출을 수행한다. 이 accept시스템 호출은 연결 설정의 요청이 실제
         수신될 때 클라이언트 프로세스의 소켓 주소로 채워진소켓주소의 데이터 구조를 참조한다.
       e. 서버는 설정된 TCP연결을 통해 클라이언트로부터 들어오는 데이타를 받아들이는 read 혹은
         recv시스템 호출을 수행한다.
       f. 서버는 필요한 절차를 수행하여 서버가 클라이언트에게 신뢰성있게 데이터를 보낼 수 있게
         해주는 write혹은 send시스템 호출을 수행한다.
    ㄴ. 클라이언트 시스템 호출
       a. 클라이언트는 자체의 반연관을 위한 프로토콜의 정보를 채우기 위해 socket시스템 호출을
         수행한다. 연결형 응용에서 socket시스템 호출은 TCP의 이용을 지정한다.
       b. 클라이언트는 서버와의 TCP연결을 설정하기 위하여 클라이언트의 소켓주소를 지정하는
         connect시스템 호출을 수행한다. 클라이언트는 connect 시스템 호출은 연결을 설정하는데
         필요한 3중 핸드쉐이크 절차를 완성하기 위해 클라이언트 프로세스와 서버 프로세스간의
         데이터가 오고 갈 수 있게 한다. 이 핸드쉐이크 과정중에 교환된 데이터는 클라이언트와
         서버의 연관을 완성하는데 필요한 정보를 포함한다. 클라이언트는 connect시스템 호출을
         수행하기 위해 서버프로세스의 소켓주소를 알아야 하므로, 일반적으로 클라이언트는 연관에
         사용될 클라이언트 자신의 인터넷주소와 사용되고 있지 않는 임시 포트 번호를 제공하도록
         통신 소프트웨어에게 요청한다.
       c. 클라이언트는 설정된 TCP연결을 통해 서버에게 데이터를 송신하기 위해 write혹은 send
         시스템 호출을 실행한다.
       d. 클라이언트는 또한 서버로부터 들어오는 데이터를 받기위해 read 혹은 recv시스템 호출을
         실행한다.
       e. 클라이언트가 서버와의 대화를 끝낸 후 이 과정을 종료한다.
(6) 소켓 프로그래밍의 구조
   1) 소켓 기술자의 데이터형 : UNIX에서 파일을 새로 열면 INT형, 즉 정수형으로 리턴한다. open문
                           이 리턴한 정수를 파일 기술자(File Descriptor)라고 하며 프로그램에서
                           open된 파일을 액세스할 때 이 파일 기술자를 사용하게 된다. 이 기술자테
                           이블에는 open되어 있는 파일의 각종 정보를 포함하고 있는 구조체를 가리
                           키고 포인터들로 구성된 테이블이다. 이런 소켓 기술자를 소켓번호라 할
                           수 있다.
   2) 구조체 : 프로그램 작성시 필요한 일종의 미리정의된 형식이다.
    * 예
     1. struct sockaddr {
           unsigned short    sa_family;      /* address family,AF_xxx */
           char              sa_data[14];    /* 14bytes of protocol address */
        };
          => sa_family는 여러가지가 될 수 있는데, 보통 "AF_INET"이 많이 사용되고, sa_data는
            목적지 주소와 포트번호를 가지게 된다.
     2. struct sockaddr_in {
           short int          sin_family;   /* address family */
           unsigned short int sin_port;     /* Port number */
           struct in_addr     sin_addr;     /* Internet address */
           unsigned char      sin_zero[8];  /* Same size as struct sockaddr */
        };
          => sin_zero배열은 sockaddr과 구조체의 크기를 맞추기 위해서 넣어진 것이므로 bzero()나
            memset()함수를 이용하여 모두 0으로 채워야 한다. 이 구조체는 sockaddr의 포인터를
            이용하여 참조될 수 있고 그 반대도 가능하다. 따라서 socket()가 struct sockaddr *를
            원하더라도 struct sockaddr_in을 사용할 수 있고 바로 참조할 수도 있다. 또한
            sin_family는 sa_family에 대응되는 것이며 물론 "AF_INET"로 지정되어야 하며,
            sin_port, sin_addr은 네트워크 바이트 순서로 되어야 한다.
   3) 사용법
     int socket(
         domain,                    // 프로토콜 체계
         type,                      // 서비스 타입
         protocol                   // 소켓에 사용될 프로토콜
        );

2.서버-클라이언트관련 시스템호출
(1)socket시스템 호출 : 소켓을 초기화하는 데 이용
   1)인자
     ㄱ. 패밀리(family) : 프로토콜 패밀리를 설명하는 정수, 주로 AF_INET 또는 PF_INET이다.
     ㄴ. 유형(type) : 초기화되는 소켓의 유형을 설명하는 정수이다. 주로 SOCK_STREAM 또는
                    SOCK_DGRAM이다.
     ㄷ. 프로토콜(protocol) : 프로토콜을 설명하는 정수, 보통 0값으로 세팅한다.
   2)결과 : 파일 기술자(file descriptor)와 유사한 정수값을 반환
   3)예
     stream_sockfd=socket(
                           AF_INET,
                           SOCK_STREAM,
                           0
                         );
     dgram_sockfd=socket(
                          AF_INET,
                          SOCK_DGREAM,
                          0
                         );
(2)bind시스템호출
   1)특징
     ㄱ. 5튜플 연관에 로컬 프로세스에 대한 종단점 식별자(인터넷주소와 포트번호)를 채운다.
     ㄴ. 이름이 없는 소켓에 이름을 지정한다.
     ㄷ. 주소를 지정하여 이 주소로 메시지가 오면 전달한다.
   2)인자
     ㄱ. 소켓 : 소켓을 식별하는 정수 기술자
     ㄴ. 로컬주소(local address) : 소켓 주소 데이트 구조의 포인터
     ㄷ. 주소길이(address length) : 로컬 주소 인자의 길이를 제공하는 정수
   3)예
     #include<sys/types.h>
     #include<sys/socket.h>

     bind (
            sockfd,
            (struct sockaddr *)&own_addr,
            sizeof(own_addr)
          );
(3)connect시스템 호출
   1)특징
     ㄱ. 연결형 응용 프로토콜의 구현시 클라이언트 프로세스에 의해 수행된다.
     ㄴ. 다른 소켓을 연결을 요청하는 역할이다.
     ㄷ. 클라이언트 프로세스와 서버 프로세스간 연관을 형성하는 5튜플을 완성하는데 필요한 모든
        정보를 운반하는 IP 데이터그램이 자동적으로 교환되는 3중 핸드쉐이크 절차를 시작한다.
   2)인자
     ㄱ. 소켓(socket) : 소켓을 식별하는 정수 기술자
     ㄴ. 원격주소(remote length) : 소켓 주소 데이터 구조의 포인터, 실제연결하고자 하는 곳의
                                 주소값이 온다.
     ㄷ. 주소길이(address length) : 원격 주소 인자의 길이를 제공하는 정수
   3)예
     connect(
             sockfd,
             (struct sockaddr *)&serv_addr,
             sizeof(serv_addr)
            );
(4)listen시스템호출
   1)특징
     ㄱ. 연결형 응용 프로토콜에서 서버 프로세스에 의해 수행한다. 즉 SOCK_STREAM과 SOCK_SEQPA
        CKET소켓에서만 사용된다.
     ㄴ. 서버 프로세스가 TCP연결 설정을 위해 클라이언트 프로세스로부터의 요청을 기꺼이 허락한
        다는 것을 알려준다. 즉 연결 요청을 받아들이겠다고 선언한다.
   2)인자
     ㄱ. 소켓(socket) : 소켓을 식별하는 정수 기술자
     ㄴ. 큐길이(queue length) : 서버가 accept시스템 호출의 수행을 기다리는 동안 연결요청을
                              시스템이 대기시킬 수 있는 지를 지시하는 정수. backlog라고 하며
                              얼마나 많은 요청을 받아들일 것인가를 지정한다.
   3)사용법
     #include<sys/types.h>
     #include<sys/socket.h>

     int listen(int s, int backlog);
   4)예
     listen(
            sockfd,
            5
            );
(5)accept시스템 호출 : 연결형 응용 프로토콜에서 서버프로세스가 클라이언트로부터 도착하는 연결
                      요청을 기다리게 하기 위해 서버프로세스에 의해 수행
   1)특징
     ㄱ. 큐에서 대기중인 연결요청에 대해서 새로운 소켓을 만든다.
     ㄴ. 서버가 여러 클라이언트에게 서비스를 하려고 소켓을 만들 때 사용한다.
     ㄷ. 큐가 비어있다면 연결요청이 올 때까지 기다린다.
     ㄹ. 새로운 소켓은 소켓기술자의 속성을 따라간다.
   2)인자
     ㄱ. 소켓(socket) : 소켓을 식별하는 정수 기술자
     ㄴ. 클라이언트 주소(client address) : 소켓주소 데이터 구조의 포인터
     ㄷ. 주소 길이(address length) : 클라이언트 주소 인자의 길이를 제공하는 정수
   3)결과 : 새로운 소켓 데이터 구조를 만들며, 소켓기술자 정수값을 반환
   4)예
     newsockfd=accept(
                      sockfd,
                      (struct sockaddr *)&cli_addr,
                      &clilen
                     );
(6)write 및 send시스템 호출 : 데이터를 원격 프로세스에 보내는데 이용
   1)인자
     ㄱ. 소켓(socket) : 소켓을 인식하는 정수 기술자
     ㄴ. 버퍼(buffer) : 보낼 데이터를 포함하는 버퍼의 포인터
     ㄷ. 길이(length) : 보낼 옥텟의 수를 지정하는 정수
     ㄹ. 플래그(flag) : send시스템 호출에만 적용
   2)결과 : write와 send 모두 실제로 전송된 옥텟수를 포함한 정수값을 반환
   3)예
     nwritten = write(
                      sockfd,
                      buffer,
                      noctets
                     );
     nwritten = send(
                     sockfd,
                     buffer,
                     noctets,
                     sendflag
                    );
(참고) 옥텟(octet)
   보통 컴퓨터에서의 옥텟은 8비트의 배열을 말한다. 따라서 옥텟 한개는 일반적으로 8비트로 구성
  되어 있는 한 바이트와 같다. 그러나 모든 컴퓨터 시스템이 8비트를 1바이트를 사용하지 않기
  때문에, 8비트 한셋을 일컫는 분명한 의미제공을 위해 옥텟이라는 용어가 사용된다.

(7)sendto시스템호출 : send와 유사, UDP를 사용한 비연결형 응용 프로토콜에서 클라이언트 프로세
                     스와 서버프로세스 모두에 의해 write또는 send대신에 사용된다.
   1)인자
     ㄱ. 소켓(socket) : 소켓을 식별하는 정수 기술자
     ㄴ. 버퍼(buffer) : 보낼 데이터를 포함하는 버퍼의 포인터
     ㄷ. 길이(length) : 보낼 옥텟의 수를 지정하는 정수
     ㄹ. 플래그(flag) : sendto동작을 위한 특수한 선택사항을 지정
     ㅁ. 원격 주소(remote address) : 소켓 주소 데이터 구조의 포인터
     ㅂ. 주소 길이(address length) : 원격 주소 인자의 길이를 제공하는 정수
   2)결과 : 실제로 전송된 옥텟수를 포함한 정수값을 반환한다.
   3)예
     nwritten = sendto(
                       sockfd,
                       buffer,
                       noctets,
                       sendflag,
                       (struct sockaddr *)&serv_addr,
                        sizeof(serv_addr)
                       );
(8)read 및 recv 시스템 호출 : 원격 프로세스로부터 들어오는 데이터를 받는데 이용
   1)인자
     ㄱ. 소켓(socket) : 소켓을 식별하는 정수 기술자
     ㄴ. 버퍼(buffer) : 수신된 데이터가 들어간 버퍼의 포인터
     ㄷ. 길이(length) : 수신 버퍼의 길이를 지정하는 정수
     ㄹ. 플래그(flag) : recv 시스템 호출에만 적용
   2)결과 : 실제로 전송된 옥텟수를 포함한 정수값을 반환
   3)예
     nread = read(
                   sockfd,
                   buffer,
                   bufferlength,
                 );
     nread = recv(
                   sockfd,
                   buffer,
                   bufferlength,
                   recvflag,
                 );
(9)recvfrom시스템 호출 : recv와 유사하며 UDP를 이용한 비연결형 응용 프로토콜에서 클라이언트
                        프로세스와 서버 프로세스에 의하여 recv 또는 read시스템 호출 대신사용
                        한다.
   1)인자
     ㄱ. 소켓(socket) : 소켓을 식별하는 정수 기술자이다.
     ㄴ. 버퍼(buffer) : 수신된 데이터가 들어갈 버퍼의 포인터이다.
     ㄷ. 길이(length) : 수신 버퍼의 길이를 지정하는 정수이다.
     ㄹ. 플래그(flag) : recvfrom동작을 위한 특수한 선택사항을 지정한다.
     ㅁ. 원격주소(remote address) : 소켓 주소 데이터 구조의 포인터
     ㅂ. 주소 길이(address length) : 원격 주소 인자의 길이를 제공하는 정수이다.
   2)결과 : 실제로 읽은 옥텟수를 포함한 정수값을 반환한다.
   3)예
      nwritten = recvfrom(
                           sockfd,
                           buffer,
                           bufferlength,
                           recvflag,
                           (struct sockaddr *)&serv_addr,
                           &length
                          );
(10)close시스템 호출 : 통신이 완료된 수 소켓을 닫기 위해 파일 기술자와 동일한 방법으로 소켓
                      기술자를 참조
   1)인자
     ㄱ. 소켓(socket) : 소켓을 식별하는 정수기술자
   2)예
     close(
            sockfd
          );

3. 소켓프로그래밍 관련 함수정리
(1) socket() : 연결의 끝점(소켓)을 생성하고 파일 기술자(File Descriptor)인 정수값을 리턴하며
               에러시에는 -1을 리턴한다. 전역변수인 errno에 에러값이 기록된다.
   1) 기본구조
     #include <sys/types.h>
     #include <sys/socket.h>

      int socket( int domain, int type, int protocol);
   2) 옵션
     -domain : 프로토콜체계를 정의한다. 소켓은 본래 TCP/IP,즉 인터넷만을 위하여 정의된 것이
             아니라, UNIX네트웍, XEROX네트웍 등에서도 사용할 수 있도록 정의되어 있다. 따라서
             가질 수 있는 값이 많다. 대표적은 것은 다음과 같다.
       PF_INET : 인터넷 프로토콜 체계 사용할 경우로 요즘은 AF_INET으로 선언해야 한다.
       PF_UNIX : UNIX방식의 프로토콜 체계를 사용할 경우
       PF_NS : XEROX 네트웍 시스템의 프로토콜을 사용할 경우
     -type : 서비스 타입을 말한다.
      SOCK_STREAM : 스트림 방식의 소켓생성
      SOCK_DGRAM : 데이타 그램 방식의 소켓생성
      SOCK_RAW : raw소켓
      SOCK_SEQPACKET : sequenced packet
      SOCK_RDM : reliably delivered message
     -protocol : 0으로 지정한다.
(2) open() : 파일을 열어서 사용하는 함수이다. 파일을 여는 데 성공하면 음수가 아닌 파일 기술자
             를 반환하며 실패하면 -1값을 반환한다.
   1)사용법
     변수 = open("파일이름",읽기타입,허가권)
   2)읽기타입(flags)
     ㄱ. O_RDONLY : 읽기 전용 액세스를 위해 파일을 연다.
     ㄴ. O_WRONLY : 쓰기 전용 액세스를 위해 파일을 연다.
     ㄷ. O_RDWR   : 읽기와 쓰기 액세스를 위해 파일을 연다.
     ㄹ. 0_CREAT  : 파일이 존재하지 않으면 생성한다.
     ㅁ. O_EXCL   : 파일이 이미 존재하면 실패한다.
     ㅂ. O_NOCTTY : 열고자 하는 tty와 프로세스가 제어하는 tty를 가지지 않았다면 즉 같은 제어권
                   이 제어하는 tty가 되지 못한다.
     ㅅ. O_TRUNC  : 파일이 존재하면 길이를 0으로 줄인다.
     ㅇ. O_APPEND : 현재 파일의 포인터를 파일의 마지막에 위치하게 한다.
     ㅈ. O_NONBLOCK : 프로세스가 지연없이 완료되지 않으면 완료되기 전에 반환한다.
     ㅊ. O_NODELAY  : 0_NONBLOCK과 같다.
     ㅋ. O_SYNC     : 기록이 완료되는 경우 반환
     ㅍ. O_DIRECTORY : 디렉토리가 아니면 open함수는 실패된다.
     ㅌ. O_LARGEFILE : 32bit시스템의 매우 큰파일 형태
   3) 사용예
      fd = open("/etc/passwd",O_RDONLY)
      => /etc/passwd파일을 읽기전용으로 연다.
(3) close() : 소켓을 닫을 때 사용한다. 정규 파일 기술자에 관한 close()를 사용하면 된다.
   1) 사용법
     #include<unistd.h>
     int close(int sockfd);
   2)특징
     ㄱ. 신뢰성 기반의 TCP를 이용한 연결에서 사용된다.
     ㄴ. 데이터 송수신 작업이 모두 끝난 소켓은 파일에서와 마찬가지로 close()시스템 호출을 이용
        하여 닫기 작업을 수행한다.
     ㄷ. 소켓을 닫을 때는 언제나 양 종단에서 소켓을 닫아야 한다.
   3) 사용예
     close(sockfd);
      => 더 이상의 입출력은 불가능 해지며 누구든지 원격지에서 이 소켓에 읽고 쓰려고 할 경우에는
        에러가 발생한다.
(예제1) 리턴되는 파일 기술자(file descriptor)출력해보기 (open_socket.c)
  1)설명 : /etc/passwd와 /etc/hosts라는 파일을 열어서 리턴되는 파일 기술자값을 십진수형태로
         출력하고 tcp소켓과 udp소켓을 열어 리턴되는 파일기술자값도 알아보도록 한다.
  2)프로그램
   #include<stdio.h>
   #include<sys/types.h>
   #include<sys/stat.h>
   #include<fcntl.h>
   #include<sys/socket.h>
   int main()
   {
     int fd1,fd2,sd1,sd2;
     fd1=open("/etc/passwd",O_RDONLY,0);
     printf("/etc/passwd's file descriptor=%d\n",fd1);
     sd1=socket(AF_INET,SOCK_STREAM,0);
     printf("stream socket desciptor=%d\n",sd1);
     sd2=socket(AF_INET,SOCK_DGRAM,0);
     printf("datagram socket descriptor=%d\n",sd2);
     fd2=open("/etc/hosts",O_RDONLY,0);
     printf("/etc/hosts's file descriptor=%d\n",fd2);
     close(fd2);
     close(fd1);
     close(sd2);
     close(sd1);
   }
  3)사용예
   [posein@www posein]$ ./a.out
   /etc/passwd's file descriptor=3
   stream socket desciptor=4
   datagram socket descriptor=5
   /etc/hosts's file descriptor=6
(4)fork() : 프로세스를 복사하는 함수이다. 이 함수를 이용하면 부모 프로세스를 복제한 자식 프로
            세스를 생성한다. 즉, 자식 프로세스는 부모 프로세스의 코드, 자료, 스택, 열린 파일
            기술자, 시그널 테이블의 복사본을 상속받는다.
   1) 사용예
     pid=fork()
      => 현재 프로세스를 복사하여 pid에 값을 넘겨준다. 만약 fork()가 성공하면 부모프로세스에게
        는 자식의 PID를 반환하며, 자식 프로세스에게는 0을 반환한다. 만약 실패한다면 부모프로
        세스에게 -1을 반환하며, 자식 프로세스는 생성되지 않는다.
(5) getpid() : 현재 프로세스의 PID를 얻는다.
(6) getppid() : 부모 프로세스의 PID를 얻는다.
(예제2) 현재 프로세스값 출력하기1
  1)설명 : 현재 실행되는 프로세스아이디값을 출력하고 fork()수행후 프로세스 아이디값을 출력
  2)프로그램
   #include<stdio.h>
   main()
   {
     printf("Current process[%d]\n",getpid());
     fork();
     printf("New Current process[%d]\n",getpid());
   }
(예제3) 현재 프로세스값 출력하기2
  1) 설명 : 현재 실행되는 프로세스아이디값을 출력하고 복제되는 자식프로세스의 아이디값도
          출력해본다.
  2) 프로그램
   #include<stdio.h>
   main()
   {
     int pid;
     printf("I'm original process[%d]\n",getpid());
     pid=fork();
     printf("I'm parent of client process[%d]\n",getpid());
     if(pid==0)            //비교해서 0이면 자식프로세스이다.
     {
        printf("I'm child process[%d]\n",getpid());
     }
     else                 //그렇지 않으면 부모프로세스이다.
     {
        printf("I'm parent process[%d]\n",getpid());
     }
     printf("[%d]process terminate\n",getpid());
   }
  3) 사용예
    [posein@www posein]$ ./a.out
    I'm original process[10057]            // 원래의 프로세스아이디를 출력한다.
    I'm parent of client process[10057]    // 복제를 했으므로 getpid()함수를 사용하면 두개의
    I'm parent of client process[10058]    //프로세스값을 출력해낸다.
    I'm child process[10058]
    [10058]process terminate
    I'm parent process[10057]
    [10057]process terminate
(예제4) 현재 프로세스값 출력하기3
  1)설명 : getpid(),getppid()함수를 이용한 간단한 출력
  2)프로그램
   #include<stdio.h>
   main()
   {
    int pid;
    printf("I'm the original process with PID %d and PPID %d.\n",getpid(),getppid());
   }
  3)사용예
   [posein@www posein]$ ./a.out
   I'm the original process with PID 10381 and PPID 1172.
(예제5) 현재 프로세스값 출력하기4
  1)설명 : fork(),getpid(),getppid()함수를 이용한 출력
  2)프로그램
   #include<stdio.h>
   main()
   {
    int pid;
    printf("I'm the original process with PID %d and PPID %d.\n",getpid(),getppid());
    pid=fork();         // 프로세스 복제
    if (pid!=0)         // pid가 0이 아니므로 부모프로세스를 나타냄
   {
    printf("I'm the parent process with PID %d and PPID %d.\n",getpid(),getppid());
    printf("My child's PID %d\n",pid);
   }
    else               // pid가 0인 경우이므로 자식 프로세스
    {
      printf("I'm the child process with PID %d and PPID %d,\n",getpid(),getppid());
    }
    printf("PID %d terminates.\n",getpid());         // 양 프로세스 모두 이를 실행
   }
  3)사용예
   [posein@www posein]$ ./a.out
   I'm the original process with PID 10405 and PPID 1172.
   I'm the parent process with PID 10405 and PPID 1172.
   My child's PID 10406
   I'm the child process with PID 10406 and PPID 10405,
   PID 10406 terminates.
   PID 10405 terminates.
(7) 순서바꾸기 관련 함수 : 이기종컴퓨터 및 네트워크 프로토콜간에 바이트순서를 변환시켜 준다.
   1) 바이트순서 : 바이트 순서에는 호스트 바이트순서와 네트웍 바이트순서가 있다.
    ㄱ. 호스트 바이트순서 : 말 그대로 컴퓨터가 내부 메모리에 숫자를 저장하는 순서를 말한다.
                         이것은 컴퓨터 CPU종류에 따라 다르다 .예를 들면 두 바이트로 구성된
                         십진수 50146의 경우 hexa로 0xC3E2이며 이것을 일반PC계열, 즉 80x86
                         계열의 CPU에서는 E2,C3의 순서(즉 하위 바이트부터)메모리에 저장된다.
                         그러나 MC68000계열의 CPU에서는 C3,E2의 순서로 메로리에 저장된다.
    ㄴ. 네트웍 바이트순서 : 네트웍에서 바이트 단위로 데이타가 전달되는 순서를 말한다. 2바이트
                         의 수 0xC3E2인 경우 C3,E2의 순서로 즉 상위바이트부터 전송된다. 즉
                         80x86계열의 CPU가 사용하는 호스트 바이트순서는 네트웍바이트순서와
                         다르다. 따라서, 80x86계열의 컴퓨터에서 네트웍을 통하여 전송한 데이터
                         를 68000계열의 컴퓨터가 수신하면 바이트 순서가 바뀌게 된다.
   2) 순서바꾸기 함수 : 컴퓨터 내부에서 만들어진 호스트 바이트 순서의 데이터를 네트웍으로 전송
                     하기 전에 htons() (host to network short의 약자)함수를 사용하여 자신에게
                     맞는 호스트 바이트순서로 항상 바꾸어야 한다. 반대로 네트웍에서 수신한
                     데이타는 ntohs()함수를 사용하여 자신의 호스트 바이트순서로 바꿔야 한다.
                     즉 네트웍 바이트순서를 지켜 데이터를 전송함으로써 수신한 데이터가 어떤
                     종류의 컴퓨터에서 만들어진 것인지를 알 필요가 없도록 하는 것이다. 참고로
                     MC68000계열의 CPU에서는 호스트 바이트순서와 네트웍바이트순서가 같은 것을
                     알 수 있는데 호스트에서의 htons()와 ntohs()함수는 아무 일도 하지 않는다.
   3) 함수의 종류 : Short은 2바이트체계이고 Long 4바이트체계이다.
     htons() : Host to Network Short
     htonl() : Host to Network Long
     ntohs() : Network to Host Short
     ntohl() : Network to Host Long
(8) getservbyname() : 포트주소를 구하는 함수이다.
   1) 사용법
      변수=getservbyname(서비스,연결형태)
   2) 사용예
      pservent=getservbyname("telnet","tcp")
   3) 관련구조
     <netdb.h>
     struct servent {
       char    *s_name;
       char    **s_aliases;           /* alias list*/
       int     s_port;                /* port # */
       char    *s_proto;              /* protocol to use */
      };
(예제6) 특정서비스의 포트번호 출력하기
  1)설명 :  순서바꾸기함수와 getservbyname()함수이용한 간단한 예제
  2)프로그램
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netdb.h>
    main()
    {
     struct servent *pmyservent;
     pmyservent=getservbyname("ftp","tcp");
     if(pmyservent==NULL)
     {
      printf("서비스정보를 얻을 수 없음.\n");
     }
      printf("port number of with ntohs():%d\n",ntohs(pmyservent->s_port));
      printf("port number of without ntohs():%d\n",(pmyservent->s_port));
    }
  3)사용예
    [posein@www posein]$ ./a.out
    port number of with ntohs():21
    port number of without ntohs():5376
(9) gethostbyname() : 도메인 네임으로부터 IP주소를 알기위해 사용하는 함수이다.
   1) 사용법
     gethostbyname(변수);
   2) 관련구조
      <netdb.h>
      struct hostent {
        char    *h_name;              /* alias list */
        char    **h_aliases;          /* address type */
        int     h_addrtype;           /* length of address */
        int     h_length;             /* list of address */
        char    **h_addr_list[0]      /* for backward compatiblity */
      };
(예제7) 도메인 주소를 IP로 변환하기
  1)설명 : 32비트의 IP주소는 편의에 따라 www.yahoo.com과 같은 도메인 네임, 192.168.0.1과 같은
          Dotted decimal 표시법, 이진수 IP표기법 등으로 바꾸어 널리 사용하고 있다. 여기서는
          hostent구조체와 gethostbyname()함수를 이용하여 도메인네임을 Dotted decimal표기법으로
          변환하여 표시한다.
  2)프로그램
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>

    main(int argc, char *argv[])
    {
        struct hostent *myhost;
        struct in_addr myinaddr;       /* IP주소를 저장할 구조체 */
        int i;

        if (argc < 2)
        {
                printf("사용법 : %s host_name(도메인 네임)\n",argv[0]);
                exit(1);
        }

        myhost=gethostbyname(argv[1]);        /* hostent 구하기 */
        if(myhost==0)
        {
                printf("error occurs...at 'gethostbyname'.\n\n\n");
                exit(1);
        }

        printf("official host name : \t\t%s\n",myhost->h_name);  /* 호스트 이름 출력 */

        i=0;                                     /* 호스트 별명 출력 */
        while(myhost->h_aliases[i]!=NULL)
        {
                printf("aliases name : \t\t%s\n",myhost->h_aliases[i]);
                i++;
        }

        printf("host address type : \t\t%d\n",myhost->h_addrtype);  /* 호스트 주소 체계 출력*/
        printf("length of host address : \t%d\n",myhost->h_length);  /*호스트 주소길이출력*/
                                                                     
        i=0;                         /* 호스트 주소를 dotted decimail형태로 출력 */
        while(myhost->h_addr_list[i] !=NULL)
        {
                myinaddr.s_addr = *((u_long *)(myhost->h_addr_list[i]));
                printf("address for host:\t\t%s\n",inet_ntoa(myinaddr));
                i++;
        }
    }
  3)사용예
    [posein@www posein]$ ./a.out yahoo.co.kr
    official host name :            yahoo.co.kr
    host address type :             2
    length of host address :        4
    address for host:               211.32.119.151
(예제8) 주소변환 예제 프로그램
  1)설명 : 호스트의 도메인 네임과 Dotted decimal주소 두가지 방식으로 입력받아 다음과 같이
          4가지 형태로 출력한다.
    ㄱ. 입력된 목적지 도메인 네임으로부터 IP주소를 찾아 화면에 출력(gethostbyname()이용)
    ㄴ. 입력받은 IP주소를 Dotted deciaml주소로 변경하여 출력 (inet_ntoa()이용)
    ㄷ. 입력된 Dotted Decimal주소로부터 IP주소를 찾아 화면에 출력 (gethostbyaddr()이용)
    ㄹ. 세번째구한 hostent구조체내에 있는 목적지 도메인 네임을 화면에 출력
  2)프로그램
    #include<netdb.h>
    #include<stdio.h>
    #include<string.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>
    int main(int argc, char *argv[])
    {
      struct hostent *ptr_he;     /* 호스트의 정보를 저장하는 구조체 */
      struct in_addr in;          /* 인터넷 주소를 저장하는 구조체 */
      char *hname;                /* 호스트 이름 */
      char *haddr;                /* Dotted decimal IP 문자열 */
      if(argc!=3)
      {
       printf("usage:hostname ip_address\n",argv[0]);
       return -1;
      }
     hname=argv[1];
     haddr=argv[2];

     if((ptr_he=gethostbyname(hname)))  /* 호스트 도메인네임으로부터 호스트정보구하기 */
      {
        memcpy(&in.s_addr,ptr_he->h_addr_list[0],sizeof(in.s_addr));
        printf("%s's binary ip address(hexa) : 0x%x\n",hname,in.s_addr);
        printf("%s's dotted decimal IP address : %s\n",hname,inet_ntoa(in));
            /* IP주소를 Dotted decimal형태의 IP로 변환 */
      }
     else
      {
       printf("gethostbyname error.\n");
      }

     if((in.s_addr=inet_addr(haddr))>0) /* 입력된 Dotted decimal IP주소에서 bianry IP구하기 */
      {
        ptr_he=gethostbyaddr((char *)&(in.s_addr),sizeof(in.s_addr),AF_INET);
        printf("%s's binary IP address(hexa) : 0x%x\n",haddr,in.s_addr);
        printf("%s's hostname : %s\n",haddr,ptr_he->h_name);
      }
     else
      {
        printf("inet_addr error.\n");
      }
    }
  3)사용예
    [posein@www posein]$ ./a.out yahoo.com 203.247.40.252
    yahoo.com's binary ip address(hexa) : 0xf56c73d8
    yahoo.com's dotted decimal IP address : 216.115.108.245
    203.247.40.252's binary IP address(hexa) : 0xfc28f7cb
    203.247.40.252's hostname : mybestone.com
(10) perror() : 시스템 호출은 어떤 경우에 실패할 수가 있다. 예를 들면 존재하지 않는 파일을
                읽기 위해 open()으로 파일을 열려고 한다면 그 호출은 실패하고 시스템 호출은
                에러가 발생하면 -1값을 반환한다. 그러나 이 값은 에러가 발생한 이유를 충분히
                설명하지 못한다. 체계적인 에러 호출을 위해 사용되는 함수가 perror()함수이다.
                즉 시스템 호출 에러를 서술하는 서브루틴(Subroutine)이다. 이 함수는 에러 호출
                관련변수인 errno와 같이 사용하여 에러 처리한다.
   1)에러호출관련변수(errno)
     가장 최근의 시스템 호출 에러의 숫자코드를 저장하고 있는 전역변수이다. 모든 프로세스는 이
    전역변수를 포함하고 있다. "errno"는 프로세스가 생성될 때 처음에는 0으로 설정된다. 그 후
    시스템 호출 에러가 발생하면, errno는 그 원인과 관련된 숫자 코드로 설정된다. 가령 존재하지
    않는 파일을 읽으려고 열면 "errno"는 2로 설정된다.
   2)사용법
     perror("문자열");
      => 에러를 표시하기 위한 문자열을 넣는다.
   3)사용예
     ㄱ.프로그램
       #include<stdio.h>
       #include<sys/file.h>
       #include<errno.h>
       main()
       {
         int fd;
         fd=open("nonexist.txt",O_RDONLY);  /* 에러를 발생을 위해 존재하지 않는 파일 열기 */
         if (fd==-1)                   /* open()함수가 에러이므로 -1값을 리턴함으로 수행 */
         {
           printf("errno=%d\n",errno);
           perror("main");
         }
         fd=open("/",O_WRONLY);      /* 다른 에러 발생 유도 */
         if(fd==-1)                  /* 역시 open()함수가 -1값을 리턴함으로 수행 */
         {
           printf("errno=%d\n",errno);
           perror("main");
         }
         fd=open("nonexist.txt",O_RDONLY|O_CREAT, 0644);  /* 시스템 호출을 성공적으로 수행 */
          /* nonexist.txt라는 파일을 읽기전용으로 열고 만약 없으면 생성한다. 허가권값은 644 */
         printf("errno=%d\n",errno);
         perror("main");
         errno=0;                           /* 인위적으로 변수 error를 0으로 설정 */
         perror("main");
       }
     ㄴ.실행
       [posein@www posein]$ ./a.out            // 프로그램 실행
       errno=2
       main: No such file or directory
       errno=21                                // 성공적 호출 뒤에도 그 값이 유지
       main: Is a directory
       errno=21
       main: Is a directory
       main: Success
(예제9) 간단한 스트림 서버
  1)설명 : 이 서버가 하는 일은 오직 스트림 접속을 하게 되는 모든 클라이언트에게 "Hello,World!"
          라는 문구열을 출력해준다.
  2)프로그램(server.c)
    #include<stdio.h>
    #include<stdlib.h>
    #include<errno.h>
    #include<string.h>
    #include<sys/types.h>
    #include<netinet/in.h>
    #include<sys/socket.h>
    #include<sys/wait.h>

    #define MYPORT 3490          /* 접속에 사용할 포트를 정의 */
    #define BACKLOG 10           /* 접속을 위해 설정되는 컨넥션의 수 정의 */

    main()
    {
      int sockfd, new_fd;
      struct sockaddr_in my_addr;
      struct sockaddr_in their_addr;
      int sin_size;

      if ((sockfd=socket(AF_INET, SOCK_STREAM,0))==-1)
       // socket()함수는 파일기술자(File Descriptor)를 리턴하며 에러시에는 -1을 리턴한다. //
       //즉, 여기서는 에러인 경우에는 socket에서 에러가 발생했다는 메시지를 표시한다. //
      {
        perror("socket");
        exit(1);
      }

      my_addr.sin_family=AF_INET; /* 보통 어떠한 프로토콜을 사용할 지를 정한다.*/
      my_addr.sin_port=htons(MYPORT); /* 사용하는 포트를 네트워크 바이트순서함수로 값 변환 */
      my_addr.sin_addr.s_addr=INADDR_ANY; /* Internet address, 즉 IP값을 저장한다. */
      bzero(&(my_addr.sin_zero),8);

      if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))==-1)
      {
        perror("bind");
        exit(1);
      }

      if (listen(sockfd, BACKLOG)==-1)
      {
        perror("listen");
        exit(1);
      }

      while(1)
      {
        sin_size=sizeof(struct sockaddr_in);
        if ((new_fd=accept(sockfd,(struct sockaddr *)&their_addr, &sin_size))==-1)
        {
          perror("accept");
          continue;
        }
        printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr));

        if (!fork())
        {
          if (send(new_fd, "Hello, world!\n",14,0)==-1)
          perror("send");
          close(new_fd);
          exit(0);
        }
        close(new_fd);

        while(waitpid(-1,NULL,WNOHANG)>0);
      }
    }
   3)사용예
     ㄱ.서버프로그램실행시키기
       [posein@www posein]$ ./a.out                    // 실행시킴
       server: got connection from 210.123.193.194     // 접속시 접속한 곳을 정보를 출력
       server: got connection from 203.247.40.252     
     ㄴ.외부클라이언트에서 접속하기
       [posein@www posein]$ telnet 203.247.40.252 3490
       Trying 203.247.40.252...
       Connected to mybestone.com (203.247.40.252).
       Escape character is '^]'.
       Hello, world!                                   // 문구열이 출력되었다.
       Connection closed by foreign host.
(예제10)간단한 스트림 클라이언트
  1)설명 : 서버스트림이 작동할 경우 해당서버를 명기해주면 해당서버로부터 문자열을 입력받아 출력
         한다.
  2)프로그램(client.c)
    #include<stdio.h>
    #include<stdlib.h>
    #include<errno.h>
    #include<netdb.h>
    #include<sys/types.h>
    #include<netinet/in.h>
    #include<sys/socket.h>

    #define PORT 3490
    #define MAXDATASIZE 100

    int main(int argc, char *argv[])
    {
      int sockfd, numbytes;
      char buf[MAXDATASIZE];
      struct hostent *he;
      struct sockaddr_in their_addr;

      if ( argc !=2)
      {
        fprintf(stderr, "usage: client hostname\n");
        exit(1);
      }

      if ((he=gethostbyname(argv[1])) == NULL)
      {
        herror("gethostbyname");
        exit(1);
      }

      if ((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == -1)
      {
        perror("socket");
        exit(1);
      }

      their_addr.sin_family=AF_INET;
      their_addr.sin_port=htons(PORT);
      their_addr.sin_addr=*((struct in_addr *)he->h_addr);
      bzero(&(their_addr.sin_zero),8);

      if(connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) ==-1)
      {
        perror("connect");
        exit(1);
      }

      if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) ==-1)
      {
        perror("recv");
        exit(1);
      }

      buf[numbytes] ='\0';
      printf("Received: %s",buf);
      close(sockfd);
      return 0;
    }
  3)사용예
    [posein@www posein]$ ./client localhost
    Received: Hello, world!
(11) sockpair() : pipe()시스템 호출과 유사하게 동작하는데, 이 시스템콜은 2개의 소켓설명자를
                  반환한다. 2개의 소켓설명자는 파이프에서와 같이 통신 통로의 양극단을 나타내지
                  만 파이프처럼 단방향이 아니고 양방향이다. 소켓설명자 0번과 1번에서 각각 데이
                  터를 읽고 쓸 수 있다.
   1)사용법
     #include<sys/type.h>
     #include<sys/socket.h>

     int socketpair(int domain, int type, int protocol, int sockfd[2]);
   2)사용예
     int rc, sockfd[2]

     rc=socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd);
(12) system() : 시스템 내부의 명령어를 실행시킬 때 사용한다.
   1)사용법
     system("command");
   2)사용예
     system("ping -c 5 localhost");
(예제11) 프로세스 상태 출력하기
  1) 설명 : socketpair()를 사용하여 소켓기술자값도 출력하고 프로세스상태도 출력한다.
  2) 프로그램 (sockpair.c)
    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<errno.h>
    #include<string.h>
    #include<sys/types.h>
    #include<sys/socket.h>

    int main(int argc, char **argv)
   {
      int z;
      int s[2];

      z=socketpair(AF_LOCAL, SOCK_STREAM,0,s);

     if (z==-1)
     {
       fprintf(stderr,"%s: socketpair(AF_LOCAL,SOCK_STREAM,0)\n", strerror(errno));
       return 1;
     }

     printf("s[0]=%d;\n",s[0]);
     printf("s[1]=%d;\n",s[1]);

     system("netstat --unix -p");
     return 0;
     }
  3)사용예
    [posein@www posein]$ ./a.out
    s[0]=3;                       // 소켓기술자1의 값을 출력 (위 예제1 참조)
    s[1]=4;                       // 소켓기술자2의 값을 출력
    (Not all processes could be identified, non-owned process info
     will not be shown, you would have to be root to see it all.)
    Active UNIX domain sockets (w/o servers)
    Proto RefCnt Flags       Type       State         I-Node PID/Program name    Path
    unix  16     [ ]         DGRAM                    892    -                   /dev/log
    unix  3      [ ]         STREAM     CONNECTED     87133  8540/a.out
    unix  3      [ ]         STREAM     CONNECTED     87132  8540/a.out
    unix  2      [ ]         DGRAM                    84704  -
    unix  2      [ ]         DGRAM                    84642  -
    unix  2      [ ]         DGRAM                    43272  -
    unix  2      [ ]         DGRAM                    14241  -
    unix  2      [ ]         DGRAM                    12194  -
    unix  2      [ ]         DGRAM                    4606   -
    unix  2      [ ]         DGRAM                    4016   -
    unix  2      [ ]         DGRAM                    3962   -
    unix  2      [ ]         DGRAM                    3925   -
    unix  2      [ ]         DGRAM                    1292   -
    unix  2      [ ]         DGRAM                    1105   -
    unix  2      [ ]         DGRAM                    1072   -
    unix  2      [ ]         DGRAM                    940    -
    unix  2      [ ]         DGRAM                    904    -
    unix  2      [ ]         STREAM     CONNECTED     540    -

(13) shutdown() : close()보다 좀더 선택적인 제어를 하면서 연결을 끊을 수 있다. 즉 특정방향으
                 로의 통신만을 끊을 수 있게 된다.
   1)사용법
     #include<sys/socket.h>

     int shutdown(int sockfd, int how);
      => sockfd는 소켓 기술자이며, how는 다음과 같다.
        0(SHUT_RD) : 더 이상의 수신금지
        1(SHUT_WR) : 더 이상의 송신금지
        2(SHUT_RDWR) : 더 이상의 송수신금지 => close()와 같은 경우에 해당
   2) 특징 : 성공하면 소켓기술자값을 리턴하고 실패하면 -1값을 리턴한다.
   2) 참고 : 연결도 되지않은 데이터그램 소켓에 shutdown()을 사용한다면 단지 send(), recv()를
           사용하지 못하게만 만든다. connect()를 사용한 경우에만 이렇게 사용할 수 있다.
(예제12) PID 출력 및 버퍼값 출력하기
  1) 설명 : socketpair()함수를 사용하여 시간을 출력하고 getppid()를 이용하여 프로세스아이디를
          출력한다.
  2)프로그램(sockpair2.c)
    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<errno.h>
    #include<string.h>
    #include<time.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<sys/wait.h>

    #ifndef SHUT_WR
    #define SHUT_RD   0
    #define SHUT_WR   1
    #define SHUT_RDWR 2
    #endif

    int main(int argc, char **argv)
    {
      int z;
      int s[2];
      char *msgp;
      int mlen;
      char buf[80];
      pid_t chpid;
      z=socketpair(AF_LOCAL, SOCK_STREAM, 0, s);

      if ( z==-1)
      {
        fprintf(stderr,"%s:socketpair(2)\n",strerror(errno));
        exit(1);
      }

      if ((chpid=fork())==(pid_t)-1)
      {
        fprintf(stderr,"%s: fork(2)\n",strerror(errno));
        exit(1);
      }
      else if (chpid==0)
      {
        char rxbuf[80];
        printf("Parent PID is %ld\n",(long)getppid());
        close(s[0]);
        s[0]=-1;
        msgp = "%A %d-%b-%Y %1:%M %p";
        mlen =strlen(msgp);

        printf("Child sending request '%s'\n",msgp);
        fflush(stdout);

        z=write(s[1],msgp,mlen);

        if (z<0)
        {
          fprintf(stderr,"%s:write(2)\n",strerror(errno));
          exit(1);
        }

        if (shutdown(s[1],SHUT_WR)==-1)
        {
          fprintf(stderr,"%s:shutdown(2)\n",strerror(errno));
          exit(1);
        }

        z=read(s[1],rxbuf,sizeof rxbuf);
        if ( z<0 )
        {
          fprintf(stderr,"%s:read(2)\n",strerror(errno));
          exit(1);
        }
        rxbuf[z]=0;

        printf("Server returned '%s'\n",rxbuf);
        fflush(stdout);
        close(s[1]);
      }
      else
      {
        int status;
        char txbuf[80];
        time_t td;

        printf("Child PID is %ld\n",(long)chpid);
        fflush(stdout);

        close(s[1]);
        s[1]=-1;

        z=read(s[0],buf,sizeof buf);

        if ( z< 0)
        {
          fprintf(stderr,"%s:read(2)\n", strerror(errno));
          exit(1);
        }

        buf[z]=0;
        time(&td);

        strftime(txbuf,sizeof txbuf, buf, localtime(&td));
        z=write(s[0],txbuf,strlen(txbuf));

        if ( z<0 )
        {
          fprintf(stderr,"%s:write(2)\n",strerror(errno));
          exit(1);
        }
        close(s[0]);
        waitpid(chpid,&status,0);
       }
       return 0;
    }
  3)사용예
    [posein@www posein]$ ./a.out
    Child PID is 8714
    Parent PID is 8713
    Child sending request '%A %d-%b-%Y %1:%M %p'
    Server returned 'Wednesday 02-Jan-2002 %1:49 PM'

4. 도메인(Domain)과 주소군(Address Family)
(1) UNIX도메인형식
   1)사용법
     #include<sys/un.h>
     struct sockaddr_un {
        sa_family_t   sun_family;                    /* Address Family */
        char          sun_path[108];                 /* Pathname */
     }
      => sun_family : AF_UNIX(AF_LOCAL)
         sun_path : UNIX경로명('\0'바이트는 없어도 된다.)
         (참고) 전통적인 주소와 추상적인 주소란 말이 있는데 추상적인 주소는 첫번째 바이트가
              '\0'이다.
   2)설명
     ㄱ. 이 주소형식은 같은 호스트 상의 두 프로세스가 통신하기 위해 생성한 소켓에 의해 이용
        된다. 예를 들면 지역프린터로 파일을 출력하려고 하는 경우에 호스트의 스풀링서비스를
        받기위해 이 지역 소켓을 사용한다.
     ㄴ. 전통적인 주소는 sun_path에 기록된 경로명은 파일시스템 내의 실제 파일을 가리켜야 한다.
       물론 이 주소를 사용하기 위해서는 프로세스 경로에 나타난 모든 디렉토리와 소켓파일이 생성
       될 디렉토리에 필요한 접근권한이 있어야 한다.
     ㄷ. 전통적인 주소의 단점으로는 사용한 소켓 파일이 지워지지 않았다면 같은이름으로 bind()
        시스템 호출을 호출하면 에러가 반환된다는 점이다. 리눅스커널 2.2에서는 추상적인 주소를
        갖는 소켓을 생성할 수 있다. 즉 경로명을 나타내는 문자열의 첫번째 바이트를 '\0'문자로
        만들면 파일 시스템내에 소켓 파일이 생성되지 않는다.
(예제13) sockaddr_un형식의 주소를 소켓이 가지도록 설정하기
  1)설명 : sockaddr_un형식의 주소를 소켓이 갖도록 설정하고 netstat명령을 실행시켜 확인해 본다.
  2)프로그램 (unixsock.c)
    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<errno.h>
    #include<string.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<sys/socket.h>
    #include<sys/un.h>

    static void
    bail(const char *on_what)
    {
      perror("on_what");
      exit(1);
    }

    int main(int argc, char **argv, char **envp)
    {
      int z;
      int sck_unix;
      struct sockaddr_un adr_unix;
      int len_unix;
      const char pth_unix[]="/tmp/my_sock";
      sck_unix=socket(AF_UNIX,SOCK_STREAM,0);
      if ( sck_unix==-1)
       bail("socket()");
      unlink(pth_unix);

      memset(&adr_unix,0,sizeof adr_unix);
      adr_unix.sun_family=AF_UNIX;

      strncpy(adr_unix.sun_path,pth_unix,sizeof adr_unix.sun_path-1)
      [sizeof adr_unix.sun_path-1]=0;

      len_unix=SUN_LEN(&adr_unix);

      z=bind(sck_unix,(struct sockaddr *)&adr_unix,len_unix);

      if ( z==-1)
        bail("bind()");
      system("netstat -pa --unix 2>/dev/null |" "sed -n '/^Active UNIX/,/^proto/p;""/af_unix/p'");
      close(sck_unix);
      unlink(pth_unix);

      return 0;
    }
  3)사용예
    [posein@www posein]$ ./a.out
    Active UNIX domain sockets (servers and established)
    Proto RefCnt Flags       Type       State         I-Node PID/Program name    Path
    unix  2      [ ACC ]     STREAM     LISTENING     4039   -                   /tmp/mysql.so
    ck
    unix  2      [ ]         STREAM                   88376  8838/a.out          /tmp/my_sock
    unix  2      [ ACC ]     STREAM     LISTENING     3959   -                   /tmp/.font-un
    ix/fs7100
    unix  16     [ ]         DGRAM                    892    -                   /dev/log
    unix  2      [ ACC ]     STREAM     LISTENING     1313   -                   /dev/gpmctl
    unix  2      [ ]         DGRAM                    84704  -
    unix  2      [ ]         DGRAM                    84642  -
    unix  2      [ ]         DGRAM                    43272  -
    unix  2      [ ]         DGRAM                    14241  -
    unix  2      [ ]         DGRAM                    12194  -
    unix  2      [ ]         DGRAM                    4606   -
    unix  2      [ ]         DGRAM                    4016   -
    unix  2      [ ]         DGRAM                    3962   -
    unix  2      [ ]         DGRAM                    3925   -
    unix  2      [ ]         DGRAM                    1292   -
    unix  2      [ ]         DGRAM                    1105   -
    unix  2      [ ]         DGRAM                    1072   -
    unix  2      [ ]         DGRAM                    940    -
    unix  2      [ ]         DGRAM                    904    -
    unix  2      [ ]         STREAM     CONNECTED     540    -

(예제14) sockaddr_un형식의 주소를 소켓이 가지도록 설정하기2
  1)설명 : sockaddr_un형식의 주소를 소켓이 갖도록 설정하고 netstat명령을 실행시켜 확인해보도록
         하고 @문자가 추상적인 지역주소를 이용하고 있음을 표시한다.
  2)프로그램 (unixsock1.c)
    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<errno.h>
    #include<string.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<sys/socket.h>
    #include<sys/un.h>

    static void
    bail(const char *on_what)
    {
      perror("on_what");
      exit(1);
    }

    int main(int argc, char **argv, char **envp)
    {
      int z;
      int sck_unix;
      struct sockaddr_un adr_unix;
      int len_unix;
      const char pth_unix[]="Z*MY-SOCKET*";
      sck_unix=socket(AF_UNIX,SOCK_STREAM,0);
      if ( sck_unix==-1)
       bail("socket()");

      memset(&adr_unix,0,sizeof adr_unix);
      adr_unix.sun_family=AF_UNIX;

      strncpy(adr_unix.sun_path,pth_unix,sizeof adr_unix.sun_path-1)
      [sizeof adr_unix.sun_path-1]=0;

      len_unix=SUN_LEN(&adr_unix);
      adr.unix.sun_path[0]=0;
      z=bind(sck_unix,(struct sockaddr *)&adr_unix,len_unix);

      if ( z==-1)
        bail("bind()");
      system("netstat -pa --unix 2>/dev/null |" "sed -n '/^Active UNIX/,/^proto/p;""/af_uni
      x/p'");
      close(sck_unix);
      return 0;
    }
  3)사용예
    [posein@www posein]$ ./a.out
    Active UNIX domain sockets (servers and established)
    Proto RefCnt Flags       Type       State         I-Node PID/Program name    Path
    unix  2      [ ACC ]     STREAM     LISTENING     4039   -                   /tmp/mysql.so
    ck
    unix  2      [ ]         STREAM                   88836  8935/a.out          @*MY-SOCKET*
    unix  2      [ ACC ]     STREAM     LISTENING     3959   -                   /tmp/.font-un
    ix/fs7100
    unix  16     [ ]         DGRAM                    892    -                   /dev/log
    unix  2      [ ACC ]     STREAM     LISTENING     1313   -                   /dev/gpmctl
    unix  2      [ ]         DGRAM                    84704  -
    unix  2      [ ]         DGRAM                    84642  -
    unix  2      [ ]         DGRAM                    43272  -
    unix  2      [ ]         DGRAM                    14241  -
    unix  2      [ ]         DGRAM                    12194  -
    unix  2      [ ]         DGRAM                    4606   -
    unix  2      [ ]         DGRAM                    4016   -
    unix  2      [ ]         DGRAM                    3962   -
    unix  2      [ ]         DGRAM                    3925   -
    unix  2      [ ]         DGRAM                    1292   -
    unix  2      [ ]         DGRAM                    1105   -
    unix  2      [ ]         DGRAM                    1072   -
    unix  2      [ ]         DGRAM                    940    -
    unix  2      [ ]         DGRAM                    904    -
    unix  2      [ ]         STREAM     CONNECTED     540    -

5. 주소 변환 함수(Address Conversion Functions)
(1) IP주소와 함수 : IP주소를 산정해주는 많은 함수가 존재한다.
   1)예
     ina.sin_addr.s_addr=inet_addr("203.27.40.252")
      => inet_addr()함수를 이용하여 IP주소를 unsigned long변수에 저장한 것이다. 참고로 inet_
        addr()은 htonl을 사용하지 않고 그 결과값으로 NBO값을 돌려준다. 주의할 것은 에러의 경우
       -1을 돌려주게 되는데 이는 unsigned long에서는 255.255.255.255을 뜻하며 이는 broadcast
       주소가 된다.
(2)커널 선정 IP주소 : 프로세스는 소켓의 IP주소를 커널에게 위임할 수도 있다 .2개 이상의 네트
                    워크 인터페이스가 장착된 경우 많이 이용된다. 실제연결이 설정될 때 소켓주소
                    를 결정한다 .포트번호도 커널이 선택한다.
   1)예
     struct sockaddr_in  adr_inet;
     int                 adr_len;

     memset(&adr_inet,0,sizeof(adr_inet);

     adr_inet.sin_family=AF_INET;
     adr_inet.sin_port=ntohs(0);
     adr_inet.sin_addr.s_addr=ntohl(INADDR_ANY);
     adr_len=sizeof(adr_inet);
      => 소켓의 주소는 실제 연결이 설정되는 순간에 커널에 의해 결정된다. sockaddr_in구조체의
        sin_addr.saddr필드에 ntohl(INADDR_ANY)값을 저장하면 된다. 마찬가지로 포트번호도 커널이
        선택할 수 있도록 지정할 수 있는 포트번호 필드를 0값으로 지정한다.
(예제15) 특정IP주소로 소켓의 주소를 지정하기
  1)설명 : 특정IP주소로 소켓의 주소를 지정한다.
  2)프로그램(ipaddr.c)
    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<errno.h>
    #include<string.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<sys/socket.h>
    #include<netinet/in.h>

    static void bail(const char *on_what)
    {
      perror(on_what);
      exit(1);
    }

    int main(int argc, char **argv, char **envp)
    {
      int z;
      int sck_inet;
      struct sockaddr_in adr_inet;
      int len_inet;
      const unsigned char IPno[]={127,0,0,1};
      sck_inet=socket(AF_INET,SOCK_STREAM,0);
      sck_inet=socket(AF_INET,SOCK_STREAM,0);

      if(sck_inet==-1)
       bail("socket()");
      memset(&adr_inet,0,sizeof adr_inet);

      adr_inet.sin_family=AF_INET;
      adr_inet.sin_port=htons(9000);
      memcpy(&adr_inet.sin_addr.s_addr,IPno,4);
      len_inet=sizeof adr_inet;

      z=bind(sck_inet,(struct sockaddr *)&adr_inet,len_inet);

      if(z==-1)
       bail("bind()");

      system("netstat -pa --tcp 2>/dev/null|" "sed -n '1,/^Proto/p;/af_inet/p'");
      close(sck_inet);
      return 0;
    }
  3)사용예
    [posein@www posein]$ ./a.out
    Active Internet connections (servers and established)
    Proto Recv-Q Send-Q Local Address        Foreign Address      State      PID/Program name
(3) inet_addr()
   1)사용법
     #include<sys/socket.h>
     #include<netinet/in.h>
     #include&arpa/inet.h>

     unsigned long inet_addr(const char *string);
   2)설명
     ㄱ. 32비트 IP주소로 변환 : 네트워크 바이트순서이다.
         string:dotted-quad표기형식("203.247.40.252")
     ㄴ. 현재는 ipv6까지 지원하지 않는 함수라면 inet_aton을 사용하는 것이 좋다.
     ㄷ. 반환값은 성공했을 경우에는 32비트주소(네트워크 바이트순서)로 리턴하며, 실패할 경우에
        는 -1(INADDR_NONE)를 리턴한다.
(4) inet_aton() : inet_addr()함수의 기능을 개선한 함수라고 할 수 있다.
   1)사용법
     #include<sys/socket.h>
     #include<netinet/in.h>
     #include<arpa/inet.h>

     int inet_aton(const char *string, struct in_addr *addr);
   2)설명
     ㄱ.인자
        a. string : dotted-quad IP주소
        b. addr : 변환될 주소가 저장될 인자
     ㄴ. 반환값 : 성공하면 0이 아닌 값을 리턴하며, 실패할 경우에는 0을 반환한다.
   3)사용예
     AF_INET 소켓의 주소를 다음과 같이 정의했다면
       struct sockaddr_in adr_inet;
     inet_aton()의 두번째인자는 다음과 같은 형태가 전달된다.
       &adr_inet.sin_addr
     그러므로, 실제 호출 형태는
       inet_aton(string,&adr_inet.sin_addr);
     이다.
(5) inet_ntoa()
   1)사용법
     #include<sys/socket.h>
     #include<netinet/in.h>
     #include<arpa/inet.h>

     char *inet_ntoa(struct in_addr addr);
   2)설명
     ㄱ. IP주소를 dotted-quad표기 문자열로 변환
     ㄴ. static문자 배열을 이용 : 반환값은 이 배열의 주소이고 다음번 호출때까지만 결과가 유효
       하다.
   3)사용예
     struct sockaddr_in addr;

     printf("IP ADDR"%s\n",inet_ntoa(addr.sin_addr);
      => 이 함수는 인자를 하나만 받는다. 이 인자는 32비트로 되어 있는 IP주소값이 된다. 이 주소
        를 dotted quad표기 형태의 문자열로 변환한다. 이 변환 작업중에 함수는 내부적으로 할당해
        놓은 정적변수를 이용한다. 변환 결과가 이 정적 문자 배열에 저장되거 함수의 반환값으로
        이용한다. 변환 결과가 이 정적 문자 배열에 저장되고 함수의 반환값으로는 정적 변수의 주소
        가 변환된다. 그러므로 변환 결과는 다음 번 이 함수가 호출되기 전까지만 유효하다. 왜냐하
        면 다음 번 호출이 일어나면 결과가 다시 이 정적 변수에 저장되기 때문이다.
(6) 기타 변환 함수들
   1)사용법
     #include<sys/socket.h>
     #include<netinet/in.h>
     #include<arpa/inet.h>

     unsigned long inet_lnaof(struct in_addr addr);
     unsigned long inet_netof(struct in_addr addr);
     unsigned long inet_makeaddr(int net,int host);
   2)설명
     ㄱ. inet_lnaof() : 32비트주소(네트워크 바이트순서) => 32비트 호스트번호(호스트순서)
     ㄴ. inet_netof() : 32비트주소(네트워크 바이트순서) => 32비트 네트워크번호(호스트순서)
     ㄷ. inet_makeaddr() : 네트워크번호 + 호스트번호 => 32비트 IP주소(네트워크바이트순서)
(7) getpeername()
   1)사용법
     #include <sys/socket.h>

     int getpeername(int sockfd, struct sockaddr *addr, int *addrlen);
   2)설명
     ㄱ. 상대편의 스트림 소켓에 누가 연결했는지 알려준다.
     ㄴ. sockfd : 스트림소켓 기술자
     ㄷ. addr : struct sockaddr(또는 struct sockaddr_in)의 포인터(상대편정보를 갖음)
     ㄹ. addrlen : 구조체의 크기를 나타내는 정수를 가리키는 포인터
     ㅁ. 반환값으로는 성공하면 0을 리턴하며, 실패하면 -1을 리턴한다.
(8)gethostname()
   1)사용법
     #include<unistd.h>

     int gethostname(char *hostname, size_t size);
   2)설명
     ㄱ. 현재 프로그램이 실행중인 컴퓨터의 이름을 알려준다.
     ㄴ. Hostname은 문자열의 포인터(함수가 돌려주는 값을 넣을 변수이다.)
     ㄷ. size는 문자열의 크기이다.
     ㄹ. 반환값으로는 성공하면 0을 리턴하며, 실패하면 -1을 리턴한다.

6. socket()과 bind()
(1)bind()
   1)사용법
     #include<sys/types.h>
     #include<sys/socket.h>

     int bind(int sockfd, sockaddr *my_addr, int addrlen);
   2)설명
     ㄱ. sockfd : socket()함수에서 받은 소켓기술자
     ㄴ. my_addr : struct sockaddr에 대한 포인터(IP주소에 관한 정보를 갖고 있음)
     ㄷ. addrlen : 구조체의 크기(sizeof(struct sockaddr))
     ㄹ. 반환값은 성공하면 0을 리턴하며, 실패하면 -1을 리턴한다.
   3)특징 : bind()함수를 호출하지 않아도 되는 경우가 있는데 그것을 예를 들면 다른 호스트에
          connect()함수를 이용해 연결하고자 하는 경우에는 자신의 포트에 관심을 두지 않아도
          된다. 수신측은 목적지로 연결을 시도할 때 자신의 포트번호는 1024보다 큰 것으로 random
          하게 잡고 간다.
(2)Port와 주소의 자동지정
   1)사용법
     my_addr.sin_port=0;
     my_addr.sin_addr.s_addr=INADDR_ANY;
   2)설명
     ㄱ. my_addr.sin_port는 '0'으로 설정되면 쓰이고 있지않은 포트번호를 지정해준다. 주의할 점
        은 1024보다 작은 번호는 모두 예약된 포트번호이다. 따라고 그 보다 큰범위로부터 65535까지
        의 번호를 할당한다.
     ㄴ. My_addr.sin_addr.s_addr을 INADDR_ANY로 지정하는 것은 지금 자신의 IP주소를 자동으로
        지정해 주라는 의미이다.
(예제16) bind()함수를 이용하여 소켓을 만들어보기
  1)설명 : bind()함수 이용해 본다.
  2)프로그램(bind.c)
    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<string.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>

    static void bail(const char *on_what)
    {
      perror(on_what);
      exit(1);
    }

    int main(int argc, char **argv, char **envp)
    {
      int z;
      int sck_inet;
      struct sockaddr_in adr_inet;
      int len_inet;

      sck_inet=socket(AF_INET, SOCK_STREAM, 0);
      if (sck_inet==-1)
       bail("socket()");
      memset(&adr_inet,0,sizeof adr_inet);

      adr_inet.sin_family=AF_INET;
      adr_inet.sin_port=htons(9000);

      inet_aton("127.0.0.24",&adr_inet.sin_addr);

      len_inet=sizeof adr_inet;

      z=bind(sck_inet,(struct sockaddr *)&adr_inet,len_inet);

      if(z==-1)
       bail("bind()");
      system("netstat -pa --tcp 2>/dev/null |""sed -n '1,/^Proto/p;/bind/p'");
      close(sck_inet);
      return 0;
    }
   3)사용예
     [posein@www posein]$ ./a.out
     Active Internet connections (servers and established)
     Proto Recv-Q Send-Q Local Address        Foreign Address      State     PID/Program name

7. 비연결성 프로토콜(Connectionless Protocols)
(예제17) 데이터그램서버
  1)설명 : 데이타그램을 이용한 서버프로그램을 실행시켜 본다.
  2)프로그램(dgramsrvr.c)
    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<errno.h>
    #include<string.h>
    #include<time.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>

    static void bail(const char *on_what)
    {
      fputs(strerror(errno),stderr);
      fputs(": ",stderr);
      fputs(on_what,stderr);
      fputc('\n',stderr);
      exit(1);
    }

    int main(int argc, char **argv)
    {
      int z;
      char *srvr_addr =NULL;
      struct sockaddr_in adr_inet;
      struct sockaddr_in adr_clnt;
      int len_inet;
      int s;
      char dgram[512];
      char dtfmt[512];
      time_t td;
      struct tm tm;

      if ( argc >= 2)
      {
        srvr_addr=argv[1];
      }
      else
      {
        srvr_addr="127.0.0.23";
      }

      s=socket(AF_INET,SOCK_DGRAM,0);
      if (s==-1)
       bail("socket()");
      memset(&adr_inet,0,sizeof adr_inet);
     adr_inet.sin_family=AF_INET;
     adr_inet.sin_port=htons(9090);
     adr_inet.sin_addr.s_addr=inet_addr(srvr_addr);

     if (adr_inet.sin_addr.s_addr==INADDR_NONE)
      bail("bad address.");
      len_inet=sizeof adr_inet;

     z=bind(s,(struct sockaddr *)&adr_inet,len_inet);
     if (z==-1)
       bail("bind()");
     for( ; ;)
     {
       len_inet=sizeof adr_clnt;
       z=recvfrom(s,
           dgram,
           sizeof dgram,
           0,
          (struct sockaddr *)&adr_clnt,
          &len_inet);
       if ( z<0)
         bail("recvfrom(2)");
        dgram[2]=0;
        if (!strcasecmp(dgram,"QUIT"))
        break;
        time(&td);
        tm = *localtime(&td);
        strftime(dtfmt,
                 sizeof dtfmt,
                 dgram,
                 &tm);
        z=sendto(s,
                 dtfmt,
                 strlen(dtfmt),
                 0,
                 (struct sockaddr *)&adr_clnt,
                 len_inet);
        if (z <0)
          bail("sendto(2)");
      }
      close(s);
      return 0;
    }
  3)사용예
    [posein@www posein]$ ./a.out &
    [1] 10340
    [posein@www posein]$ ./a.out 203.247.40.252 &
    [2] 10341
    [posein@www posein]$ ./a.out 210.123.193.194 &
    [3] 10342
    [posein@www posein]$ Cannot assign requested address: bind()

    [3]+  Exit 1                  ./a.out 210.123.193.194
      => netstat -anp 명령으로 확인해보자.

8. 연결기반(Connection-Oriented) 프로토콜
(1)서버프로그램
(예제18) TCP기반 프로토콜의 서버프로그램을 실행하여 특정포트로 소켓을 설정하기
  1)설명 : TCP기반 프로토콜에서 특정포트를 열어 소켓을 활성화한 후 접속한 클라이언트에게 현재
         시간을 출력해준다.
  2)프로그램(tcpserver.c)
    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<errno.h>
    #include<string.h>
    #include<time.h>
    #include<sys/types.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>
    #include<netdb.h>

    static void bail(const char *on_what)
    {
      if (errno !=0)
      {
        fputs(strerror(errno),stderr);
        fputs(": ",stderr);
      }
      fputs(on_what,stderr);
      fputc('\n',stderr);
      exit(1);
    }

    int main(int argc, char **argv)
    {
      int z;
      char *srvr_addr= NULL;
      char *srvr_port="9099";
      struct sockaddr_in adr_srvr;
      struct sockaddr_in adr_clnt;
      int len_inet;
      int s;
      int c;
      int n;
      time_t td;
      char dtbuf[128];

      if (argc >= 2)
      {
        srvr_addr=argv[1];
      }
      else
      {
        srvr_addr="127.0.0.1";
      }
      if (argc>=3)
        srvr_port = argv[2];
      s = socket(PF_INET, SOCK_STREAM,0);
      if ( s==-1)
       bail("socket()");
      memset(&adr_srvr,0,sizeof adr_srvr);
      adr_srvr.sin_family=AF_INET;
      adr_srvr.sin_port=htons(atoi(srvr_port));
      if ( strcmp(srvr_addr,"*") !=0)
      {
        adr_srvr.sin_addr.s_addr=inet_addr(srvr_addr);
        if (adr_srvr.sin_addr.s_addr==INADDR_NONE)
         bail("bad address.");
      }
      else
      {
         adr_srvr.sin_addr.s_addr=INADDR_ANY;
      }
      len_inet=sizeof adr_srvr;
      z=bind(s,(struct sockaddr *)&adr_srvr,len_inet);
      if ( z==-1)
       bail("bind(2)");
      z=listen(s,10);
      if ( z==-1)
       bail("listen(2)");
      for (;;)
      {
        len_inet=sizeof adr_clnt;
        c=accept(s,
                 (struct sockaddr *)&adr_clnt,
                 &len_inet);
        if ( c==-1)
          bail("accept(2)");
        time(&td);
        n=(int) strftime(dtbuf,sizeof dtbuf,"%A %b %d %M %S %Y\n",
                         localtime(&td));
        z=write(c,dtbuf,n);
        if ( z==-1)
         bail("write(2)");
        close(c);
       }
       return 0;
    }
  3)사용예
    ㄱ. 실행
     [posein@www posein]$ ./a.out &
     [1] 12272
    ㄴ. 확인
      [posein@www posein]$ netstat -p --inet
      Active Internet connections (w/o servers)
      Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
      tcp        1      0 localhost.localdom:9000 localhost.localdo:43128 CLOSE_WAIT  -
    ㄷ. 접속해보기
       [posein@www posein]$ telnet localhost 9099
       Trying 127.0.0.1...
       Connected to localhost.localdomain (127.0.0.1).
       Escape character is '^]'.
       Thursday Jan 03 52 37 2002                      //현재 날짜와 시간등을 출력해준다.
       Connection closed by foreign host.
(2)클라이언트프로그램
(예제19) 서버로부터 메시지를 받아오는 클라이언트 프로그램
  1)설명 : 작동중인 서버프로그램으로부터 특정포트로 접속하여 메시지를 받아오도록 한다.
  2)프로그램(tcpclient.c)
    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<errno.h>
    #include<string.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>
    #include<netdb.h>

    static void bail(const char *on_what)
    {
      if(errno !=0)
      {
        fputs(strerror(errno),stderr);
        fputs(": ",stderr);
      }
      fputs(on_what,stderr);
      fputc('\n',stderr);
      exit(1);
    }
    int main(int argc,char **argv)
    {
      int z;
      char *srvr_addr=NULL;
      char *srvr_port="9099";
      struct sockaddr_in adr_srvr;
      int len_inet;
      int s;
      char dtbuf[128];
      if (argc >=2)
      {
        srvr_addr=argv[1];
      }
      else
     {
       srvr_addr="127.0.0.1";
     }
      if (argc>=3)
         srvr_port=argv[2];
      s=socket(PF_INET,SOCK_STREAM,0);
      if (s==-1)
       bail("socket()");
      memset(&adr_srvr,0,sizeof adr_srvr);
      adr_srvr.sin_family=AF_INET;
      adr_srvr.sin_port=htons(atoi(srvr_port));
      adr_srvr.sin_addr.s_addr=inet_addr(srvr_addr);
      if (adr_srvr.sin_addr.s_addr==INADDR_NONE)
       bail("bad address.");
      len_inet=sizeof adr_srvr;

      z=connect(s,&adr_srvr,len_inet);
      if (z==-1)
       bail("connect(2)");
      z=read(s,&dtbuf,sizeof dtbuf-1);
      if(z==-1)
      bail("read(2)");
      dtbuf[z]=0;
      printf("Date & Time is : %s\n",dtbuf);
      close(s);
      putchar('\n');
      return 0;
    }
  3)실행예
    [posein@www posein]$ ./tcpclient
    Date & Time is : Thursday Jan 03 23 31 2002
      => 서버로부터 현재시간을 받아 출력한다.
    [posein@www posein]$ ./tcpclient 9099
    Invalid argument: connect(2)                  //오류형태1
    [posein@www posein]$ ./tcpclient aaa 9099
    bad address.                                  //오류형태2

9. 블로킹과 select()함수
(1)블로킹
   1)블로킹 : 잠자는 듯이 기다리는 것을 의미한다.
   2)예 : recvfrom()함수를 호출하였을 때 데이터가 들어올 때까지 기다리게 되는데 이런 것이
        블로킹이다.
   3)블로킹되는 함수 : accept(), recv(), recvfrom()등
   4)사용하는 이유 : 함수를 블록 가능하게 하는 이유는 소켓이 socket()함수로 만들어 질 때 블록
                  가능하게 설정했기 때문이다.
   5)블로킹방지 : fcntl()함수를 이용하여 블로킹을 방지
     ㄱ. 사용법
        #include<unistd.h>
        #include<fcntl.h>

        sockfd=socket(AF_INET,SOCK_STREAM,0);
        fcntl(sockfd,F_SETFL,O_NONBLOCK);
      ㄴ. 설명
         a. 효과적인 socket이용가능
         b. 데이터가 접수되지 않은 소켓에서 데이터를 읽으려고 시도하면 -1을 반환, errno를
           EWOULDBLOCK으로 세팅한다.
(2)select() : 서버프로세스가 동작하고 있을 경우 이미 연결된 소켓에 데이터가 들어올 경우가
              있다. 중복 입출력은 관리하는 함수이다.
   1)사용법
     #include<sys/time.h>
     #include<sys/types.h>
     #include<unistd.h>

     int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
                struct timeval *timeout);
   2)설명
     ㄱ. 파일 기술자의 집합인 readfds, writefds, exceptfds등을 관리
     ㄴ. numfds : 가장 높은 파일 기술자에 '1'을 더해서 지정함.
     ㄷ. Timeval : 시간간격을 정의함.
   3) struct timeval의 구조
     ㄱ. 사용법
        struct timeval {
            int tv_sec;                             /* seconds */
            int tv_usec;                            /* microseconds */
        }
     ㄴ. 설명
        a. tv_sec은 초단위
        b. tv_usec은 마이크로 초(백만분의 일초)단위
     ㄷ. 특징 : 만약에 timeval변수들을 '0'으로 하면 select()함수는 즉시 그 결과를 돌려주게
              되며 지금의 set의 내용들을 바로 알려주게 된다. 만약에 timeout를 null로 지정
              하면 끝나지 않고 파일 기술자를 기다리게 되고, 어떤 특정한 set의 변화에 관심이
              없다면 그러한 부분을 null로 채우면 된다.
   4) 파일 기술자 집합의 관리 : 각각의 집합은 fd_set형이고 다음에 나오는 매크로형으로 제어가능
     ㄱ. FD_ZERO(fd_set *set) : 파일 기술자 집합을 제거
     ㄴ. FD_SET(int fd_set *set) : fd를 set에 더해줌
     ㄷ. FD_CLR(int fd,fd_set *set) : fd를 set에서 제거
     ㄹ. FD_ISSET(int fd, fd-set *set) : fd가 set안에 있는지 검사

10. 호스트이름과 네트워크이름 검색
(1)uname() : 프로그램이 수행 중인 시스템에 관한 정보를 제공해준다. 지역 호스트에 관한 자세한
             정보를 얻어낼 수 있다.
   1)사용법
     #include<sys/utsname.h>

     int uname(struct utsname *buf);

     struct utsname {
          char    sysname[SYS_NMNL];
          char    nodename[SYS_NMLN];
          char    release[SYS_NMLN];
          char    version[SYS_NMLN];
          char    machine[SYS_NMLN];
          char    domainname[SYS_NMLN];
     }
   2)구조체의 필드값
     ㄱ. sysname : 현재 운용중인 운영체제의 이름
        예) "Linux"
     ㄴ. nodename : 컴퓨터의 네트워크 호스트 이름
        예) "com01"
     ㄷ. release : 운영체제의 배포번호
        예) 2.2.16
     ㄹ. version : 운영체제의 버전, 리눅스는 버전번호, 커널 빌드의 날짜
        예)"#2 SMP Sat Dec 23 10:03:50 KST 2000"
     ㅁ. machine : 하드웨어 유형
        예) "i686"
     ㅂ. domainname : NIS/YP 도메인 이름
   3)설명 : 성공하면 0을 리턴하며 실패하면 -1을 리턴한다.

(예제20) 시스템의 정보보기
  1)설명 : uname()함수를 이용하여 시스템의 정보를 출력해보자.
  2)프로그램(uname.c)
    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<errno.h>
    #include<string.h>
    #include<sys/utsname.h>

    int main (int argc, char **argv)
    {
      int z;
      struct utsname u_name;

      z=uname(&u_name);

      if(z==-1)
      {
        fprintf(stderr,"%s,: uname(2)\n",strerror(errno));
        exit(1);
      }
      printf("  sysname[]='%s';\n",u_name.sysname);
      printf("  nodename[]='%s';\n",u_name.nodename);
      printf("  release[]='%s';\n",u_name.release);
      printf("  version[]='%s';\n",u_name.version);
      printf("  machine[]='%s';\n",u_name.machine);

      return 0;
    }

  3)실행예
    [posein@www posein]$ ./a.out
      sysname[]='Linux';
      nodename[]='www';
      release[]='2.4.2-3';
      version[]='#1 Sun Jun 24 01:31:37 KST 2001';
      machine[]='i686';
(2)호스트이름과 도메인이름
   1)사용법
     #include<unistd.h>

     int gethostname(char *name,size_t len);
     int getdomainname(char *name, size_t len);

   2)설명
     ㄱ. 각각 호스트이름과 NIS도메인 이름을 반환
     ㄴ. getdomainname()함수는 내부적으로 uname()함수를 사용
   3)반환값 : 성공하면 0을 실패하면 -1을 리턴한다.
(예제21) 현재 시스템의 호스트이름과 도메인이름 출력
  1)설명 : 현재시스템의 호스트이름과 도메인이름을 출력해본다.
  2)프로그램(gethostname.c)
    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<errno.h>
    #include<string.h>

    int main(int argc, char **argv)
    {
      int z;
      char buf[32];

      z=gethostname(buf,sizeof buf);

      if (z==-1)
      {
        fprintf(stderr,"%s: gethostname(2)\n", strerror(errno));
        exit(1);
      }
      printf("host name='%s'\n",buf);

      z=getdomainname(buf,sizeof buf);

      if (z==-1)
      {
        fprintf(stderr,"%s: getdomainname(2)\n",strerror(errno));
        exit(1);
      }

      printf("domain name='%s'\n",buf);

      return 0;
    }
  3)사용예
    [posein@www posein]$ ./a.out
    host name='www'
    domain name='(none)'
(3)원격 호스트 주소검색
(예제22) 원격 호스트의 주소를 검색
  1)설명 : 원격지 호스트의 주소를 검색해본다.
  2)프로그램(lookup.c)
    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<string.h>
    #include<errno.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>
    #include<netdb.h>

    extern int h_errno;

    #define TRUE 1
    #define FALSE 0

    int main(int argc, char **argv)
    {
      int x, x2;
      struct hostent *hp;

      sethostent(TRUE);

      for (x=1;xh_name);
        fputs("  Aliases:\t",stdout);
        for(x2=0;hp->h_aliases[x2];++x2)
        {
          if (x2)
            fputs(",",stdout);
          fputs(hp->h_aliases[x2],stdout);
        }
        fputc('\n',stdout);
        printf("  Type:\t\t%s\n",
               hp->h_addrtype == AF_INET
                   ? "AF_INET"
                   : "AF_INET6");
        if (hp->h_addrtype == AF_INET)
        {
          for (x2=0; hp->h_addr_list[x2];++x2)
          printf("  Address:\t%s\n",
          printf("  Address:\t%s\n",
                  inet_ntoa( *(struct in_addr *)
                  hp->h_addr_list[x2]));
        }
        putchar('\n');
      }
      return 0;
    }
  3)사용예
    [posein@www posein]$ ./a.out www.microsoft.com www.chosun.com
    Host www.microsoft.com :
      Officially:   www.microsoft.akadns.net
      Aliases:      www.microsoft.com
      Type:         AF_INET
      Address:      207.46.197.100
      Address:      207.46.197.101
      Address:      207.46.197.102
      Address:      207.46.197.113
      Address:      207.46.230.218
      Address:      207.46.230.219
      Address:      207.46.230.220

    Host www.chosun.com :
      Officially:   www.chosun.com
      Aliases:
      Type:         AF_INET
      Address:      210.116.112.100
      Address:      210.116.112.200
(예제23) 원격 호스트의 열려진 포트 검색
  1)설명 : 원격 호스트의 열려진 포트(1024번이내)를 검색하는 프로그램이다.
  2)프로그램(p.c)
    #include<string.h>
    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netdb.h>
    #include<netinet/in.h>
    #include<errno.h>

    int samplescan(char *hostaddr, int cport, int socktype);
    int main(int argc, char *argv[])
    {
        int loop_port;
       //loop defined
       // address check
       // if address argc don't collect, exit

        if (argc < 2)
        {
           printf("samplescan address\n");
           exit(1);
        }

        // well-known port scaning range.

        for (loop_port = 1;loop_port < 1024;loop_port++)
        {
         //if term is collect, excute
           if (samplescan(argv[1], loop_port, SOCK_STREAM) == 0)
           {
             printf("%5d Open\n", loop_port);
           }
         }
         return 0;
    }

    int samplescan(char *hostaddr, int loop_port, int socktype)
    {
      int sockfd;
     //soket fd(file descripter)
      struct hostent *he;
      struct sockaddr_in destaddr;
      int pok;
      if ((he = gethostbyname(hostaddr)) == NULL)
      {
         printf("error");
         return 0;
      }
      sockfd = socket(AF_INET, socktype, 0);

      destaddr.sin_family = AF_INET;       /* TCP/IP connetion request */
      destaddr.sin_addr = *((struct in_addr *)he->h_addr);
      /* address value */
      destaddr.sin_port = htons(loop_port);                /* port place */
      bzero(&(destaddr.sin_zero), 8);
      pok = connect(sockfd, (struct sockaddr *)&destaddr, sizeof(struct sockaddr));
      /* connect */
      close(sockfd);
      /* close */

      if (pok == -1)
      /* connet return value 0 but -1 */
      return -1;
      return 0;
    }
  3)사용예
    [posein@www posein]$ ./a.out www.hannam.ac.kr
        7 Open
        9 Open
       13 Open
       19 Open
       21 Open
       23 Open
       25 Open
       37 Open
       79 Open
       80 Open
      109 Open
      110 Open
      111 Open
      512 Open
      513 Open
      514 Open
      540 Open
      587 Open
 
출처 블로그 > 석민이네 집
원본 http://blog.naver.com/dgkwon01/90004497176

 

    레이어 닫기

    'My work space > Java' 카테고리의 다른 글

    프로그래밍에유용한사이트  (0) 2008.08.20
    AWT/SWING 성능 비교(기본 출력 기능)  (0) 2008.08.20
    Swing으로 GUI만들기  (0) 2008.08.20
    AWT란  (0) 2008.08.20
    awt와 swing의 차이점  (0) 2008.08.20
    2008. 8. 20. 14:57

    Swing으로 GUI만들기

    Swing으로 GUI만들기

    Objective

    • JDK 1.2에서는 JFC를 제공하고 있다.
    • JFC의 한 부분으로 100% pure Java로 구현한 Swing이라는 새로운 Component를 제공하고 있다.
    • JFC에 대한 간단한 소개와
    • Swing package에 대한 소개를 하고,
    • Swing component에 대한 정의와
    • container와 component를 정의하고, SwingGUI를 만들기 위해서 어떻게 상호간에 동작하는 가를 보고,
    • 간단한 Swing application을 compile하고 실행시켜 본다.
    • JComponent Class의 주요한 특징

    JFC란?

    앞의 강의에서 배웠던 JDK 1.1 의 GUI인 AWT를 확장한 것으로 AWT기반의 Application과 완전히 호환되는 그래픽 사용자 인터페이스(GUI) 클래스 라이브러리를 추가한 것이다. JFC는 다음과 같이 구성이 되어 있다.

    AWT

    앞의 강의에서 배웠던 것처럼 Java application에 있어서 광범위하게 사용되는 GUI tools을 제공한다.

    Swing 1.0

    platform 독립적으로 보여질 수 있는 GUI를 만들기 위한 많은 component와 framework을 제공한다. 즉, form-based application 개발을 위해서 설계되었다.

    Drag and Drop

    Java application과 non-java application간의 데이터를 공유하는 것으로 MIME 기반의 확장 가능한 데이터 타입 시스템을 사용해서 가능하게 했다

    Java 2D class library

    컬러 제어, 라인아트, 이미지 프로세싱, 스타일드 텍스트등을 다룰수 있다.

    Accessibility

    비 전통적인 입출력을 사용하는 application 개발을 돕기 위한 도구를 제공한다. 이 api를 사용해서, screen readers, screen magnifiers, audible text readers같은 보조적인 기술에 대한 interface를 제공한다.



    Swing에 대해서

    Swing의 이점

    • Swing component는 Beans이다. 그렇기 때문에 Beans를 지원하는 모든 개발환경에서 사용할 수 있다.
    • Swing은 대부분의 UI component를 제공한다.
    • 속도의 측면에서도 모든 component는 lightweight이다.
    • Swing은 portability의 측면에 있어서도 전부 자바로 작성되어졌기 때문에 충분히 만족한다.
    • Keyboard의 이동을 자동으로 구현을 해 준다. - 기존의 AWT는 특별한 code가 필요하다.
    • Scrolling의 지원은 큰 노력이 필요하지 않다. 단지 JScrollPane에 component를 add하면 된다.
    • Swing은 "pluggable look and feel"을 지원한다. UI의 appearance를 현재 작업하고있는 platform에 상관없이 동적으로 바꿀 수 있다.

    Pluggable Look and Feel

    • 앞의 강의에서 배웠던 JDK 1.1의 AWT를 사용하면, 아래의 그림 중에서 1) 혹은 2) 모습이다. (Win95환경경우는 1), Motif환경의 경우는 2).


    • Swing을 사용하면, 사용자가 사용자의 마음에 드는 디자인과 인터페이스를 제공할 수 있도록 Programing을 할 수가 있다. 이와 같은 것을 pluggable look and feel(교체 가능한 룩앤필)이라고 한다.
    • 기존의 환경에서, 그리고, JDK1.1에서 제공하는 AWT를 사용할 때는 하나의 디자인과 인터페이스를 가지고 있어서 그것을 따를 수밖에 없었다. Swing을 이용하면, 사용자가 다양한 look and feel을 선택하거나 프로그램 상황에 맞게[ 룩앤필을 정해놓고 사용할 수 있다.

    Swing vs AWT

    • Swing component는 JDK 1.1에서의 AWT component와 마찬가지로 경량(light weight)component 이지만, 더 많은 component를 제공하며, 이들은 많은 새로운 형태의 기능을 수행하게 한다.

    Swing과 AWT과의 차이점

    Swing과 AWT 간의 가장 큰 차이점은

    • Swing component는 수행될 때, 플랫폼으로부터 어떠한 native code도 가져다 쓰지 않는 다는 것이다. 다시 말해서 swing은 전혀 platform 종속적인 수행을 하지 않는 다는 것이다. 그리고 대신에 직접 작성된 교체 가능한 Look and Feel을 사용한 자신의 component를 만들었다.
    • AWT component는 사용자의 입력에 응답하고 그들 자신을 표현하기 위해 peer 형태로 native code에 의존하지만, Swing component는 순수하게 자바로 쓰여졌다는 점이 차이가 난다. Swing component는 자신과 이벤트를 처리하기 위해 UI Object라 불리는 것을 사용하는데, 이 UI object 또한 순수 자바로 작성돼 있다. 이것은 앞서 말한 pluggable Look and Feel 형태를 지원한다.

    ※ 즉, Swing compont는 native code에 의존하지 않고, 특정 플랫폼에 제한되어 있지 않아서 AWT보다 강력한 기능을 가진다 그래서 Swing은 텍스트와 애니메이션을 포함한 이미지들을 나타낼 수 있다.

    Swing Hierarchy


    Swing Component

    다음은 Swing 제공하는 Component이다.





    javax.swing.* package

     

    표 11-1 스윙과 관련된 패키지와 주요기능

    스윙 패키지

    주 요 기 능

    javax.swing

    기본적인 스윙 컴포넌트 클래스를 정의

    javax.swing.border

    스윙의 경계선(border) 특징을 지정하는 클래스

    javax.swing.colorchooser

    스윙에서 색의 선택 기능을 제공

    javax.swing.event

    스윙에서 필요로 하는 이벤트 타입과 리스너를 정의

    javax.swing.filechooser

    파일 선택 기능을 제공하기 위한 클래스 및 인터페이스를 제공

    javax.swing.plaf

    스윙의 look-and-feel에 관련된 클래스 및 인터페이스를 제공

    javax.swing.plaf.basic

    기본적인 look-and-feel에 관련된 UI 객체 생성을 지원

    javax.swing.plaf.metal

    metal look-and-feel에 관련된 UI 객체 생성을 지원

    javax.swing.plaf.multi

    복합 look-and-feel에 관련된 UI 객체 생성을 지원

    javax.swing.table

    스윙의 테이블 관련 클래스를 정의

    javax.swing.text

    스윙의 텍스트 관련 클래스를 정의

    javax.swing.text.html

    텍스트 에디터를 만들기 위한 클래스를 제공

    javax.swing.text.html.parser

    html 문서의 parser 기능을 제공

    javax.swing.text.rtf

    Rich-Text-Format과 관련된 에디터를 만들기 위한 클래스 제공

    javax.swing.tree

    스윙의 트리 작성에 필요한 클래스를 제공

    javax.swing.undo

    텍스트 에디터와 같은 어플리케이션에서 undo/redo 기능을 제공


    AWT Component와 Swing Component의 비교

     

    표 11-2 AWT에서 기능이 확장된 스윙 컴포넌트

    AWT의 컴포넌트

    스윙 컴포넌트

    Frame

    JFrame

    Panel

    JPanel

    Button

    JButton

    TextField

    JTextField

    TextArea

    JTextArea

    List

    JList

    Choice

    JCombo

    Checkbox

    JCheckbox

    Label

    JLabel

    Dialog

    JDialog

    FileDialog

    JFileChooser

    ScrollPane

    JScrollPane

    MenuBar

    JMenuBar

    Menu

    JMenu

    MenuItem

    JMenuItem

    PopupMenu

    JPopupMenu


    Swing에서 새롭게 추가된 Component

     

    표 11-3 스윙에서 추가된 컴포넌트 (일부분임)

    스윙 컴포넌트

    기 능

    JProgressBar

    어떤 작업의 진행정도를 그래픽하게 보여준다

    JSlider

    숫자의 입력을 슬라이드로 할 수 있게 한다

    JToolBar

    메뉴와 비슷하나 floating될 수 있다(도구상자 등)

    JTable

    편리한 테이블 작성을 지원한다

    JTabbedPane

    제목이 있는 여러 화면을 겹치게 구성한다

    JSplitPane

    pane을 두영역으로 나눈다

    JInternalFrame

    프레임 내에 프레임을 만든다

    JLayeredPane

    여러 장의 화면을 중첩할 수 있게 한다

    JTree

    트리 구조로 항목을 나열한다(디렉토리 구조 등)

    JColorChooser

    Color를 선택할 수 있게 한다

    JToggleButton

    버튼이 on, off 상태를 가진다


    AWT에서의 버튼과 Swing의 버튼 비교


    '

    // AWT의 Button 생성 프로그램 ----------------
    import java.awt.*;
    public class Test {
    public void go() {
    Frame frame = new Frame("Button Test");// 프레임 생성
    Panel panel = new Panel();// 패널 생성
    Button button = new Button("Button Test");// 버튼 생성
    panel.add(button);
    frame.add(panel);
    frame.setSize(300,100);
    frame.setVisible(true);
    }
    public static void main(String args[]) {
    new Test().go();
    }
    }
    // 스윙의 JButton 생성 프로그램 ----------------
    import java.awt.*;
    import javax.swing.*;
    public class Test {
    public void go() {
    JFrame frame = new JFrame("JButton Test");// 프레임 생성
    JPanel panel = new JPanel();// 패널 생성
    JButton button = new JButton("JButton Test");// 버튼 생성
    panel.add(button);
    frame.getContentPane().add(panel);
    frame.setSize(300,100);
    frame.setVisible(true);
    }
    public static void main(String args[]){
    new Test().go();
    }
    }

    크게 달라진점 3가지

    • 스윙에서는 import javax.swing.* 이 필요함
    • 스윙 컴포넌트 클래스의 이름의 변경됨 (Button -> JButton)
    • 스윙 컴포넌트를 프레임에 직접 추가하지 못하고 content pane에 추가 해야 함

    다음은 Component들 중에 기본이 되는 component에 대한 간단한 예제와 그 실행의 예이다. 다음의 예를 살펴보면서 중요한 부분과 특징을 살펴 볼 수 있다

    JButton


    import java.awt.*;
    import javax.swing.*;
    import javax.swing.plaf.basic.*;
    import javax.swing.border.*;
    public class Test {
    public void go() {
    JButton button = new JButton("JButton");
    JPanel panel1 = new JPanel();
    JPanel panel2 = new JPanel();
    BasicArrowButton up =
    new BasicArrowButton(BasicArrowButton.NORTH);
    BasicArrowButton down =
    new BasicArrowButton(BasicArrowButton.SOUTH);
    BasicArrowButton right=
    new BasicArrowButton(BasicArrowButton.WEST);
    BasicArrowButton left =
    new BasicArrowButton(BasicArrowButton.EAST);
    panel2.add(up);
    panel2.add(down);
    panel2.add(right);
    panel2.add(left);
    panel2.setBorder(new TitledBorder("Basic Arrow Button"));
    JToggleButton toggle = new JToggleButton("Toggle");
    JRadioButton radio = new JRadioButton("Radio");
    panel1.add(button);
    panel1.add(panel2);
    panel1.add(toggle);
    panel1.add(radio);
    JFrame frame = new JFrame("JButton Test");
    frame.getContentPane().add(panel1);
    frame.setSize(400,100);
    frame.setVisible(true);
    }
    public static void main(String args[]) {
    new Test().go();
    }
    }

    Borders

    스윙에서는 모든 컴포넌트의 경계선을 다양하게 표현할 수 있다. 이 경계선을 표현하기 위해서 아래의 메쏘드를 사용하고 경계선의 종류는 다음과 같다.
    • public void setBorder(Border bd);
    • Border class
    • TitledBorder("Title")
    • EtchedBorder();
    • LineBorder(Color.blue)
    • MatteBorder(5,5,30,30,Color.green);
    • BevelBorder(BevelBorder.LOWERED)
    • CompoundBorder(new EtchedBorder(),new LineBorder(Color.red))



    Tool Tips

    컴포넌트 위에 마우스가 오면 간단한 설명문을 보여주는 기능을 Tool Tips라고 한다. 어떤 컴포넌트가 Tool Tips를 제공하도록 하려면 다음과 같은 메소드를 호출하면서 간단한 설명문의 내용을 스트링 타입의 인자 s로 주면 된다.

      public void setToolTipText(String s);

    아래에 버튼에 Tool Tips를 지정하는 예와 해당 프로그램 보였다.


    import java.awt.*;
    import javax.swing.*;
    public class Test {
     
    public void go() {
    JButton button = new JButton("button");
    JPanel panel = new JPanel();
    button.setToolTipText("Tool Tip Test");
    panel.add(button);
    JFrame frame = new JFrame("ToolTip Test");
    frame.getContentPane().add(panel);
    frame.setSize(150,100);
    frame.setVisible(true);
    }
    public static void main(String args[]) {
    new Test().go();
    }
    }

    Button Groups

    "exclusive or" 형태의 동작을 하는 radio button은 button group에 더할 수 있다. 그리고, 예전의 awt보다는 훨씬 자유스러운 것을 알 수 있다. 아래의 예제에서는 abstract button을 button Group에 더하는 예이다.
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.border.*;
    public class ButtonGroups extends JPanel{
     
    public ButtonGroups(){
    ButtonGroup bg1 = new ButtonGroup();
    ButtonGroup bg2 = new ButtonGroup();
    JPanel jp1 = new JPanel();
    JPanel jp2 = new JPanel();
    jp1.setBorder(new TitledBorder("JButton Group"));
    JButton jb1= new JButton("JButton1");
    JButton jb2= new JButton("JButton2");
    JButton jb3= new JButton("JButton3");
    JButton jb4= new JButton("JButton4");
    jp1.add(jb1);
    bg1.add(jb1);
    jp1.add(jb2);
    bg1.add(jb2);
    jp1.add(jb3);
    bg1.add(jb3);
    jp1.add(jb4);
    bg1.add(jb4);
    add(jp1);
    jp2.setBorder(new TitledBorder("JToggleButton Group"));
    JToggleButton JT1 =new JToggleButton ("JToggleButton1");
    JToggleButton JT2 =new JToggleButton ("JToggleButton2");
    JToggleButton JT3 =new JToggleButton ("JToggleButton3");
    JToggleButton JT4 =new JToggleButton ("JToggleButton4");
    jp2.add(JT1);
    bg2.add(JT1);
    jp2.add(JT2);
    bg2.add(JT2);
    jp2.add(JT3);
    bg2.add(JT3);
    jp2.add(JT4);
    bg2.add(JT4);
    add(jp2);
    }
    public static void main(String args[]){
    JFrame f = new JFrame();
    ButtonGroups bgt = new ButtonGroups();
    f.getContentPane().add(bgt);
    f.setSize(400,400);
    f.setVisible(true);
    }
    }



    ListBox 와 ComboBox

    Swing에서의 List Box와 Combo Box는 예전의 AWT보다 더 많은 일을 할 수 있다. 그리고, 필요하다면, 사용할 수 있는 많은 함수를 가지고 있다.
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    public class ListCombo extends JPanel{
     
    static String ids[] = {"June","Ward","Beaver","Wally","Eddie","Lumpy"};
    public ListCombo(){
    setLayout(new BorderLayout());
    JList list = new JList(ids);
    add(new JScrollPane(list), "Center");
    JComboBox combo = new JComboBox();
    for( int i =0; i <100 ; i++)
    combo.addItem(Integer.toString(i));
    add(combo,"South");
    }
    public static void main(String args[]){
    JFrame f = new JFrame();
    ListCombo list = new ListCombo();
    f.getContentPane().add(list);
    f.pack();
    f.setVisible(true);
    }
    }

    실행결과


    JList는 자동으로 Scrolling을 제공하지 않기 때문에 List을 JScrollpane에 add한후 사용할 수 있다.

    JSliders

    • 슬라이더(JSlider)는 볼륨조절 등을 할 때와 같이 어떤 수치를 직접 입력하는 대신 그래픽으로 입력하는 기능을 제공한다. 슬라이더가 AWT의 스크롤바와 다른점은 스크롤바는 어떤 물체의 보이는 영역을 움직이는데 사용되고 슬라이더는 어떤 값을 입력하는데 사용된다는 것이다. (스윙에서는 스크롤바를 평면적으로 제공하기 위하여 JScrollPane 클래스를 제공하고 있다.)
    • JSlider는 여러 형태의 생성자를 제공하는데 예를들어 다음과 같은 생성자에서 orientation은 수평 또는 수직방향을 나타내고 min은 슬라이더의 최소값을, max는 최대값을, value는 초기값을 각각 지정한다.
      • JSlider(int orientation, int min, int max, int value)
      • JSlider가 제공하는 주요 메소드는 다음과 같다.
      • setMajorTickSpacing(int t)// 눈금의 간격을 지정
      • getValue() // 현재의 슬라이더의 값을 읽음
      • setValue() // 현재의 슬라이더의 값을 지정
      • setPaintTicks(true)// 눈금을 나타냄
      • setPaintLabels(true)// 눈금의 값을 나타냄
      • addChangeListener(ChangeListener c) // 리스너 연결
    • 아래에는 0과 100 사이의 값을 입력하는 슬라이더와 해당 프로그램을 보였는데 현재의 슬라이더의 위치 값을 JTextField에 나타내고 있다. 슬라이드가 움직일 때 발생하는 이벤트를 익명클래스로 처리하고 있으며 리스너를 연결하기 위하여 addChangeListener() 메소드를 사용하고 있다.

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    public class SliderTest {
     
    JPanel panel = new JPanel();
    JTextField jtf = new JTextField(20);
    JSlider sd = new JSlider(JSlider.HORIZONTAL, 0, 100, 60);
    public void go() {
    panel.setLayout(new GridLayout(2, 1));
    panel.add(jtf);
    sd.setValue(0);
    sd.setMajorTickSpacing(20);
    sd.setMinorTickSpacing(5);
    sd.setPaintTicks(true);
    sd.setPaintLabels(true);
    sd.addChangeListener(new ChangeListener() {// 익명클래스
    public void stateChanged(ChangeEvent e) {
    jtf.setText("Position is "+ sd.getValue());
    }
    } );
    panel.add(sd);
    JFrame frame = new JFrame();
    frame.getContentPane().add(panel);// 프레임에 패널을 추가
    frame.setSize(200,200);
    frame.setVisible(true);
    }
    public static void main(String args[]) {
    new SliderTest().go();
    }
    }

    JProgressBar

    • JProgressBar는 어떤 작업의 진행정도를 그래픽하게 나타내는 데 사용된다. JProgressBar는 여러가지 생성자를 제공하는데, 예를들어 다음과 같은 생성자에서 orientation은 수평 또는 수직방향을 나타내고, min은 최소값을, max는 최대값을 각각 나타낸다.
    • JProgressBar(int orientation, int min, int max)
    • JProgressBar가 제공하는 주요 메소드는 다음과 같다.
      • setValue(int) // JProgressbar의 값을 지정함
      • getValue() // JProgressbar의 값을 읽음
      • getPercentComplete() // JProgressbar의 값을 백분율로 읽음
    • 아래는 앞에서 소ws개한 JSlider 응용 예제에 ProgressBar의 기능을 추가시킨 것인데, 슬라이더를 움직이면 슬라이더의 현재 값을 읽어 그림의 상단에 있는 JProgressBar에 그대로 나타내고 있다.


    • 위와같은 결과를 얻기 위해 JSlider 예제의 Test 클래스에 추가되는 코드는 다음과 같다.
    JProgressBar jp = new JProgressBar();
    . . .
    public void go() {
    panel.setLayout(new GridLayout(3, 1));
    panel.add(jp);
    . . .
    sd.addChangeListener(new ChangeListener() {
    public void stateChanged(ChangeEvent e) {
    jtf.setText("Position"+sd.getValue());
    jp.setValue(sd.getValue());
    }
    . . .

    JToolBar

    • 툴바(JToolBar)는 메뉴와 유사한 기능을 제공하는 것으로, 화면 상단에 여러 도구상자 등을 나타내는데 사용될 수 있다. JToolBar는 인자 없는 생성자 한 가지만을 제공하고 있다. JToolBar가 제공하는 주요 메소드는 다음과 같다.
      • add(Component c) // 컴포넌트를 툴바에 추가한다
      • addSeparator() // 툴바에 경계선을 추가한다
      • setFloatable(boolean b)// 툴바가 플로팅될 수 있는지를 지정한다
      • isFloatable() // 툴바가 플로팅될 수 있는지 알아본다
    • 툴바는 플로팅 기능을 제공하는데 이것은 화면에 나타난 툴바를 프레임에서 떼어 내어 화면상의 다른 곳으로 이동시킬 수 있는 기능이다. 아래의 좌측 그림은 툴바를 처음 만든 것이고 우측의 그림은 툴바 부분을 프레임에서 떼어 내어 다른 곳으로 움직인 결과이다. 이들을 구현하는 코드를 아래에 나타냈다.

                               

    import javax.swing.*;
    import java.awt.*;
    public class ToolbarTest {
     
    public void go() {
    JPanel panel = new JPanel();
    JToolBar toolbar = new JToolBar();
    toolbar.setLayout(new GridLayout(1,3));
    JButton button1, button2, button3;
    button1 = new JButton(new ImageIcon("duke.gif"));
    button2 = new JButton(new ImageIcon("javalogo.gif"));
    button3 = new JButton("Button !!");
    toolbar.add(button1);
    toolbar.add(button2);
    toolbar.add(button3);
    panel.add(toolbar);
    JFrame frame = new JFrame();
    frame.getContentPane().add(panel,"North");
    frame.getContentPane().add(new JTextArea(),"Center");
    frame.setSize(180,150);
    frame.setVisible(true);
    }
    public static void main(String args[]) {
    new ToolbarTest().go();
    }
    }

    JMenu

    • 스윙에서도 메뉴를 사용하려면 AWT에서와 같이 메뉴바를 먼저 만들고 메뉴를 메뉴바에 추가한 후, 메뉴항목들을 메뉴에 추가하여야 한다. 그러나 스윙의 메뉴 기능은 AWT보다 다양해졌는데, 예를들면 AWT에서와 달리 메뉴를 Panel이나 Applet에서도 사용할 수 있게 하였다(AWT에서는 프레임에만 사용할 수 있었음). 또한 메뉴항목에 텍스트 뿐 아니라 이미지도 넣을 수 있게 하였다.
    • 아래에 그림이 들어있는 메뉴항목을 포함하여, 세개의 메뉴항목이 있는 메뉴를 만든 결과 그림과 이 결과를 얻는 프로그램을 나타냈다.


    import java.awt.*;
    import javax.swing.*;
    public class Test {
    public void go() {
    JFrame frame = new JFrame();
    JMenuBar jmenubar = new JMenuBar();// 메뉴바 생성
    frame.setJMenuBar(jmenubar);// 메뉴바 설치
    JMenu jmenu = new JMenu("Menu Test");// 메뉴 생성
    jmenubar.add(jmenu);// 메뉴 추가
    JMenuItem jm1, jm2, jm3;
    jm1 = new JMenuItem("Text Only");
    jm2 = new JMenuItem("Text and Icon", new
    ImageIcon("javalogo.gif"));
    jm3 = new JMenuItem(new ImageIcon("duke.gif"));
    jmenu.add(jm1);// 메뉴항목 추가
    jmenu.add(jm2);
    jmenu.add(jm3);
    frame.getContentPane().add(new JTextArea(), "Center");
    frame.setSize(200,100);
    frame.setVisible(true);
    }
    public static void main(String args[]) {
    new Test().go();
    }
    }

    JTable

    • 스윙이 제공하는 기능 중 가장 편리한 기능이 아마 테이블(JTable)일 것이다. 특히 온라인으로 데이터베이스 처리를 하고 결과를 테이블 형태로 보여주면 편리한 경우가 많아 JTable이 널리 사용되고 있다.
    • 예를들어 아래의 그림은 4x3의 테이블을 나타내고 있다.


    • 위와같은 테이블을 만드는 코드를 아래에 보였다. 테이블의 내용을 담기 위하여 2차원 어레이를 사용하는데 먼저 4x3 어레이 tableData[4][3]을 정의하고 초기값을 주었다. 다음에 테이블 각 컬럼의 이름을 주기 위하여 스트링 타입의 어레이 column[3]를 만들고 이들을 사용하여 다음과 같이 테이블을 생성하였다.
      • JTable table = new JTable(tableData, column)
    • 아래 프로그램에서는 사용자가 테이블의 어떤 항목을 마우스로 클릭하면 그 항목의 내용을 테이블 상단에 있는 텍스트필드에 출력하도록 하였는데(위 그림에서는 Unix를 선택하고 있음), 이를 처리하기 위하여 MouseListener를 연결하였고 mouseClicked() 메소드를 구현하였다. mouseClicked()에서는 showMe()라는 메소드를 호출하는데 여기서 테이블의 선택된 항목을 읽어 텍스트필드에 출력한다.
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.table.*;
    public class JTableTest {
    Object tableData[][] = {// 테이블 내용
    {new Integer(1), "Java Programming", "Electronics"},
    {new Integer(2), "Socket Programming", "General"},
    {new Integer(3), "Unix", "Enginerring College"},
    {new Integer(4), "Corba Programming", "Graduate school"}
    };
    String column[] = {"Number", "Course", "Department"};
    JTable table;
    JTextField text;
    public void go() {
     
    JPanel panel = new JPanel();
    table = new JTable(tableData, column);// 테이블 생성
    text = new JTextField("");
    JScrollPane scrollPane = new JScrollPane(table);
    panel.setLayout(new BorderLayout());
    panel.add(text, "North");
    panel.add(scrollPane, "Center");
    table.addMouseListener(new MouseAdapter() {// 마우스 리스너
    public void mouseClicked(MouseEvent e) {
    showMe();
    }
    });
    JFrame frame = new JFrame("Table Example");
    frame.getContentPane().add(panel);
    frame.setSize(400, 200);
    frame.setVisible(true);
    }
    private void showMe() {
     
    int numRows = table.getSelectedRow();// row 값을 얻는다
    int numColumns = table.getSelectedColumn();// column 값
    TableModel model = table.getModel();
    text.setText(model.getValueAt(numRows, numColumns).toString());
    }
    public static void main(String args[]) {
     
    new JTableTest().go();
    }
    }

    JTabbedPane

    • JTabbedPane은 아래 그림처럼 여러 pane으로 된 문서에서 특정 탭을 가진 pane을 쉽게 찾아주는 기능을 제공한다(견출지를 붙인 것과 같이). 아래 그림에서 견출지의 역할을 하는 부분을 탭이라고 하는데, 모든 탭은 만들어진 순서대로 index 값을 배정받는다(0부터 시작함). 탭은 스트링 타입의 이름을 가질 수 있다.


    • 프로그램에서 탭의 이름으로 또는 탭의 index로 해당 pane을 찾아낼 수 있으며 사용자가 탭을 마우스로 클릭하면 해당 pane이 전면에 나오도록 선택할 후 있다.
    • 다음은 JTabbedPand의 주요 생성자이다.
      • JTabbedPane()// 탭의 위치가 상단에 옴
      • JTabbedPane(int) // 탭의 위치를 지정함
    • 인자가 없는 생성자는 디폴트로 탭을 상단부에 만들며, 탭을 다른 곳에 두려면 JTabbedPane.BOTTOM, JTabbedPane.LEFT, JTabbedPane.RIGHT 등의 static 변수를 인자로 하여 두번째 생성자를 호출하면 된다.
    • 다음은 JTabbedPane의 주요 메소드이다. 아래에서 탭을 추가하거나 삭제하는 메소드가 있고, 특정 index를 얻는 메소드, 그리고 선택된 탭을 화면에 나타나도록 하는 메소드가 있음을 알 수 있다.
      • addTab(String s, Component c) // 이름이 s인 c 타입의 탭을 추가
      • remove(Component c)// c와 관련된 탭을 삭제
      • removeTabAt(int i) // index i의 탭을 삭제
      • indexOfComponent(Component c)// c와 관련된 탭의 index를 리턴
      • getSelectedIndex()// 현재 선택된 탭의 index를 리턴
      • indexOfTab(String s)// 탭 이름이 s인 탭의 index를 리턴
      • setSelectedIndex(int i)// index i의 탭을 선택
      • setSelectedComponent(Component c) // c와 관련된 탭을 선택
    • 아래의 코드는 위에 보인 그림을 얻는 프로그램인데 사용자가 특정 탭을 마우스로 선택하면 선택된 탭의 pane이 화면에 나타나며 자신의 인덱스 값을 하단의 텍스트필드에 출력하도록 하였다. 이벤트 처리를 위하여 ChangeListener를 연결하였으며 stateChanged() 메소드를 구현하였다.
    import java.awt.*;
    import javax.swing.*;
    import javax.swing.event.*;
    public class Test {
    JTabbedPane tabpane = new JTabbedPane();
    JPanel panel = new JPanel();
    JTextField text = new JTextField();
    public void go() {
    panel.setLayout(new BorderLayout());
    tabpane.addTab("First", // 탭 추가
    new Label("First Tab Pane",Label.CENTER));
    tabpane.addTab("Second",
    new Label("Second Tab Pane",Label.CENTER));
    tabpane.addTab("Third",
    new Label("Third Tab Pane",Label.CENTER));
    tabpane.setSelectedIndex(0);// 첫 탭 지정
    tabpane.addChangeListener(new ChangeListener() { // 리스너
    public void stateChanged(ChangeEvent e) {
    int index = tabpane.getSelectedIndex();
    text.setText("Current index = "+index);
    }
    });
    panel.add(tabpane,"Center");
    panel.add(text,"South");
    JFrame frame = new JFrame("Text Tabs Examples");
    frame.getContentPane().add(panel, "Center");
    frame.setSize(300,300);
    frame.setVisible(true);
    }
    public static void main(String args[]) {
     
    new Test().go();
    }
    }

    JTree

    • 스윙에서는 아래 그림과 같이 트리 구조로 항목들을 나열할 수 있는데 이것은 디렉토리 구조를 표현할 때 많이 사용된다. 트리에 관련된 메소드는 매우 많으나 기본적인 기능만 사용하여도 간단히 트리를 만들 수 있다.


    • 위 그림과 같은 트리를 만드는 코드를 아래에 나타냈다. 먼저 트리의 각 항목을 담을 2차원 어레이 node[][]를 정의하고 초기값을 주었다. 트리는 루트(root) 노드와 서브루트 노드를 중심으로 구성되는데 DefaultMutableTreeNode 클래스를 사용해서 노드들을 만들고 트리의 기본 모델인 DefaultTreeModel을 만든 다음에 이것을 JTree() 생성자의 인자로 주었다.
    import javax.swing.*;
    import javax.swing.tree.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;

    public class Test {
     
    DefaultTreeModel treeModel;// 트리의 디폴트 모델
    JTree tree;
    String subRoot[] = {"OS", "Language"};
    String node[][] = { // 트리의 각 항목 내용
    {"Linux", "Windows NT", "Unix"},
    {"Java", "C++", "BASIC"}
    };
    DefaultMutableTreeNode root, subRootNode;
    public void go() {
    JPanel panel = new JPanel();
    root = new DefaultMutableTreeNode("Root");
    for(int i =0; i
     
    subRootNode = new DefaultMutableTreeNode(subRoot[i]);
    root.add(subRootNode);
    for(int j =0; j < node[i].length; j++) {
    subRootNode.add(new DefaultMutableTreeNode(node[i][j]));
    }
    }
    treeModel = new DefaultTreeModel(root);// 트리 모델 생성
    tree = new JTree(treeModel);// JTree 생성자
    panel.setLayout(new BorderLayout());
    panel.add(new JLabel("Tree Example"));
    panel.add(new JScrollPane(tree), "Center");
    JFrame frame = new JFrame("Tree Example");
    frame.getContentPane().add(panel);
    frame.pack();
    frame.setVisible(true);
    }
    public static void main(String args[]) {
    new Test().go();
    }
    }

    Swing의 Container와 Component

    • Swing에서 Top-level container는 JFrame, JApplet, JDialog, JWindow이다.
    • Swing에서 Light weight component는 앞에 설명한 JButton, JPanel, JMenu, 등등의 component 들이다.
    • Top-level container는 lightweight component가 존재하는 framework을 제공한다. 다시 말해서 top-level Swing Container는 lightweight Swing Component가 그려질 수 잇는 영역을 제공하는 것이다.
    • Top-level container는 container의 heavy weight AWT component의 Swing subclass 이다.
    • 모든 Swing component들은 top-level Swing container를 가지고 있다. 예를 들어 , Swing component를 가지고 있는 모든 Applet은 JApplet( 이것은 java.applet.Applet의 subclass이다.) subclass이다. 비슷하게 Swing component를 가지고 있는 모든 main window는 JFrame으로부터 implement 되어 졌다.
    • 일반적으로 Swing component를 사용하기 위해서는 Swing component 와 Swing Container를 같이 사용해야한다.
    • Swing은 Top-level container에 바로 add 되어질 수가 없고, Top-level container와 연관되어 있는 content pane에 add할 수 있다.
    • contenet pane은 JPanel과 같은 lightweight Swing component이다.

    Swing GUI 예제

    import javax.swing.*;
    import java.awt.*;
    public class SwingGUI{
    JFrame topLevel;
    JPanel jPanel;
    JTextField jTextField;
    JList jList;
    JButton b1;
    JButton b2;
    Container contentPane;
    Object listData[] = {
    new String("First selection"),
    new String("Second selection"),
    new String("Third selection"),
    };
    public static void main(String args[]){
    SwingGUI swingGui =new SwingGUI();
    swingGui.go();
    }
    public void go(){
    topLevel = new JFrame("Swing GUI");
    jPanel = new JPanel();
    jTextField = new JTextField(20);
    jList = new JList(listData);
    contentPane = topLevel.getContentPane();
    contentPane.setLayout(new BorderLayout());
    b1 = new JButton("1");
    b2 = new JButton("2");
    contentPane.add(b1,BorderLayout.NORTH);
    contentPane.add(b2,BorderLayout.SOUTH);
    jPanel.setLayout(new FlowLayout());
    jPanel.add(jTextField);
    jPanel.add(jList);
    contentPane.add(jPanel,BorderLayout.CENTER);
    topLevel.pack();
    topLevel.setVisible(true);
    }
    }

    실행결과



    JComponent Class

    • 모든 Swing component는 JComponent class의 subclass이다.
    • JComponet는 Container class로부터 inherit 되었다. 그리고, Swing Component들을 JComponent의 다음의 기능을 inherit해서 가지고 있다.
    • Borders - setBorder()를 사용하면, 앞에서 예를 들었듯이 component 주위의 edge를 좀더 다르게 나타낼 수 있다.
    • Double Buffering - Swing은 Default로 DoubleBuffering 된다.
    • Tool Tips - setToolTipText()를 사용하면, component의 사용자에게 help를 제공할 수 있다.
    • KeyBoard navigation - registerKeyboardAction()을 사용하면, mouse 대신에 keyboard로 GUI 사이를 이동시킬 수 있다.
    • Application-wide pluggable look and feel - 각각의 Java application runtime은 runtime's Swing의 look and feel을 결정하는 GUIManager object를 가지고 있다. UIManager.setLookAndFeel()를 사용해서 모든 Swing component에 의해서 사용되는 look and feel을 바꿀 수 있다. 그리고 JComponent Object는 ComponentGUI object와 연관되어서 모든 drawing과 event handling, size determination 등을 JComponent에 대해서 수행한다.

    응용예제1

    JFC를 이용한 WordPad를 만들기

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    public class JWordPad extends WindowAdapter implements ActionListener {
     
    JFrame f;
    JMenuBar mb ;
    JMenu mFile;
    JMenuItem miNew,miLoad, miSave,miExit;
    JToolBar toolbar ;
    JButton bNew, bLoad, bSave;
    JTextArea ta;
    public JWordPad(){
     
    f = new JFrame("Word Pad");
    ta = new JTextArea();
    mb = new JMenuBar();
    mb.setForeground(Color.red);
    mFile = new JMenu("File");
    miNew = new JMenuItem("New",new ImageIcon("image/01.jpg"));
    miLoad = new JMenuItem("Open",new ImageIcon("image/02.jpg"));
    miSave = new JMenuItem("Save",new ImageIcon("image/03.jpg"));
    miExit = new JMenuItem("Close",new ImageIcon("image/04.jpg"));
    mFile.add(miNew);
    mFile.add(miLoad);
    mFile.add(miSave);
    mFile.addSeparator();
    mFile.add(miExit);
    mb.add(mFile);
    Container c = f.getContentPane();
    f.setJMenuBar(mb);
    toolbar = new JToolBar();
    toolbar.setLayout(new GridLayout(1,3));
    bNew = new JButton(new ImageIcon("image/04.jpg"));
    bLoad = new JButton(new ImageIcon("image/05.jpg"));
    bSave = new JButton(new ImageIcon("image/06.jpg"));
    bNew.setToolTipText("File New");
    bLoad.setToolTipText("File Loading");
    bSave.setToolTipText("File Saving");
    toolbar.add(bNew);
    toolbar.add(bLoad);
    toolbar.add(bSave);
    c.add(toolbar,"North");
    c.add(ta,"Center");
    f.setSize(400,400);
    f.setVisible(true);
    Listener();
    }
    public void Listener(){
    miLoad.addActionListener(this);
    miSave.addActionListener(this);
    miExit.addActionListener(this);
    f.addWindowListener(this);
    }
    public void windowClosing(WindowEvent e){
    f.dispose();// frame만 종료되고, process 는 종료되지 않는다. applet을 짤때, 좋다.
    System.exit(1);
    }
    public void actionPerformed(ActionEvent e){
    if(e.getSource() == miNew){
    ta.setText("New...");
    }else if(e.getSource() == miLoad){
    ta.setText("Load...");
    }
    else if(e.getSource() == miSave){
    ta.setText("Save...");
    }else if(e.getSource() == miExit){
    //f.dispose();
    System.exit(1);
    }
    }
    public static void main(String args[]){
    JWordPad wp = new JWordPad();
    } // main end
    }// class end

    Level 3 배경색 바꾸는 프로그램

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    public class ColorChange implements ChangeListener{
     
    JPanel panel = new JPanel();
    JTextField jtf = new JTextField(20);
    JSlider redSlider, blueSlider, greenSlider;
    Canvas can ;
    int R,G,B;
    void go(){
    JFrame f = new JFrame("Color Change");
    Container c = f.getContentPane();
    JPanel contPanel = new JPanel();
    contPanel.setLayout(new GridLayout(1,3));
    redSlider = new JSlider(JSlider.VERTICAL, 0, 255, 60);
    redSlider.setMajorTickSpacing(20);
    redSlider.setMinorTickSpacing(5);
    redSlider.setPaintTicks(true);
    redSlider.setPaintLabels(true);
    redSlider.addChangeListener(this);
    blueSlider = new JSlider(JSlider.VERTICAL, 0, 255, 60);
    blueSlider.setMajorTickSpacing(20);
    blueSlider.setMinorTickSpacing(5);
    blueSlider.setPaintTicks(true);
    blueSlider.setPaintLabels(true);
    blueSlider.addChangeListener(this);
    greenSlider =new JSlider(JSlider.VERTICAL, 0, 255, 60);
    greenSlider.setMajorTickSpacing(20);
    greenSlider.setMinorTickSpacing(5);
    greenSlider.setPaintTicks(true);
    greenSlider.setPaintLabels(true);
    greenSlider.addChangeListener(this);
    contPanel.add(redSlider);
    contPanel.add(blueSlider);
    contPanel.add(greenSlider);
    c.add(contPanel,"East");
    can = new Canvas();
    c.add(can,"Center");
    R=10;
    G=10;
    B=10;
    can.setBackground(new Color(R,G,B));
    f.setSize(400,400);
    f.setVisible(true);
    }
    public void stateChanged(ChangeEvent e) {
    if(e.getSource() == redSlider){
    R = redSlider.getValue();
    can.setBackground(new Color(R,G,B));
    can.repaint();
    }else if(e.getSource() == blueSlider){
    B = blueSlider.getValue();
    can.setBackground(new Color(R,G,B));
    can.repaint();
    }else if(e.getSource() == greenSlider){
    G = greenSlider.getValue();
    can.setBackground(new Color(R,G,B));
    can.repaint();
    }
    }
    public static void main(String args[]){
    new ColorChange().go();
    }
    }

    'My work space > Java' 카테고리의 다른 글

    AWT/SWING 성능 비교(기본 출력 기능)  (0) 2008.08.20
    소켓(Socket)  (0) 2008.08.20
    AWT란  (0) 2008.08.20
    awt와 swing의 차이점  (0) 2008.08.20
    Basic Java - Swing  (0) 2008.08.14