반응형

1. 개요

Elastic에서 elasticsearch를 저장공간으로하여 다양한 제품들이 출시되고 있는데 그중에 beats 들을 이용하면 다소 귀찮은 일들을 손쉽게 처리할 수 있다.

이번 포스팅에서는 많은 beats 들 중 자원들을 모니터링 해주는 metric beat에 대해 설치해보고 결과화면을 확인해 보고자 한다.

2. 준비물

- elasticsearch

- kibana

- metric beat

* 버전은 최신버전 (6.1)을 기준으로 작성한다.

* 다운로드 : https://www.elastic.co/downloads/beats/metricbeat

* 필자는 ubuntu를 사용하고 있음으로 linux-64 bit 버전을 다운받았다.

3. 실행

- 다운로드 받은 파일을 설치하거나 압축을 풀고 실행해야한다.

- metric beat은 elasticsearch에 데이터를 저장해야하기 때문에 먼저 elasticsearch와 kibana를 실행해준다.

- elasticsearch

/home/user/work/elastic/bin/> ./elasticsearch -d

- kibana

/home/user/work/elastic/bin/> ./kibana

- metric beat

- kibana에 saved search와 dashboard를 추가하기 위해 setup을 먼저 해준다.

/home/user/work/metricbeat/> ./metricbeat setup -e

- 실행

/home/user/work/metricbeat/> ./metricbeat -c metricbeat.yml -e

4. 확인

문제없이 모든 데몬을 실행시켰다면 metricbeat이 모니터링하는 정보를 확인할 수 있다.

- metricbeat이 전송하는 데이터

2018/01/19 05:27:32.333111 metrics.go:39: INFO Non-zero metrics in the last 30s: beat.info.uptime.ms=30000 beat.memstats.gc_next=5994816 beat.memstats.memory_alloc=3678176 beat.memstats.memory_total=1336843960 libbeat.config.module.running=3 libbeat.output.read.bytes=9085 libbeat.output.write.bytes=29844 libbeat.pipeline.clients=6 libbeat.pipeline.events.active=0 libbeat.pipeline.events.published=45 libbeat.pipeline.events.total=45 libbeat.pipeline.queue.acked=45 metricbeat.system.cpu.events=3 metricbeat.system.cpu.success=3 metricbeat.system.load.events=3 metricbeat.system.load.success=3 metricbeat.system.memory.events=3 metricbeat.system.memory.success=3 metricbeat.system.network.events=12 metricbeat.system.network.success=12 metricbeat.system.process.events=21 metricbeat.system.process.success=21 metricbeat.system.process_summary.events=3 metricbeat.system.process_summary.success=3
2018/01/19 05:28:02.333097 metrics.go:39: INFO Non-zero metrics in the last 30s: beat.info.uptime.ms=30000 beat.memstats.gc_next=4847104 beat.memstats.memory_alloc=3440536 beat.memstats.memory_total=1355945168 libbeat.config.module.running=3 libbeat.output.read.bytes=9883 libbeat.output.write.bytes=31932 libbeat.pipeline.clients=6 libbeat.pipeline.events.active=0 libbeat.pipeline.events.published=49 libbeat.pipeline.events.total=49 libbeat.pipeline.queue.acked=49 metricbeat.system.cpu.events=3 metricbeat.system.cpu.success=3 metricbeat.system.filesystem.events=2 metricbeat.system.filesystem.success=2 metricbeat.system.fsstat.events=1 metricbeat.system.fsstat.success=1 metricbeat.system.load.events=3 metricbeat.system.load.success=3 metricbeat.system.memory.events=3 metricbeat.system.memory.success=3 metricbeat.system.network.events=12 metricbeat.system.network.success=12 metricbeat.system.process.events=22 metricbeat.system.process.success=22 metricbeat.system.process_summary.events=3 metricbeat.system.process_summary.success=3
2018/01/19 05:28:32.333110 metrics.go:39: INFO Non-zero metrics in the last 30s: beat.info.uptime.ms=30000 beat.memstats.gc_next=4612032 beat.memstats.memory_alloc=2717080 beat.memstats.memory_total=1374846424 libbeat.config.module.running=3 libbeat.output.read.bytes=9085 libbeat.output.write.bytes=29805 libbeat.pipeline.clients=6 libbeat.pipeline.events.active=0 libbeat.pipeline.events.published=45 libbeat.pipeline.events.total=45 libbeat.pipeline.queue.acked=45 metricbeat.system.cpu.events=3 metricbeat.system.cpu.success=3 metricbeat.system.load.events=3 metricbeat.system.load.success=3 metricbeat.system.memory.events=3 metricbeat.system.memory.success=3 metricbeat.system.network.events=12 metricbeat.system.network.success=12 metricbeat.system.process.events=21 metricbeat.system.process.success=21 metricbeat.system.process_summary.events=3 metricbeat.system.process_summary.success=3
2018/01/19 05:29:02.333105 metrics.go:39: INFO Non-zero metrics in the last 30s: beat.info.uptime.ms=30000 beat.memstats.gc_next=5296112 beat.memstats.memory_alloc=3262032 beat.memstats.memory_total=1394037504 libbeat.config.module.running=3 libbeat.output.read.bytes=9884 libbeat.output.write.bytes=31872 libbeat.pipeline.clients=6 libbeat.pipeline.events.active=0 libbeat.pipeline.events.published=49 libbeat.pipeline.events.total=49 libbeat.pipeline.queue.acked=49 metricbeat.system.cpu.events=3 metricbeat.system.cpu.success=3 metricbeat.system.filesystem.events=2 metricbeat.system.filesystem.success=2 metricbeat.system.fsstat.events=1 metricbeat.system.fsstat.success=1 metricbeat.system.load.events=3 metricbeat.system.load.success=3 metricbeat.system.memory.events=3 metricbeat.system.memory.success=3 metricbeat.system.network.events=12 metricbeat.system.network.success=12 metricbeat.system.process.events=22 metricbeat.system.process.success=22 metricbeat.system.process_summary.events=3 metricbeat.system.process_summary.success=3

- kibana

-- kibana의 config 를 수정하지 않았다면 http://localhost:5601 로 접속을 할 수 있을것이다. 

- 상기 캡쳐는 host overview 대시보드를 캡쳐한것이다. 시스템의 자원 상황을 확인할 수 있다.

- 기타 docker, apache, mongo db, mysql 등 사용하고 있는 서비스 별로 전용 over view가 제공되니 해당 서비스를 사용하고 있으면 손쉽게 모니터링 대시보드를 구성할 수 있다.

반응형
반응형

때로는 select 쿼리에 where in 조건순으로 정렬을 해야할때가 있다.

이때 order by 식으로 심플하게 위 상황을 출력할 수 있다.


예)

SELECT * FROM TABLE

WHERE COLUMN IN ('A', 'B', 'C')

ORDER BY FIELD(COLUMN, 'A', 'B', 'C')


MYSQL 기능은 진짜 무궁무진한듯....

반응형
반응형

크롬에서 특정 언어의 단어를 발견하면 자동번역 기능을 제공한다.

크롬에서 자체적으로 끄면 나오지 않겠지만

그렇지 않은 사용자들의 경우에는 도움이 될수도 있겠지만 번역을 제공받고 싶지 않은 사용자에겐 귀찮을 수 있다.

해당 사이트에서 그런 옵션을 막는 옵션이 메타태그로 존재한다.


<meta name="google" value="notranslate">


html의 header 부분에 추가해주면 더이상 자동번역 팝업이 뜨지 않는다.

반응형
반응형

웹 ui 설계 관련 툴을 찾다가 발견한 balsamiq mockup 

adobe air 기반의 설치형 어플리케이션이며 다운로드는 http://balsamiq.com/ 여기서 받을 수 있다.

먼저 사용 동영상을 먼저 보도록 하자.




위 동영상과 같이 웹 ui를 손쉽게 설정할 수 있다.

더 좋은 점은 웹 뿐만 아니라 일반 어플리케이션, 아이폰까지도 포괄적으로 설계할 수 있다.
 
 



괜찮다 싶어 설치를 했는데 데모버전이며 7일밖에 사용하지 못한다.

그러나 라이센스를 발급받을 수 있는 방법이 있다.

If you are a blogger / journalist / maven willing to write us up (honest reviews are the most useful to us) email Mariah a short blurb with the link to your blog and she'll send you a license, FREE of charge, so that you can evaluate Mockups properly.

블로거일 경우 블로그에 정직한 리뷰를 작성하여 메일을 보내면 라이센스를 준다고 한다.

아직 나도 블로그를 작성중이니 라이센스를 받은건 아니지만 -_-; 라이센스를 받기위해 글을 쓰고 있다고 보면 된다..

웹 ui 설계 프로그램을 찾던 사람은 제법 반가운 프로그램일거라 생각이 든다.

반응형
반응형

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <TITLE> Navigator 객체 </TITLE>
</HEAD>

 <BODY>
 <Font size=4>
 <Script Language="JavaScript">
 <!--
 document.write("[1] 브라우저 이름 : ", navigator.appName, "<BR>");
 // 브라우저 인식용으로 많이 사용됩니다.
 document.write("[2] 이름/버전 이름 : ", navigator.userAgent, "<BR>");
 document.write("[3] 버전 : ", navigator.appVersion, "<BR>");
 document.write("[4] 코드 : ", navigator.appCodeName, "<BR>");
 document.write("[5] 언어 : ", navigator.language, "<BR>");
 document.write("[6] 시스템 환경 : ", navigator.platform, "<BR>");
 document.write("[7] 스크립트 가능 유무 : ", navigator.javaEnabled(), "<BR>");
 document.write("[8] 오류 유무 : ", navigator.taintEnabled(), "<BR>");
 -->
 </Script>
 </Font>
 </BODY>
</HTML>

반응형
반응형

여러곳에 올라와 있는데, 원본의 주소는 알수가 없었다..


Writter by Youngil Kim, C#.NET Developer  

이번에는 WinForm에서 제공하는 DataGridView컨트롤을 사용해보는 컬럼을 마련해 보았습니다. 일단 간단하게 VS2005에서 Windows 응용프로그램 프로젝트를 하나 만들고 윈폼화면에 DataGridView컨트롤 배치시키고 마음에 드는 사이즈로 만드세요! ^^ 

여기서 사용하는 데이터베이스는 SQL Server 2005에서 새롭게 제공하는 Advanture Works 샘플DB의 Store테이블의 데이터를 가지고 설명하겠습니다.(다른 DB를 사용하시는 분들은 알아서 맞추시면 되요 ^^;) 데이터 연결된 소스부분은 같이 첨부한 샘플소스를 참고해주세요 ^^; 

<컨트롤 속성>

DataGridView ID: dbView


1. 홀수행을 다른 색으로 보여주고 싶을 때

행마다 특정 배경색을 입혀보고 싶은 분들은 다음과 같이 구현하시면 됩니다. 일단 홀수행을 기준으로 설명하자면 AlternatiogRowsDefaultCellStyle속성에 BackColor를 선언하여 색상을 지정하시면 됩니다. 

dbView.AlternatingRowsDefaultCellStyle.BackColor = Color.Aqua; 


2. 여러개의 열이나 행을 선택하지 못하도록 막고 싶을 때

기본적으로 여러개의 열과 행을 선택할 수 있는데 이를 막고 한개의 열이나 한개의 행만 선택하도록 하고 싶을 때 다음과 같이 선언하면 됩니다. 

dbView.MultiSelect = false;
 

3. 행단위로 클릭하도록 만들고 싶을 때

기본적으로 열단위로 클릭하도록 처리되어 있는데 이를 행단위로 클릭할 수 있는 기능도 있습니다. 이 기능은 SelectionMode속성에 DataGridViewSelectionMode.FullRowSelect를 설정하면 간단하게 됩니다. 

dbView.SelectionMode = DataGridViewSelectMode.FullRowSelect;

 

참고로 DataGridViewSelectMode열거체이외의 값도 설정하여 열단위로 선택기능을 구현할 수 있고 열단위로 선택기능을 사용시 각 열에 대한 SortMode속성이 Automatic값(기본)으로 설정이 안되어 있으면 사용할 수 없습니다.
 

4. 행번호 보여주고 싶을 때

각 행의 행번호를 보여주고 싶을 때에는 행을 화면에 보여주는 타이밍인 RowPostPaint이벤트 타이밍에 그 행의 인덱스번호+1형태로 행헤더의 열 안에 넣어주면 끝납니다.

RowPostPaint이벤트핸들러의 2번째 파라미터인 DataGridViewRowPostPaintEventArgs 객체로부터 보여주기 위해 필요한 Graphics객체나 좌표값을 얻을 수 있습니다.

이하 e변수로 받을 수 있는 객체에 대해서 알아보면 다음과 같습니다. 

<DataGridViewRowPostPaintEventArgs 객체>
  * e.Graphics - Graphics객체
  * e.RowIndex - 표시중인 행번호 (0부터 시작하기 떄문에 +1필요) 
  * e.RowBounds.X 행헤더 열 왼쪽 위 X좌표
  * e.RowBounds.Y 행헤더 열 왼쪽 위 Y좌표
  * e.RowBounds.Height 행헤더 열높이
  * dbView.RowHeadersWidth 행헤더 셀 폭
  * dbView.RowHeadersDefaultCellStyle.Font 사용폰트
  * dbView.RowHeadersDefaultCellStyle.FontColor 폰트 색상
  
private void dbView_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e) {

     // RowPointPaint 이벤트핸들러
     // 행헤더 열영역에 행번호를 보여주기 위해 장방형으로 처리
     Rectangle rect = new Rectangle(e.RowBounds.Location.X,

                         e.RowBounds.Location.Y,

                         dbView.RowHeadersWidth - 4,

                         e.RowBounds.Height);
     // 위에서 생성된 장방형내에 행번호를 보여주고 폰트색상 및 배경을 설정
     TextRenderer.DrawText(e.Graphics,

                         (e.RowIndex + 1).ToString(), 

                         dbView.RowHeadersDefaultCellStyle.Font,

                         rect,  

                         dbView.RowHeadersDefaultCellStyle.ForeColor,

                         TextFormatFlags.VerticalCenter | TextFormatFlags.Right);

}

 

5. 특정 행이나 열을 고정시키고 스크롤하지 못하도록 막고 싶을 때

여기서는 2번째 열을 고정시킨 경우를 보여주고 있는데 그리드를 옆으로 스크롤 할 경우 3번째 열보다 우측의 스크롤이 나오고 1번째열과 2번째열은 고정된 형태를 보여줍니다. 

- Frozen 속성 : 열 고정시키기 위한 속성으로 이를 고정시키기 위한 열을 지정하고 true값을 선언하면 해당 열의 좌측 열은 전부 고정되어 스크롤 할 없게 됩니다. 

dbView.Columns[1].Frozen = true; 

- DividerWidth 속성 : 구분선 폭 변경을 할 때 사용하는 속성으로서 이를 통해서 2번째열과 3번째열 사이 구분선을 약간 두껍게 표현하여 보다 직관적으로 구분할 수 있습니다. 

dbView.Columns[1].DividerWidth = 3;

 

6. 그리드 실행될 때 기본 열이 선택된 모습을 보여주고 싶지 않을 때

아주 간단하게 속성하나만 선언하면 되는데 이때 주의해야할 점은 폼_Load이벤트핸들러에서는 효과가 없다는 것입니다. 어느 열도 선택되지 않는 상태로 보여주기 위해서는 폼이 표시된 이후 한번만 발생하는 폼_Shown 이벤트핸들러에서 선언해주는 것이 좋습니다. 

        private void Form1_Shown(object sender, EventArgs e)
        {
            //6. 그리드 실행될 때 기본 열이 선택된 모습을 보여주고 싶지 않을 때
            dbView.CurrentCell = null;
        }

 

7. 특정값을 가진 열을 좀 다르게 보여주고 싶을 때

특정값을 가진 열을 좀더 강조하여 보여주고 싶은 경우가 종종 생깁니다. 이럴 때 유용한 것으로 예제에서는 Bike란 단어가 포함된 열인 경우 빨간색으로 글씨를 보여주도록 설정하였습니다.

특히, 개별적인 열에 대해서 보여주기 위해서는 폼_CellFormating이벤트핸들러를 이용하면 될것같습니다. 본래 이 이벤트핸들러는 특정값을 가진 열의 독립적인 서식을 적용하기 위한 것으로 열 스타일만 변경할 수 있습니다.

CellFormmating이벤트핸들러의 2번째파라미터로 받는 DataGridViewCellFormattingEventArgs객체로부터 그 열의 현재 스타일이나 열의 값을 얻거나 설정할 수 있습니다. 즉, 이것을 통해 열의 값을 확인하고 그 스타일을 변경하는 형태로 개발을 해보려고 합니다. 또한, 이벤트 발생시 열위치는 ColumnIndex속성과 RowIndex속성으로 알 수 있습니다. 

private void dbView_CellFormatting(object sender,

DataGridViewCellFormattingEventArgs e) {
{
      // 7. 특정값을 가진 열을 좀 다르게 보여주고 싶을 때
      if (e.ColumnIndex == 1)
      {
            if (e.Value != null)
            {
                 string text = e.Value.ToString();
                 if (text.Contains("Bike"))
                 {
                      e.CellStyle.ForeColor = Color.Red;
                      e.CellStyle.SelectionForeColor = Color.Red;
                  }
              }
         }
  }

 

8. 헤더열이나 헤더행의 색을 변경하고 싶을 때

헤더행과 헤더열의 색을 변경하고싶은 경우에는 ColumnHeadersDefaultCellStyle속성과 RowHeadersDefaultCellStyle속성을 사용하면 괜찮을 것같습니다. 

dbView.ColumnHeadersDefaultCellStyle.BackColor = Color.RosyBrown;
dbView.RowHeadersDefaultCellStyle.BackColor = Color.SeaGreen; 

단, 위와 같이 선언하여도 그것이 사용할 수 없는 경우가 있는데 이것은 애플리케이션이 적용하고 있는 Windows XP의 Visual 스타일을 우선적으로 사용하기 때문인데 이 코드는 윈폼을 만들 때 자동으로생성하기 때문에 Application클래스의 EnableVisualStyles메소드를 호출합니다. 

dbView.EnableHeadersVisualStyles = false; 

그외 열과 행의 사이에 있는 선스타일을 변경할 수 있는데 다음과 같이 선언하게 되면 한개의 라인으로 보여주게 됩니다. 

dbView.RowHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
dbView.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;

 

9. 선택한 행이나 열에 대한 값을 확인하고 싶을 때

보통 특정 행을 추가하거나 삭제하고 편집도 하는데 이럴 때 선택된 행이나 열에 대해서 어떤 조작을 하는 경우도 많습니다. 그래서 이번에는 이를 간단하게 처리하는 방법에 대해서 정리해보았습니다. 이 부분에 대한 것을 사용형태만 설명하고 넘어가겟습니다. 

아래에서 설명한 것들중에서 같은 클래스명이나 속성명이 Row가 들어가거나 Column이란 단어로 비교되는 것을 알 수 있는데 이것에 의해 열에 대한 행과 똑같은 조작을 할 수 있다는 것을 알 수 있습니다. 

- 선택된 열 얻기 : SelectedCells 속성

현재 선택된 열은 SelectedCells속성으로 얻을 수 있고 그리드에서 여러개의 열을 동시에 선택할 수 있기 때문에 이 속성은 DataGridViewSelectedCellCollection클래스 객체로 되어 잇습니다. 여기서는 간단하게 하나의 열을 조작할 경우에 사용되는 형태를 보여줍니다. 

foreach (DataGridViewCell cell in dbView.SelectedCells) { } 

선택된 열 갯수 얻기을 얻어 위에서선택된 열을 얻을 수 있는 방법도 있습니다.

 SelectedCells.Count

for(int i=0; i<dbView.SelectedCells.Count; i++) { } 

또한 MultiSelect속성을 false를 설정한 것은 사용자가 여러개의 행/열을 선택할 수 있도록 할 수 있습니다. 

- 선택된 행 얻기 : SelectedRows 속성

행을 선택하여 행정보를 얻는 경우에 필요한 것으로 DataGridViewRow클래스의 객체의 컬렉션은 Selectedows속성으로 얻을 수 있습니다. 

foreach(DataGridViewRow row in dbView.SelectedRows) { } 

- 특정 셀이나 행이 선택되었는지 확인하는 경우 : Selected 속성

셀이 선택되었다면 true, 셀이 선택되지 않았다면 false로 결과를 보내줍니다. 

dbView[x,y].Selected; 

특정 행이 선택되었는지 확인하는 경우 

dbView.Rows[n].Selected; 

- 선택된 행이나 열 설정

데이터 새로고침등의 이벤트로 인해 데이터를 새롭게 보여줄때 현재 위치를 나타내고 싶은 경우에 필요한 것으로 (x,y)위치에 있는 열을 선택한 상태로 두고 싶다면 다음과 같이 선언합니다. 

dbView[x,y].Selected = true; 

n행의 행을 선택한 상태로 두고 싶은 경우에는 아래와 같이 선언합니다. 

dbView.Rows[n].Selected = true; 

- 모든 선택된 열을 지울 때 : ClearSelection 메소드

 

10. 열에 보여지는 문자열을 여러행으로 보여주고 싶을 때

열에 표시되는 문자열이 길게 되면 한줄로 보여주지만 오버되면 잘려서 안보여줍니다. 이는 열스타일의 WrapMode속성을 DataGridViewTriState.True(그외 False, NotSet)로 설정하여 셀크기안에서 오버되면 여러행으로 해당 텍스트등을 모두 보여줍니다.

그리드안의 모든 열을 여러행을 보여주고 싶다면, DefaultCellStyle속성의 WrapMode속성에 DataGridViewTriState.True를 설정하는 것을 권장합니다. 이렇게하면 정말 간단하게 구현이 됩니다. ^^

또한, 다음줄로 넘어간 문자열이 발생하면 행의 높이는 자동으로 조절되는데 AutoSizeRowMode속성에 DataGridViewAutoSizeRowsMode.AllCells를 설정할 것을 권장합니다. 이상 이 두가지를 정리하면 다음과 같습니다. 

dbView.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
dbView.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;

 

11. 맨 밑까지 스크롤하고 싶을 때

보통 맨 밑에 있는 행을 합계로 보여주거나 응용프로그램 실행시 곧바로 사용자가 새 행을 추가할 있도록 하는 경우가 있는데 이럴때 그리드 맨밑까지 스크롤을 가볍게 해줄 필요가 있습니다. 열단위 표시를 스크롤하기 위한 속성이 3가지가 있는데 다음과 같습니다. 

<속성>

FirstDisplayedCell 그리드 왼쪽 위에 표시된 열 얻기/설정

FirstDisplayedScrollingColumnIndex 그리드에 표시된 처음 열 얻기/설정

FirstDisplayedScrollingRowIndex 그리에 표시된 처음 행 얻기/설정 

예를 들어 [2,15]의 위치에 있는 열을 FirstDisplayedCell속성으로 설정하면 [2,15]위치의 열에 왼쪽위로 그리드가 스크롤된 상태로 보여집니다. 

dbView.FirstDisplayedCell = dbView[2,15]; 

마지막 행을 표시하기 위해 그리드 맨밑까지 스크롤시키려면 FirstDisplayedScrollingRowIndex속성을 이용하길 권장합니다. 

dbView.FirstDisplayedScrollingRowIndex = dbView.Rows.Count - 1;

 

12. 오토컴플릿 기능을 사용하고 싶을 때

텍스트박스 열은 열 편집 및 새 행을 추가시 텍스트박스를 사용합니다. 이럴때 열편집시 오토컴플릿 기능을 사용할 수 있다는 점입니다.

이는 열이 편집상태가 될 때 발생하는 EditingControlShowing이벤트핸들러가 발생할 때 보여주고 있는 텍스트박스 객체를 얻어 오토컴플릿에 필요한 속성을 설장하는 형태입니다.

실제 이 텍스트박스는 DataGridViewTextBoxEditingControl 클래스의 인스턴스를 만들어 TextBox클래스의 파생클래스로서 TextBox형으로 케스팅합니다.

이렇게 예고로 내놓은 코드는 모든 텍스트박스에 대한 오토컴플릿기능을 설정하고 있기 때문에 어느 열을 사용하더라도 오토컴플릿기능이 작동되며 특정열만 오토컴플릿 기능을 지정할 수도 있습니다. 이 예제에서는  

 private void dbView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
 {
        TextBox tb = e.Control as TextBox;
        if (tb == null)
        {
             return;
         }
        if (dbView.CurrentCell.ColumnIndex == 1)
        {
             tb.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
             tb.AutoCompleteSource = AutoCompleteSource.AllSystemSources;
         }
         else
         {
             tb.AutoCompleteMode = AutoCompleteMode.None;
         }
  }  

 

13. 열안에 문자열 선택하고 싶을 때

열 안에의 문자열을 선택하여 처리하고 싶다면 BeginEdit메소드를 사용하는 것을 권장합니다. 이 이름처럼 열을 편집하기 위한 것으로 파라미터값을 true로 선언하면 열 안의 문자열이 선택된 상태로 편집할 수 있습니다. 만약 false로 선언하면 커서가 문자열은 선택하지 않고 문자열끝에 커서가 있는 상태로 조작을 할 수 있습니다. 

 // 폼_Load이벤트핸들러가 BeginEdit를 호출할 경우 폼을 먼저 표시할 필요가 있음
 this.Show();
 // 2행 1열 열을 현재 열로 지정
 dbView.CurrentCell = dbView[0, 1];
 // 현재 열을 편집상태로
 dbView.BeginEdit(true);

 

14. 왼쪽 윗 빈 열에 값 설정하고 싶을 때

왼쪽 맨 윗열은 항상 빈 여백의 열로 남아 있는데 여기에 특정한 표시를 나타내기 위해 값을 넣거나 열 스타일을 변경할 수 있습니다.

이 빈열은 DataGridView컨트롤의 TopLeftHeaderCell속성으로 접근할 수 있고 이 속성값은 헤더 행이나 헤더 열과 동일한 DataGridViewHeaderCell클래스의 객체입니다. 일반적인 열을 나타내는 DataGridViewCell클래스를 상속받은 클래스입니다. 

dbView.TopLeftHeaderCell.Value = "매장";

 

15. 오른쪽버튼 클릭시 열 선택을 할 수 있도록 하고 싶을 때

기본적으로 마우스 오른쪽버튼으로 클릭시 어떠한 조작도 제어되지 않습니다. 그래서 간단하게 클릭시 열을 선택할 수 있도록 하는 방법을 추가해보고자 합니다.

이는 CellMouseClick이벤트핸들러를 생성하여 열을 클릭시 Control클래스로 정의되어 있는 MouseClick이벤트가 추가되어 CellMouseClick이벤트핸들러가 발생하는 형태입니다. 이 이벤트핸들러의 파라미터로는 클릭된 열의 행번호와 열번호를 얻을 있어 클릭되어 진 열을 간단하게 접근하실 수 있습니다.

여기서 보여주는 스타일은 이벤트핸들러를 통해 클릭된 열의 선택상태를 알려주는 것을 아주 간단합니다. 

 private void dbView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
      //오른쪽 버튼 클릭인가?
      if (e.Button == MouseButtons.Right) {
           // 헤더 이외의 열
          if (e.ColumnIndex >= 0 && e.RowIndex >= 0) {
               // 오른쪽 버튼 클릭된 열
               DataGridViewCell cell = dbView[e.ColumnIndex, e.RowIndex];
               cell.Selected = !cell.Selected; // 선택상태 반전
           }
      }

  }  

한가지더 알려드리자면, 두번째 파라미터 DataGridViewCellMouseEventArgs클래스는 MouseClick이벤트핸들러의 파라미터인 MouseEventArgs클래스의 파생클래스입니다. 이 클래스는 마우스의 위치나 클릭된 버튼 종류를 알려주며 클릭된 열의 행번호와 열번호를 리턴해주는 RowIndex속성과 ColumnIndex속성이 추가되어 있고 헤더용 열이나 행이 클릭된 경우 속성은 -1로 처리됩니다.

 

16. 행 삭제시 확인메세지를 보여주고 싶을 때

행을 선택하고 Del키를 누르면 행을 삭제할 수 있습니다. 이럴 때 행의 삭제시 확인 메세지박스를 보여주는 형태를 구현하고 싶은 분들이 있을 것입니다. 이를 한번 구현해보이도록 하겠습니다.

DataGridView컨트롤에서는 행이 삭제될 때 UserDeletingRow이벤트핸들러가 발생합니다. 따라서 이 타이밍에 확인 메세지박스를 보여주는 것을 좋을 것같습니다. 그리고 한가지 팁으로 여러개의 행을 선택하고 Del키를 누르면 선택되어 있는 각 행별로 UserDeletingRow이벤트핸들러가 발생합니다.

또한 이 UserDeletingRow이벤트핸들러의 두번째 파라미터는 DataGridViewRowCancelEventArgs객체의 Cancel속성을 true로 설정하여 행삭제를 취소할 수 있습니다. 

private void dbView_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e) {
       if (MessageBox.Show("삭제하시겠습니까?",

                                 "지정한 행삭제",

                                 MessageBoxButtons.YesNo) == DialogResult.No)
       {
             e.Cancel = true; //삭제 취소
       }
 }  

 

17. 열 순서를 마음대로 바꾸고 싶을 때

가끔 고객의 요구로 인해 열을 사용자가 원하는 순서대로 배치하고 싶은 경우가 나옵니다. 이럴때 이런 기능을 모르면 대략 난감했죠 ㅜ_ㅜ; 근데 DataGridView에서는 간단하게 되네요 ^^; 보통 열 순서변경은 마우스로 열 헤더를 드래그&드롭하여 처리할 수 있습니다.

AllowUserToOrderColumns속성을 true로 하면 간단하게 끝납니다. ㅡ_ㅡ;;; 

dbView.AllowUserToOrderColumns = true; 

반응형
반응형

출처 : http://support.microsoft.com/kb/307548/ko




본 문서에서는 XmlTextReader 클래스를 사용하여 파일에서 XML(eXtensible Markup Language)을 읽는 방법을 설명합니다. XmlTextReader 클래스는 XML에 대한 직접 구문 분석과 토큰화 기능을 제공하고 W3C(World Wide Web Consortium)의 XML 네임스페이스에 대한 사양뿐 아니라 XML 1.0 사양도 구현합니다. 본 문서에서는 XML 문서 개체 모델(DOM) 등의 개체 모델을 사용하는 대신에 XML에 대해 토큰화된 고속 스트림 액세스를 제공합니다.

 

요구 사항

다음은 권장 하드웨어, 소프트웨어, 네트워크 인프라 및 서비스 팩입니다.
  • Microsoft Visual Studio .NET
이 문서는 사용자가 다음 항목을 잘 알고 있다고 가정합니다.
  • XML 용어
  • XML 파일 만들기 및 읽기
 

파일에서 XML을 읽는 방법

이 예에서 사용할 Books.xml이라는 파일은 직접 만들어 사용하거나 .NET Software Development Kit(SDK) QuickStarts의 다음 위치에 있는 예제 파일을 사용할 수 있습니다.
\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\Samples\QuickStart\Howto\Samples\Xml\Transformxml\Cs
이 프로젝트를 만드는 폴더의 하위 폴더인 \Bin\Debug에 Books.xml을 복사해야 합니다. 또한 Books.xml을 다운로드할 수도 있습니다. 다운로드 위치는 참조 절을 참조하십시오.
  1. Visual Studio .NET을 엽니다.
  2. 새로운 Visual C# .NET 콘솔 응용 프로그램을 만듭니다. 전체 코드 예제 절로 직접 이동하거나 이 절차를 계속 수행하여 응용 프로그램을 빌드할 수 있습니다.
  3. System.Xml.dll 어셈블리에 대한 참조가 프로젝트에 포함되어 있는지 확인합니다.
  4. System.xml 네임스페이스에 using 지시문을 지정합니다. 그러면 나중에 코드에서 XmlTextReader 선언을 한정하지 않아도 됩니다. using 지시문은 항상 선언 앞에 사용해야 합니다.
    using System.Xml;
  5. XmlTextReader 개체의 인스턴스를 생성하고 XML 파일로 채웁니다. 대개 XmlTextReader 클래스는 DOM의 오버헤드 없이 XML을 원시 데이터로 액세스해야 할 경우에 사용됩니다. 따라서 XmlTextReader 클래스는 XML을 빠르게 읽을 수 있는 메커니즘을 제공합니다. XmlTextReader 클래스에는 XML 데이터의 위치를 지정하는 다른 생성자가 있습니다. 다음 코드에서는 XmlTextReader 클래스의 인스턴스를 만들고 Books.xml 파일을 로드합니다. Class1의 Main 프로시저에 다음 코드를 추가합니다.
    XmlTextReader reader = new XmlTextReader ("books.xml");
  6. XML을 읽습니다. 이 단계에서는 외부 "While" 루프를 보여주고, 다음 두 단계에서는 외부 "While" 루프를 사용하여 XML을 읽는 방법을 보여줍니다. XmlTextReader 개체를 생성했으면 Read 메서드를 사용하여 XML 데이터를 읽습니다. Read 메서드는 XML 파일을 순차적으로 계속 읽다가 파일 끝에 도달하면 "거짓(False)" 값을 반환합니다.
    while (reader.Read()) 
    {
        // Do some work here on the data.
    	Console.WriteLine(reader.Name);
    }
    Console.ReadLine();
  7. 노드를 검사합니다. XML 데이터를 처리하기 위해 각 레코드마다 하나의 노드 종류를 갖는데, 이 노드 종류는 NodeType 속성에서 결정할 수 있습니다. NameValue 속성은 현재 노드(또는 레코드)의 노드 이름(요소와 특성 이름)과 노드 값(노드 텍스트)을 반환합니다. NodeType 열거는 노드 종류를 결정합니다. 다음 코드 예제에서는 요소 이름과 문서 종류를 표시합니다. 이 예제에서는 요소 특성이 무시됩니다.
    while (reader.Read()) 
    {
        switch (reader.NodeType) 
        {
            case XmlNodeType.Element: // The node is an element.
                Console.Write("<" + reader.Name);
       Console.WriteLine(">");
                break;
      case XmlNodeType.Text: //Display the text in each element.
                Console.WriteLine (reader.Value);
                break;
      case XmlNodeType. EndElement: //Display the end of the element.
                Console.Write("</" + reader.Name);
       Console.WriteLine(">");
                break;
        }
    }
  8. 특성을 검사합니다. 요소 노드 종류에는 관련된 특성 노드 목록이 포함될 수 있습니다. MovetoNextAttribute 메서드는 요소 내의 특성 사이를 순차적으로 이동합니다. HasAttributes 속성을 사용하여 노드에 특성이 있는지 테스트합니다. AttributeCount 속성은 현재 노드의 특성 수를 반환합니다.
    while (reader.Read()) 
    {
        switch (reader.NodeType) 
        {
            case XmlNodeType.Element: // The node is an element.
                Console.Write("<" + reader.Name);
    
                while (reader.MoveToNextAttribute()) // Read the attributes.
                    Console.Write(" " + reader.Name + "='" + reader.Value + "'");
                Console.Write(">");
       Console.WriteLine(">");
                break;
      case XmlNodeType.Text: //Display the text in each element.
                Console.WriteLine (reader.Value);
                break;
      case XmlNodeType. EndElement: //Display the end of the element.
                Console.Write("</" + reader.Name);
       Console.WriteLine(">");
                break;
        }
    }
  9. 프로젝트를 저장하고 닫습니다.
 

전체 코드 예제

using System;
using System.Xml;

namespace ReadXMLfromFile
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {
        static void Main(string[] args)
        {
            XmlTextReader reader = new XmlTextReader ("books.xml");
            while (reader.Read()) 
            {
                switch (reader.NodeType) 
                {
                    case XmlNodeType.Element: // The node is an element.
                        Console.Write("<" + reader.Name);
                        Console.WriteLine(">");
                        break;
                    case XmlNodeType.Text: //Display the text in each element.
                        Console.WriteLine (reader.Value);
                        break;
                    case XmlNodeType.EndElement: //Display the end of the element.
                        Console.Write("</" + reader.Name);
                        Console.WriteLine(">");
                        break;
                }
            }
            Console.ReadLine();
        }
    }
}
 

출력 예제

<bookstore>
<book>
<title>
The Autobiography of Benjamin Franklin
</title>
<author>
<first-name>
Benjamin
</first-name>
<last-name>
Franklin
</last-name>
</author>
<price>
8.99
</price>
</book>
<book>
<title>
The Confidence Man
</title>
<author>
<first-name>
Herman
</first-name>
<last-name>
Melville
</last-name>
</author>
<price>
11.99
</price>
</book>
<book>
<title>
The Gorgias
</title>
<author>
<name>
Plato
</name>
</author>
<price>
9.99
</price>
</book>
</bookstore>
 

참조

다음 파일은 Microsoft 다운로드 센터에서 다운로드할 수 있습니다.
그림 축소그림 확대
다운로드
지금 Books.xml 다운로드 (http://download.microsoft.com/download/xml/utility/1.0.0.1/wxp/en-us/books.exe)
자세한 내용은 다음 Microsoft 웹 사이트의 MSDN Magazine에 있는 "XML in .NET: .NET Framework XML Classes and C# Offer Simple, Scalable Data Manipulation" 문서를 참조하십시오.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmag01/html/xml0101.asp (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmag01/html/xml0101.asp)
XmlReader 클래스에 대한 자세한 내용은 다음 Microsoft .NET Framework Class Library 웹 사이트를 참조하십시오.
http://msdn.microsoft.com/library/dotnet/cpref/frlrfsystemxmlxmlreaderclasstopic.htm (http://msdn.microsoft.com/library/dotnet/cpref/frlrfsystemxmlxmlreaderclasstopic.htm)
XmlReader를 사용하여 XML 데이터를 읽는 방법은 다음 Microsoft .NET Framework Developer's Guide 문서를 참조하십시오.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguidnf/html/cpconreadingxmldatausingxmlreader.asp (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguidnf/html/cpconreadingxmldatausingxmlreader.asp)
반응형
반응형

1. 기 능

파일의 마지막 부분을 출력한다.

2. 문 법

tail  [option] ... [file] ...
기본 출력은 파일의 마지막 10줄을 보여준다.

3. 옵션

--bytes=N : Nbyte 만큼 출력한다.
-f : 파일의 10줄을 출력해주고 파일의 내용을 실시간으로 계속해서 출력한다.
-n N : n 개수만큼의 라인을 출력한다.

4. 사용방법 및 정보
[root@ls ]# tail -n 20 anaconda-ks.cfg
anaconda-ks.cfg 파일의 마지막부터 20줄까지를 출력한다.
[root@ls ]# tail -n +20 anaconda-ks.cfg
anaconda-ks.cfg 파일의 20번째 줄 이후를 출력한다.
[root@ls ]# tail -f /var/log/messages

/var/log/messages 파일을 실시간으로 화면에 출력한다(log 모니터링에 사용됨)

[출처] [리눅스 명령어 / 29강] tail |작성자 단미

반응형
반응형
http://blog.paran.com/oraclejava
에서 퍼왔습니다.

1.        TCP Client & Server 만들기

관련 클래스
System.Net.Sockets.TCPClient : TCP 네트웍의 클라이언트 서비스를 제공, Socket 클래스를 기본으로 작성 되었으며 TCP 서비스를 제공 한다. TCPCLient는 TCP Client를 작성 할 때 쓰이며 FTP나 HTTP와 같은 애플리케이션 계층 프로토콜을 개발 하는데 주로 사요 된다.
예)
TCPClient myClient = new TCPClient(“***.***.***.***”, 13);
Stream myStream = myClient.GetStream();

System.Net.Sockets.NetworkStream : Network용 데이터 스트림을 제공 한다. 네트웍의 소켓을 통해 데이터를 전송 및 수신하는 표준 닷넷 프레임워크 스트림 방식을 구현 한다.

System.Net.Sockets.Socket : 버클리 소켓을 제공 한다. 트랜스포트 계층을 지원하며 생성된 소켓은 Bind() 메소드를 통해 특정한 종단점으로 바운드 되며 Connect 메소드를 통해서 연결이 생성 된다. Send(), SendTo() 메소드르 통해 테이터를 소켓으로 전송하며 Receive() 나 ReceiveFrom() 메소들 통해 소켓으로부터 데이터를 수신한다. 소켓으로 하는 모든 작업이 완료되면 Shutdown() 메소드를 이용해 소켓을 비활성화 한 후 Close() 메소드를 이용 해 소켓을 닫는다. 닷넷에서의 소켓은 인터넷의 TcpClient, UdpClient, WebRequest 그리고 파생된 클래스들의 연결을 맺는데 사용 된다.

System.Net.Sockets.TcpListener : TCP 네트웍의 클라이언트 접속을 Listen, 소켓 클래스를 기반으로 TCP 서비스를 제공하기 위한 클래스 이다. TcpListener는 TCP 클라이언트의 접속을 리슨하기 위해 서버 측에서 사용하며 FTP, HTTP와 같은 프로토콜을 사용하는 애프리케이션 계층은 TcpListener를 기반으로 작성 될 수 있다.



소스(TcpClientExample.cs)

using System;
using System.IO;
using System.Text;
using System.Net;
using System.Net.Sockets;

class TcpClientTest {
        static void Main(string[] args)
        {
                TcpClient client = null;
                try {
                        //LocalHost에 지정 포트로 TCP Connection을 생성하고 데이터를 송수신 하기
                        //위한 스트림을 얻는다.
                        client = new TcpClient();
                        client.Connect("localhost", 5001);
                        NetworkStream writeStream = client.GetStream();

                        //보낼 데이터를 읽어 Default 형식의 바이트 스트림으로 변환
                        string dataToSend = Console.ReadLine();        
                    byte [] data = Encoding.Default.GetBytes(dataToSend);                                                        
                        
                        while(true)
                        {                                                                
                                dataToSend += "\r\n";                                
                                data = Encoding.Default.GetBytes(dataToSend);                                
                                writeStream.Write(data,0,data.Length);                                
                                
                                if (dataToSend.IndexOf("<EOF>") > -1) break;
                                        
                                dataToSend = Console.ReadLine();
                        }                                
                }
                catch(Exception ex) {
                        Console.WriteLine(ex.ToString());
                }
                finally {
                        client.Close();
                }
        }
}

소스(TCPServer.cs)

using System;
using System.IO;
using System.Text;
using System.Net;
using System.Net.Sockets;

class Server
{
   public static void Main()
   {  
          NetworkStream stream = null;
          TcpListener tcpListener = null;
          StreamReader reader = null;
          Socket clientsocket = null;
      try
      {              
                 //IP주소를 나타내는 객체를 생성,TcpListener를 생성시 인자로 사용할려고
                 IPAddress ipAd = IPAddress.Parse("127.0.0.1");

                 //TcpListener Class를 이용하여 클라이언트의 연결을 받아 들인다.
         tcpListener = new TcpListener(ipAd, 5001);
                 tcpListener.Start();

                 //Client의 접속이 올때 까지 Block 되는 부분, 대개 이부분을 Thread로 만들어 보내 버린다.
                 //백그라운드 Thread에 처리를 맡긴다.
                 clientsocket = tcpListener.AcceptSocket();

                 //클라이언트의 데이터를 읽고, 쓰기 위한 스트림을 만든다.
                 stream = new NetworkStream(clientsocket);
                                 
             Encoding encode = System.Text.Encoding.GetEncoding("ks_c_5601-1987");
                 reader = new StreamReader(stream, encode);
                

                 while(true)
                 {                                
                         string str = reader.ReadLine();        
                         Console.WriteLine(str);                        
                 }                
      }
      catch (Exception e )
      {
         Console.WriteLine(e.ToString());
      }
          finally {
                clientsocket.Close();
          }
   }
}


[실습] 위의 예제는 Client는 단순히 보내기만 하고 Server는 단순히 받기만 한다. 적절히 수정하여 Client가 보내는 것을 서버는 화면에 출력하고 Client에 다시 보내는 EchoClient와 EchoServer를 작성 해 보시기를 바랍니다. 이 경우 Client 역시 보내고 받는 부분의 처리가 가능 해야 합니다.
[EchoClient.cs]
using System;
using System.IO;
using System.Text;
using System.Net;
using System.Net.Sockets;

class TcpClientTest {
        static void Main(string[] args)         {
                TcpClient client = null;
                try {
                        //LocalHost에 지정 포트로 TCP Connection을 생성하고 데이터를 송수신 하기
                        //위한 스트림을 얻는다.
                        client = new TcpClient();
                        client.Connect("localhost", 5001);
                        NetworkStream writeStream = client.GetStream();

                        Encoding encode = System.Text.Encoding.GetEncoding("ks_c_5601-1987");
                        StreamReader readerStream = new StreamReader(writeStream, encode);

                        //보낼 데이터를 읽어 Default 형식의 바이트 스트림으로 변환
                        string dataToSend = Console.ReadLine();        
                        byte [] data = Encoding.Default.GetBytes(dataToSend);                                                        
                        
                        while(true)
                        {                                                                
                                dataToSend += "\r\n";                                
                                data = Encoding.Default.GetBytes(dataToSend);                                
                                writeStream.Write(data,0,data.Length);                                
                                
                                if (dataToSend.IndexOf("<EOF>") > -1) break;

                                string  returnData;
                                returnData = readerStream.ReadLine();
                                Console.WriteLine("server : " + returnData);
                                        
                                dataToSend = Console.ReadLine();
                        }                                
                }
                catch(Exception ex)
                {
                        Console.WriteLine(ex.ToString());
                }
                finally
                {
                        client.Close();
                }
        }
}





[EchoServer.cs]

using System;
using System.IO;
using System.Text;
using System.Net;
using System.Net.Sockets;
class Server
{
        public static void Main()
        {  
                NetworkStream stream = null;
                TcpListener tcpListener = null;
                StreamReader reader = null;
                Socket clientsocket = null;
                try
                {              
                        //IP주소를 나타내는 객체를 생성,TcpListener를 생성시 인자로 사용할려고
                        IPAddress ipAd = IPAddress.Parse("localhost");

                        //TcpListener Class를 이용하여 클라이언트의 연결을 받아 들인다.
                        tcpListener = new TcpListener(ipAd, 5001);
                        tcpListener.Start();

                        //Client의 접속이 올때 까지 Block 되는 부분, 대개 이부분을 Thread로 만들어 보내 버린다.
                        //백그라운드 Thread에 처리를 맡긴다.
                        clientsocket = tcpListener.AcceptSocket();

                        //클라이언트의 데이터를 읽고, 쓰기 위한 스트림을 만든다.
                        stream = new NetworkStream(clientsocket);
                                 
                        Encoding encode = System.Text.Encoding.GetEncoding("ks_c_5601-1987");
                        reader = new StreamReader(stream, encode);        

                        while(true)
                        {                                
                                string str = reader.ReadLine();        
                                if(str.IndexOf("<EOF>") > -1)
                                {
                                        Console.WriteLine("Bye~ Bye~");
                                        break;
                                }
                                Console.WriteLine(str);                        

                                str += "\r\n";
                                byte[] dataWrite = Encoding.Default.GetBytes(str);

                                stream.Write(dataWrite,0,dataWrite.Length);

                        }                
                }
                catch (Exception e )
                {
                        Console.WriteLine(e.ToString());
                }
                finally
                {
                        clientsocket.Close();
                }
        }
}




[질문] 위의 예제에서 Client를 두 개 이상 만들어서 서버에 접속 해 보길 바랍니다.
과연 어떤 일이 일어 날까요? 그럼 그 해결책은 무엇 인가요? 아마도 멀티 쓰레드를  이용하여 블록킹 되는 메소드를 쓰레드로 처리를 해야 할 겁니다. 실습 해 보시기 바랍니다.





Client Program은 그대로 두고 서버를 다시 만들도록 합시다.

[MultiThreadEchoServer.cs]

using System;
using System.IO;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

public class ClientHandler
{
   public Socket clientSocket;

   public void runClient()
   {             
          NetworkStream stream = null;          
          StreamReader reader = null;                    
      try
      {                               
                 //Client의 접속이 올때 까지 Block 되는 부분, 대개 이부분을 Thread로 만들어 보내 버린다.
                 //백그라운드 Thread에 처리를 맡긴다.
                 //clientSocket = tcpListener.AcceptSocket();

                 //클라이언트의 데이터를 읽고, 쓰기 위한 스트림을 만든다.
                 stream = new NetworkStream(clientSocket);
     System.Console.WriteLine("111111111");                                 
                 Encoding encode = System.Text.Encoding.GetEncoding("ks_c_5601-1987");
                 reader = new StreamReader(stream, encode);
                
                 while(true) {                                
                         string str = reader.ReadLine();
                         if (str.IndexOf("<EOF>") > -1)
                        {
                                Console.WriteLine("Bye Bye ");
                                break;
                        }
                         Console.WriteLine(str);        
                         str += "\r\n";
                                
                         byte [] dataWrite = Encoding.Default.GetBytes(str);
                        
                         stream.Write(dataWrite,0,dataWrite.Length);
                 }                
      }
      catch (Exception e )
      {
         Console.WriteLine(e.ToString());
      }
          finally {
                    clientSocket.Close();
          }
   }
}

public class EchoServer
{                        
        public static void Main(string [] arg)
        {
                TcpListener tcpListener = null;
                try
                {
                        //IP주소를 나타내는 객체를 생성,TcpListener를 생성시 인자로 사용할려고
                        IPAddress ipAd = IPAddress.Parse("172.18.1.186");

                        //TcpListener Class를 이용하여 클라이언트의 연결을 받아 들인다.
                        tcpListener = new TcpListener(ipAd, 8000);
                        tcpListener.Start();
                        
                        Console.WriteLine("Waiting for connections...");        
                        
                        while(true)
                        {
                                // acepting the connection
                                Socket client = tcpListener.AcceptSocket();
                                                                                                        
                                ClientHandler cHandler = new ClientHandler();
                                // passing value to the thread class
                                cHandler.clientSocket = client;                                
                                
                                // creating a new thread for the client
                                Thread clientThread = new Thread(new ThreadStart(cHandler.runClient));
                                clientThread.Start();                                
                        }                                                        
                }
                catch(Exception exp)
                {
                        Console.WriteLine("Exception: " + exp);
                }                
                finally {
                        tcpListener.Stop();
                }
                        
        }
}
반응형
반응형

 

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

Server Socket 작성 하기

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

1. 소스 코드를 작성 하기 전에 우선 전체적인 코드를 개략적으로 이해 하기로 하자 .

우선 서버의 입장에서 로컬 종점을 생성 한다 . 리스닝을 위한 소켓을 열기 전에 로컬 종점 주소를 작성 해야 하며 서비스에 대한 종점을 생성 하기 위해 호스트의 IP 주소와 서비스의 포트 번호를 조합하여 TCP/IP 서비스의 고유 주소를 정의 한다 . Dns 클래스는 로컬네트워크 기기에서 지원하는 네트워크 주소에 대한 정보를 되돌려 주는 메소드를 제공 한다 . 로컬 네트워크 기기가 하나 이상의 네트워크 주소를 가지거나 로컬 시스템이 하나 이상의 네트워크 기기를 지원 한다면 Dns 클래스는 모든 네트워크 주소에 대한 정보를 되돌려 주며 애플리케이션은 아 배열에서 적절한 주소를 선택해야 한다 .

// 소켓에 사용할 종점을 설정

IPHostEntry ipHost = DNS.Resolve(“localhost”);

IPAddress ipAddr = ipHost.AddressList[0];

IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000);

2. 다음은 Socket 클래스의 새로운 인스턴스를 이용하여 스트림소켓을 생성 한다 . 이미 리스닝에 사용 할 로컬 종점을 작성 하였으므로 바로 소켓을 생성 할 수 있다 .

//TCP/IP 소켓을 생성

Socket sListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

AddressFamily 열거형은 Socket 인스턴스가 주소를 해석 하기 위해 사용하는 주소 스키마를 나타낸다 . 몇 가지 값들은 아래와 같다 .

AddressFamily.InterNetwork : IP 버전 4 주소

AddressFamily.InterNetwork V6: IP 버전 6 주소

AddressFamily.Ipx : IPX/SPX 주소

AddressFamily.NetBios: NetBios 주소

SocketType 은 TCP 와 UDP 소켓을 구분 하는데 이용 가능한 값은 아래와 같다 .

SocketType.Dgram : 데이터그램을 지원 , Dgram 은 Udp ProtocolType 과 AddressFamily.InterNetwork 와 함께 사용되어야 한다 .

SocketType.Raw : Raw Socket

SocketType.Stream : 스트림 소켓을 지원 , Stream 은 Tcp ProtocolType 과 AddressFamily.InterNetwork 와 함께 사용되어야 한다 .

세번째 파라미터 , 네번째 파라미터는 소켓에 필요한 프로토콜 형식을 정의 한다 . 그 값은 아래와 같다 .

Raw : Raw 패킷 프로토콜

Tcp : TCP

Udp : UDP

Ip : Internet Protocol

?  다음 단계는 Bind() 메소드를 사용하여 소켓에 이름을 부여 한다 . 생성자를 이용하여 소켓을 개방하면 소켓에 아무런 이름도 할강되어 있지 않다 . 즉 Bind() 메소드를 통해 소켓을 Local 종점에 연결 시키는 것이다 .

try {

sListener.Bind(ipEndPoint);

?  이제 소켓이 생성 되었고 , 이름이 바인딩 되었으므로 Listen() 을 사용하여 들어오는 연결에 대해 리스닝을 수행 할 수 있다 . 이때 파라미터에는 큐에 대기중인 연결의 최대 개수를 지정 한다 .

sListener.Listen(10);

?  위에서 리스닝을 했으므로 이젠 Accept() 를 이용하여 클라이언트의 연결을 수신하여 클라이언트와 서버의 이름 연결을 완료 한다 . Accept() 메소드는 대기중인 요청 큐로 부터 먼저 들어온 연결을 가지고 와 이를 처리할 새로운 소켓을 생성 한다 . 새로운 소켓이 생성 되었다고 하더라도 원래 소켓은 계속 리스닝을 수행 하므로 복수의 클라이언트 요청을 처리하기 위해서는 멀티쓰레드를 사용 한다 .

while(true) {

...

Socket handler = sListener.Accept();

?  Send(), Receive() 메소드를 이용하여 데이터를 보내고 , 받는다 .

string data = null;

while(true) {

byte[] bytes = new byte[1024];

// 클라이언트로부터 수신된 데이터

int byteRes = handler.Receive(byte);

// 바이트를 문자열로 변환

data += Encoding.Default.GetString(bytes, 0, byteRec);

// 메시지의 끝인지 확인

if (data.IndexOf(“”) > -1) {

break;

}

}

?  루프를 빠져 나온 후 클라이언트에게 응답을 돌려주기 위해 새로운 바이트 배열을 준비 한다 . 변환을 마친 후 Send() 메소드를 이용하여 데이터를 보내자

string theReply = “Thank you for those ” + data.Length.ToString() + “ characters …”;

byte[] msg = Encoding.Default.GetBytes(theReply);

handler.Send();

?  서버와 클라이언트의 데이터 교환이 끝나면 Close() 를 이용하여 소켓을 종료 한다 . 항상 Close() 를 하기 전에 Shutdown() 을 이용하여 남아 있는 데이터를 확실히 제거 하자 . 각 소켓 인스턴스 마다 Close() 메소드를 호출 해야 한다 .

handler.Shutdown(SocketShutdown.Both);

handler.Close();

SocketShutdown 값은 열거형으로 아래와 같은 값을 취한다 .

Both : 송 . 수신용 소켓 모두

Receive : 수신용

Send : 송신용 소켓

소스 코드는 아래와 같다 .[SocketServer.cs]

using System;

using System.Net.Sockets;

using System.Net;

using System.Text;

public class SocketServer

{

public static void Main (string [] args)

{

// establish the local end point for the socket

IPHostEntry ipHost = Dns.Resolve("localhost");

IPAddress ipAddr = ipHost.AddressList[0];

IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000);

// create a Tcp/Ip Socket

Socket sListener = new Socket(AddressFamily.InterNetwork,

SocketType.Stream, ProtocolType.Tcp);

// bind the socket to the local endpoint and

// listen to the incoming sockets

try

{

sListener.Bind(ipEndPoint);

sListener.Listen(10);

// Start listening for connections

while (true)

{

Console.WriteLine("Waiting for a connection on port {0}",ipEndPoint);

// program is suspended while waiting for an incoming connection

Socket handler = sListener.Accept();

string data = null;

// we got the client attempting to connect

while(true)

{

byte[] bytes = new byte[1024];

int bytesRec = handler.Receive(bytes);

data += Encoding.ASCII.GetString(bytes,0,bytesRec);

if (data.IndexOf("") > -1)

{

break;

}

}

// show the data on the console

Console.WriteLine("Text Received: {0}",data);

string theReply = "Thank you for those " + data.Length.ToString()

+ " characters...";

byte[] msg = Encoding.ASCII.GetBytes(theReply);

handler.Send(msg);

handler.Shutdown(SocketShutdown.Both);

handler.Close();

}

}

catch(Exception e)

{

Console.WriteLine(e.ToString());

}

} // end of Main

}

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

Client Socket 작성 하기

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

1. 클라이언트 코드가 서버와 다른 점은 Connect() 메소드 부분이다 . 이것은 클라이언트가 원격의 서버에 연결 하고자 할 때 사용하는 메소드 이다 . 사용하기 위해서는 우선 원격 종점을 설정 해야 한다 .

// 소켓에 사용할 원격 종점을 설정

IPHostEntry ipHost = DNS.Resolve(“127.0.0.1”);

IPAddress ipAddr = ipHost.AddressList[0];

IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000);

Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

sender.Connect(ipEndPoint);

Connect() 메소드로 소켓을 종점 파라미터로 지정된 원격 호스트와 연결을 맺는다 . 일단 연결이 이루어 지면 데이터를 보내고 받을 수 있다 .

string theMessage = “This is a test”;

byte[] msg = Encoding.Default.GetBytes(theMessage+””);

// 소켓을 이용하여 데이터를 보냄

int bytesSend = sender.Send(msg);

// 원격으로부터 ( 서버 ) 응답을 수신

int bytesRec = sender.Receive(bytes);

이젠 마지막으로 Shutdown() 을 호출하여 소켓을 해제 한다 . 그리고 Close() 하자

sender.Shutdown(SocketShutdown.Both);

sender.Close();

[ 아래는 SocketClient.cs 의 소스 파일 이다 .]

using System;

using System.Net.Sockets;

using System.Net;

using System.Text;

public class SocketClient

{

// If you specify any text as a command-line argument, it will be sent to the server.

// e.g. SocketClient "Send this text" will send that string

// If no command-line arguments are specified, a default string is sent

public static void Main (string [] args)

{

// data buffer for incoming data

byte[] bytes = new byte[1024];

// connect to a Remote device

try

{

// Establish the remote end point for the socket

IPHostEntry ipHost = Dns.Resolve("127.0.0.1");

IPAddress ipAddr = ipHost.AddressList[0];

IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 11000);

Socket sender = new Socket(AddressFamily.InterNetwork,

SocketType.Stream, ProtocolType.Tcp);

// Connect the socket to the remote endpoint. Catch any errors

sender.Connect(ipEndPoint);

Console.WriteLine("Socket connected to {0}",

sender.RemoteEndPoint.ToString());

//string theMessage=Console.ReadLine();

string theMessage;

if (args.Length==0)

theMessage = "This is a test";

else

theMessage = args[0];

byte[] msg = Encoding.ASCII.GetBytes(theMessage+"");

// Send the data through the socket

int bytesSent = sender.Send(msg);

// Receive the response from the remote device

int bytesRec = sender.Receive(bytes);

Console.WriteLine("The Server says : {0}",

Encoding.ASCII.GetString(bytes,0, bytesRec));

// Release the socket

sender.Shutdown(SocketShutdown.Both);

sender.Close();

}

catch(Exception e)

{

Console.WriteLine("Exception: {0}", e.ToString());

}

}

}

반응형
반응형
http://blog.paran.com/oraclejava/   에서 퍼왔습니다.
 
Socket Programming

-------
소켓
-------
소켓 이란? 두 프로그램이 네트워크를 통해 서로 통신을 수행 할 수 있도록 양쪽에 생성 되는 링크의 단자이다. 두 소켓이 연결되면 서로 다른 프로세스끼리(프로세스가 원격에 있든지 로컬에 있든지 상관 없다.) 데이터를 전달 할 수 있다. 결국 소켓이 구현됨으로써 네트워크 및 전송 계층의 캡슐화가 가능해 졌다.

소켓은 원래 캘리포니아 버클리 대학 분교에서 UNIX 용으로 개발 되었으며 유닉스에서의 입출력 메소드의 표준인 개방/읽기/쓰기/닫기 메커니즘을 따른다.

-------
소켓 형식
-------
1.        스트림 소켓
스트림소켓은 양방향으로 바이트 스트림을 전송 할 수 있는 연결 지향형 소켓으로 양쪽 어플리케이션이 모두 데이터를 주고 받을 수 있다는 것을 의미 한다. 스트림소켓은 오류수정, 전송처리, 흐름제어 등을 보장 해 주며 송신된 순서에 따른 중복되지 않은 데이터를 수신 하게 된다. 이 소켓은 각 메시지를 보내기 위해 별도의 연결을 맺는 행위를 하므로 약간의 오버헤드가 존재 한다. 그러므로 소량의 데이터 보다는 대량의 데이터를 보내는 경우에 적당 하다. 스트림소켓은 이러한 품질의 통신을 수행 하기 위하여 TCP 프로토콜을 사용 한다.

2.        데이터그램 소켓
명시적으로 연결을 맺지 않으므로 비 연결형 소켓이라고 한다. 메시지는 대상 소켓으로 전송되며 대상 소켓은 메시지를 적절히 수신 한다. 스트림 소켓을 사용하는 것이 데이터그램 소켓을 사용 하는 것 보다 더 신뢰성이 높은 방법이지만 연결을 수립하는데 드는 오버헤드는 무시 할 수 없다. 데이터그램 소켓을 사용하려면 클라이언트에서 서버로 데이터를 전송 할 때 UDP를 사용 한다. 이 프로토콜에서는 메시지의 크기에 약간의 제한이 있으며 메시지의 확실 한 전달 역시 보장 하지 않으며 통신 중 데이터를 잃어 버리더라도 오류를 되돌리지 않는다.
3.        Raw 소켓
Raw 소켓은 패킷을 가져오면 TCP/IP 스택상의 TCP, UDP 계층을 우회하여 바로 애플리케이션으로 송신하는 소켓이다. 이런 소켓에서 패킷은 TCP/IP 필터를 통해 전달 되지 않으므로 원형 그대로의 패킷을 볼 수 있다. 이는 모든 데이터를 적절히 처리하거나 헤더를 제거하고 이를 파싱 하는 과정은 모두 수신 애플리케이션에서 담당해야 하는 것이다. 실제 Raw 소켓을 이용하여 프로그래밍을 하는 일은 거의 드물며 만약 시스템 소프트웨어나 패킷을 분석하는 프로그램을 개발 시에는 필요 할 수도 있다. 즉 Raw Socket은 저수준 프로토콜 애플리케이션을 작성 할 때 주로 사용 된다고 보면 된다.


---------
포트
---------
여러 개의 애플리케이션들이 동시에 통신을 수행하기 위하여 포트가 정의 되는데 기본적으로 포트는 IP 주소 표기를 확장 하는 개념 이다. 네트워크에서 패킷을 수신하는 애플리케이션이 동시에 실행 되고 있는 컴퓨터로 연결을 맺을 때 송신자가 알고 있는 수신 애플리케이션의 고유 포트 번호를 이용하여 대상 프로세스를 식별 하는 것이다.

소켓 번호는 컴퓨터의 IP 주소와 TCP 애플리케이션에서 사용하는 포트 번호로 이루어져 있다. IP주소는 인터넷 상에서 유일 하고 포트 번호는 개별 컴퓨터에서 유일하기 때문에 전체 인터넷에서 소켓 번호 또한 유일 한 것이다.

-----------------------
.NET 에서 소켓 다루기
-----------------------
System.Net.Sockets 네임스페이스의 클래스들은 .NET에서 지원하는 소켓들을 제공 한다.

System.Net.Sockets.MulticastOption : IP 멀티캐스트 그룹에 참여 하거나 탈퇴하기 위한 IP 주소 값을 설정 한다.

System.Net.Sockets.NetworkStream : 데이터를 주고 받는 하위 스트림을 구현 한다. 이는 TCP/IP 통신 채널에 대한 연결을 나타내는 고수준 추상형이다. 이 클래스를 이용하여 네크워크 소켓을 통해 데이터를 주고 받을 수 있다. NetworkStream은 버퍼 기능이 지원되지 않으므로 BufferedStream을 중간 저장 매체로 함께 사용 하기도 한다.
System.Net.Sockets.TcpClient : Socket 클래스를 기반으로 하여 작성 되었으며 고수준 TCP 서비스를 제공하여 준다.

System.Net.Sockets.TcpListener : Socket 클래스를 기반으로 작성 되었으며 서버 애플리케이션에서 사용 한다.이 클래스는 들어오는 클라이언트의 연결을 리스닝 하며 애플리케이션에게 연결된 요청을 알려 준다.

System.Net.Sockets.UdpClient : UDP 서비스를 구현하기 위한 클래스

System.Net.Sockets.SocketException : 소켓에서 오류가 존재할 때 발생하는 예외

System.Net.Sockets.Socket : 소켓 애플리케이션의 기본 기능을 제공 한다.


------------------------
System.Net.Sockets.Socket
------------------------
Socket 클래스는 네트워크 프로그래밍에서 중요한 역할을 담당 하는데 클라이언트와 서버 사이의 모든 동작을 수행 한다.윈도우 소켓 API의 해당 하는 메소드로 매핑 된다.

아래는 몇 가지 속성 이다.

AddressFamily : 소켓의 주소 계열을 획득, Socket.AddressFamily 열거형의 값 이다.
Available : 읽을 수 있는 데이터 량을 Return
Blocking : 소켓이 블로킹 모드 인지 확인
Connected : 소켓이 원격 호스트에 연결 되어 있는 지
LocalEndPoint : 로컬 종점을 돌려 줌
ProtocolType : 소켓의 프로토콜 형식을 돌려 준다.
SocketType : 소켓의 타입을 돌려 준다.

아래는 몇 가지 메소드 이다.
Accept() : 들어오는 연결을 다루기 위한 새로운 소켓을 생성
Bind() : 들어오는 연결을 리스닝 하기 위하여 소켓을 로컬종점으로 연결
Close() : 소켓을 종료
Connect() : 원격 호스트에 연결을 맺는다.
Listen() : 리스닝 상탸로 만든다, 이것은 서버 소켓에서만 사용 된다.
Receive() : 연결된 소켓으로부터 데이터를 수신 한다.
Send() : 연결된 소켓으로 데이터를 송신 한다.
Shutdown() : 소켓에 대한 연결을 비 활성화 한다.

다음 시간에는 실제 예제를 작성하며 이해해 보도록 하죠...
반응형
반응형

C# 네임 스페이스 정리

 

Mcrosoft.CSharp : C#을 사용한 컴파일과 코드 생성 제공
Mcrosoft.JSharp : JSharp.NET 을 사용한 컴파일과 코드 생성 제공
Mcrosoft.VisualBasic : VisualBasic.NET 을 사용한 컴파일과 코드 생성 제공
Mcrosoft.Win32 : 윈도우 레지스트리 참조와 윈도우 시스템 이벤트 제공
System : 일반적으로 사용되는 값 타입과 레퍼런스 데이타 타입, 이벤트와 이벤트 핸들러, 인터페이스 , 속성, 예외 등을 포함하며, 가장 중요한 네임스페이스이다.
System.Collections : 리스트와 큐 배열, 해쉬 테이블, 사전 등과 같은 컬렉션 타입 제공
System.ComponentModel : 컴포넌트의 런타임과 디자인 타임 때 사용 제공
System.Configuration : .NET 프레임 워크 설정 세팅을 위해 참조 제공
System.Data : ADO.NET 타입 제공
System.Data.SqlClient : Sql Server.NET 데이터 타입 제공
System.Data.SqlTypes : 윈시SQL서버 데이터 타입 제공
System.Diagnostics : 디버깅과 트래킹을 위한 애플리케이션, 윈도우의 이벤트 로그 클래스제공
System.DirectoryService : LDAP이나 NDS와 같은 서비스 제공자를 사용하여 동적 디렉토리 참조 제공
System.Drawing : 윈도우 GDI+  그래픽 타입 제공
System.Globalization : 언어 수용과 관련되 타입, 스티링 정렬 순서, 나라/지역, 달력,날짜, 통화와 같은 숫자 형태 제공
System.IO : 스트림과 파일에 읽고 씀
System.Messaging : 메시지가 큐에 넣어 보내고 받고 관리하는 기능(MSMQ) 제공
System.Net : DNS와 HTTP같은 간단한 네트위크 프로토콜 API제공
System.Net.Sockets : TCP/UDp 소켓 API제공
System.Reflection : 적재된 타입과 멤버 참조 제공
System.Reflection.Emit : 메타데이터/IL 생성과 PE파일 생성 제공
System.Resources 애플리케이션 리소스위 생성과 관리 제공
System.Runtime.InteropService : COM 객체와 원시 API 참조 제공
System.Runtime.Remoting : 분산 객체의 생성과 설정 제공
System.Runtime.Remoting.Channels : 원격 채널관리와 채널 싱크(sink) 제공
System.Runtime.Remoting.Channels.Http : HTTP(SOAP) 채널 관리 제공
System.Runtime.Remoting.Channels.Tcp : TCP(이진) 채널 관리 제공
System.Runtime.Remoting.Lifetime : 원격 객체의 생명주기 관리 제공
System.Security : CLR 보안 시스템 하의 참조 제공
System.Security.Permissions : 정책에 기반한 오퍼레이션과 리소스 참조 제한 제공
System.Security.Policy : CLR 보안 정책 시스템에 적용될 규칙이 정의된 코드 그룹, 멤버쉽 상태 , 증거 제공
System.Security.Principal : 규칙 기반의 보안이 사용된 주요 클래스, 인터페이스, 열거형 제공
System.ServiceProcess : 윈도우 서비스 설치와 실행 제공
System.Text : ASCII, 유니코드, UTF-7, UTF-8 과 같은 텍스트 인코딩과 전환 제공
System.Text.RegularExpression : 이미 만들어져 있는 정규 표현식 엔진 참조 제공
System.Threading : 멀티 쓰레드 프로그래밍을 위한 클래스와 인터페이스 제공
System.Timers : 특정한 시간 간격으로 이벤트를 발생시키는 타이머 컴포넌트 제공
System.Web : HttpApplication, HttpRequest. HttpResponse 와 같은 ASP.NET 클래스에서 사용하는 기능을 포함한 브라우저/ 서버간의 통신 제공
System.Web.Configuration : ASP.NET설정 클래스와 열거형 제공
System.Web.Services : 웹 서비스 제작과 사용 제공
System.Web.Services.Description : WSDL을 사용한 웹 서비스 제공
System.Web.Services.Discovery : DISCO를 통한 웹 서비스 제공
System.Web.SessionState : ASP.NET세션 상태 참조 제공
System.Web.UI : ASP.NET 웹 페이지와 컨트롤 생성
System.Web.UI.Design : 웹 폼을 제공하기 위한 디자인 제공
System.Web.UI.Design.WebControls : 웹 컨트롤을 제공하기 위한 다지인 제공
System.Web.UI.HtmlControls : HTML 서버 컨트롤 생성 제공
System.Web.UI.WebControls : Web 서버 컨트롤 생성 제공
System.Windows.Forms : 윈도우 폼 기반의 사용자 인터페이스와 컨트롤 생성 제공
System.Windows.Forms.Design : 윈도우 품을 위한 디자인 제공
System.Xml : 표준 XML제공
System.Xml.Schema : 표준 XML스키마 제공
System.Xml.Serialization : XML문서 또는 스트림 객체의 직렬화 제공
System.Xml.XPath : XPath 파서와 평가 엔진 제공
System.Xml.Xsl : XSL전환 제공

반응형
반응형

------------------------------------------------------------------
외국사이트
------------------------------------------------------------------

 

1. ASP.NET Forums(포럼소스)

   http://www.asp.net/Default.aspx?tabindex=7&tabid=41

 

2. DotNetNuke(홈페이지 자동화 구축) / VB.NET

   http://www.dotnetnuke.com/DesktopDefault.aspx?tabid=125    

   

3. C# 메일서버(웹메일 포함)

   

http://www.lumisoft.ee/lsWWW/ENG/Products/Mail_Server/mail_index_eng.aspx?type=download

 

4. WebControl(텍스트 편집기)

   http://www.freetextbox.com/getfreetextbox.aspx

   

5. Rainbow Portal

   http://www.rainbowportal.org/Rainbow/Default.aspx          

    

6. CodeProject(각종 아티글)

   http://www.codeproject.com/

 

7. Lutz Roeder's (닷넷 자료)

   http://www.aisto.com/roeder/dotnet/

 

8. Master C# (닷넷 커뮤니티)

   http://www.mastercsharp.com/

 

9. CrownwoodSoftwhere(매직 라이브러리)

   http://www.crownwood.net/

 

------------------------------------------------------------------
국내사이트
------------------------------------------------------------------

 

1. taeyo's ASP & .NET

   http://www.taeyo.net

 

2. SKY.ph-개발자 커뮤니티 사이트

   http://sky.ph/

 

3. Neovis-ASP.NET,C#,ASP

   http://www.neovis.pe.kr

 

4. HOONS 닷넷 개발자 SIDE

   http://www.hoonsbara.com

 

5. 고수닷넷 (닷넷 관련 아티글)

   http://www.gosu.net

 

6. 소설같은 C#(C#의 기본 문법 정리)

   http://www.jabook.org/   



웹서핑하다 펌~

반응형
반응형

드디어 ASP.NET을 배우고 있다.

그동안 DB도 배우고 C#도 배우고 했는데 블로그 관리에 너무 소흘했다..

폴더만 덩그러니 있구나...

이번 ASP.NET을 배우는데 VS2008 막강한 기능들 때문에

마치 나모 웹 에디터를 쓰는듯한 기분으로 웹페이지를 만들고 있다.

이번에 소개할 Calendar 또한 기본 제공하는 컨트롤 치고 킹왕짱인듯 싶다.

먼저 맛뵈기로 실행 화면을 보면..

사용자 삽입 이미지


짠~

이게 기본으로 제공되는 컨트롤이다. 놀랍지 않은가? 나만 놀라운가-_-;
저걸 일일이 자바스크립트로 짤려면 얼마나 빡셀지...

이것은 보는바와 마찬가지로 기념일 세팅 달력이다.

어떻게 하는지 캡쳐화면으로 몇장 보여주고 소스코드를 보여주겠다.

먼저, VS2008 새로만들기 -> 웹사이트 -> (Asp.net 웹 사이트) -> 추가 -> 웹폼

이렇게 파일을 하나 만들어주고,

사용자 삽입 이미지

그냥 드래그해서 넣어주면 된다.

그럼 달력생성 -_-;

만들어진 Calendar 옆에 화살표 클릭하면 자동서식 있다. 클릭~

사용자 삽입 이미지


이 창이 뜰거다..

여기서 취향대로 맞춰준다.

자 그럼 특정 날에 그림파일 집어넣는 방법은?

protected void  Page_Load(object sender, EventArgs e)
{
    int year = DateTime.Today.Year;
    dates.Add(new Pair(new DateTime(year, 3, 1), "삼일절"));
    dates.Add(new Pair(new DateTime(year, 10, 20), "동선이 생일"));
    dates.Add(new Pair(new DateTime(year, 5, 19), "선생님 생일"));
    dates.Add(new Pair(new DateTime(year, 7, 17), "제헌절"));
    dates.Add(new Pair(new DateTime(year, 10, 3), "개천절"));
   
}

우선 Page_Load에 기념일 넣어줄 데이터를 넣어주고~

protected void  Calendar1_DayRender(object sender, DayRenderEventArgs e)
{
    foreach(Pair d in dates)
    {
        if((DateTime)d.First == e.Day.Date)
        {
            HyperLink hl = new HyperLink();
            hl.NavigateUrl = e.SelectUrl;
            hl.ImageUrl = "./img/kr.gif";
            hl.Text = (String)d.Second;
            e.Cell.Controls.Clear();
            e.Cell.Controls.Add(hl);
        }
    }   
}
Calendar를 더블클릭한 뒤 저 소스를 넣어주면 된다. 물론 이름은 맞춰줘야겠지^^
hl.ImageUrl = "./img/kr.gif" 는 웹폼이 저장된곳의 이미지 폴더에 저장된 그림파일이다.
형식도 입맛대로 바꿔줄수있으니 응용하면 다른 작품이 나올수도 있는거고
취향대로 그림도 넣으면 된다. ^*^

반응형
반응형
소프트웨어가 정확히 무엇인가?"와 같은 존재에 대한 질문에는 즉시 답할 수가 없습니다.

다음과 같은 상황을 고려해 보십시오. 여행중에 기념품 가게에서 친구나 가족에게 줄 선물을 고르고 있다고 가정합니다. 이런 경우 판매원은 보통 "처음 방문하신 겁니까? 출장으로 오신 겁니까 아니면 휴가로 오신 겁니까?" 같은 질문을 할 것입니다.

만약 여러분이 소프트웨어와 관련된 일을 하고 있고 휴가 중이 아니라면 위에서 언급한 존재에 대한 질문에 직면하게 됩니다.

그렇다면 정확히 소프트웨어는 무엇에 관한 것인가요?

특히 여러분이 소프트웨어와 직접적인 연관이 없이 그저 휴가를 즐기는 중이라면 이러한 존재에 대한 질문에 답하는 것은 쉽지가 않습니다.

필자는 나름대로 간단하게 고찰해보았습니다. 첫째, 소프트웨어는 컴퓨터와 관련이 있습니다. 또한 소프트웨어는 발전의 산물입니다. 확실히 소프트웨어는 데이터와 관련이 있고, 특히 데이터 저장소 및 조작에 관련이 있습니다.

그렇다면 최근 몇 년동안 데이터 저장소 및 사용에 대해 어떤 종류의 소프트웨어가 발전했는지에 대한 의문이 생깁니다. 따라서 OLE DB 고찰 및 .NET 관점에서 OLE DB의 발전에 대해 살펴보겠습니다.


소프트웨어의 발전 과정
=====================
역사적으로 보면 ODBC는 응용 프로그램이 데이터베이스를 일정한 방식으로 액세스를 하는 최초의 시도였습니다. 소프트웨어의 관점에서 ODBC는 특정한 요구에 부합하기 위해 설계되었습니다. 그리고 정보 기술 발전사에 새로운 장을 열었습니다.

ODBC는 내부 정보, 언어, 테이블 조직 등에 관계없이 데이터베이스를 액세스하는 공통의 추상적인 API를 제공했습니다. 시간이 지남에 따라 새로운 방식으로 데이터 기반 응용 프로그램을 설계하고 구축하는 상황에 ODBC는 부적합하게 되었습니다.

치열한 소프트웨어 경쟁속에서 살아남기 위한 일환으로 ODBC는 다른 이름, 다른 프로그래밍 모델 및 획기적인 기능을 적용하여 위기를 극복했습니다. 그리고 그 다음 OLE DB라는 새로운 기능을 토대로 개방형 데이터베이스 연결을 제공했습니다.

OLE DB는 Microsoft UDA(Universal Data Access) 전략의 이론적인 개념을 구체화한 프로그래밍 인터페이스 모델입니다. UDA(범용 데이터 액세스)는 단일 COM 기반 프로그래밍 인터페이스를 사용하여 관계형, 비관계형, 계층형 등과 같은 모든 유형의 데이터를 액세스할 수 있는 기능을 제공합니다.

구성 요소 기술로 설계되었기 때문에 OLE DB는 여러 계층 구조 모델 기능을 제공합니다. COM 브리지의 한쪽에는 데이터를 보유하는 서버 구성 요소가 있고, 다른 한쪽에는 데이터를 연결하고 요청하는 클라이언트 구성 요소가 있습니다. 전자를 OLE DB 데이터 공급자라고 하고 후자를 OLE DB 소비자라고 합니다.

소비자 및 공급자 모두 COM 개체이므로 COM 인터페이스를 통해 서로 통신할 수 있습니다. COM 기반 통신은 DataSource, Session, Command 및 Rowset과 같은 추상 개체에서 수행되는 작업입니다. 소비자가 DataSource 연결하여 Session을 열고 Command를 수행하면 Rowset 데이터를 가져올 수 있습니다.

ODBC는 UDA 및 OLE DB 기능을 도입하여 결합되었기 때문에 관계형, 비관계형 또는 계층형에 관계없이 모든 엔터프라이즈 데이터를 단일 관계형 테이블처럼 처리할 수 있습니다.


OLE DB 모델
===========
데이터 액세스에 관해서라면 다음과 같은 두 가지 기본 선택이 있습니다. 그 중 하나는 UDA 처럼 데이터 액세스 전략을 범용화하는 것이고, 다른 하나는 데이터 구조에 알맞게 범용화를 적용하는 것입니다. 따라서 현재 데이터 저장소에서 각 데이터를 광범위하게 포함할 수 있는 단일 데이터베이스 서버로 이동해야 합니다.

OLE DB를 이용하면 클라이언트와 모든 결합을 시도할 수 있습니다. 클라이언트에 대해 모든 형식의 정보를 조작할 수 있는 더 강력하고 획기적인 DBMS로 Scaling Up(하드웨어 차원의 확장)을 수행해야 합니다.

OLE DB는 ODBC보다 물리적 데이터 구조에서 매우 독립적입니다. 또한 엄밀히 말해서 SQL 기반이 아닙니다. OLE DB 명령은 SQL 구문 및 그 외 다른 구문일 수 있습니다. 일반적으로 OLE DB 명령은 대상 공급자가 인식할 수 있는 구문에 따라 쓰여진 텍스트 문자열입니다.

ODBC와 같이 OLE DB도 중간 계층 모듈에서 데이터 액세스의 성능을 최대화하기 위해 C++로 설계되었습니다. 이와 같은 이유로 OLE DB는 Visual Basic? 또는 ASP에서 직접 사용할 수 없습니다.

수 많은 분산 시스템은 구성 요소를 만들기 위해 Visual Basic을 사용했습니다. 이것이 Microsoft가 ADO(ActiveX? Data Objects) 라이브러리를 소개하게 된 이유입니다.

ADO는 원시 OLE DB SDK보다 다양한 프로그래밍 인터페이스를 가지고 있습니다. C++ 응용 프로그램에서 ADO를 사용할 수 있는 것은 확실하지만 OLE DB 호출은 ADO 코드에 비해 더 적은 코드 계층을 통과하며 보다 직접적인 방식으로 이동합니다.

ADO는 OLE DB 위에 설계되었지만 원시 OLE DB 인터페이스에 대한 호출과 ADO 런타임을 통해 실행된 호출은 다른 상대적 속도를 갖습니다. 이러한 수행은 일종의 언어 기반 문제를 발생시킵니다. 그렇다면 OLE DB의 고성능 수준 C++ 또는 Visual Basic 구성 요소의 더 쉽고 일반적인 ADO 모델 중 어느것이 더 나은 권장 사항일까요?

공급자 및 소비자 외에 OLE DB 모델은 제3요소인 OLE DB 서비스를 포함하고 있습니다. 서비스는 소비자에게 반환되는 Rowset을 처리하는 COM 구성 요소로서 소비자와 공급자 간의 모든 소통량을 모니터하는 후크처럼 작동합니다. ADO는 데이터 모양, 지속성 및 연결이 끊긴 레코드 집합과 같은 확장된 기능을 추가하기 위해 OLE DB 서비스를 전적으로 이용합니다.

분산 COM 기반 응용 프로그램 작성을 지원하기 위한 일환으로 여러 가지 적합한 실습이 특정 분야를 위해 개발되었습니다. 웹 응용 프로그램의 확장성을 향상시키려면 데이터 액세스 연결이 끊긴 모델에 관심을 두어야 합니다.

간단히 말해서 데이터 소비자 및 데이터 공급자는 항상 연결되어 있지 않습니다. 일단 연결이 되면 해당 쿼리 명령을 수행하여 메모리 내부 저장소로 레코드를 가져오고 데이터 원본에서 연결을 끊습니다. 오프라인 상태에서 레코드 작업을 하고 있는 경우 필요하면 나중에 다시 연결하고 변경 내용을 제출할 수 있습니다. 이러한 모델은 일반인 대상이 아닙니다. 확장성 증대 및 전체적인 성능면에서 매우 중요합니다.

데이터 연결을 끊을 수 있는 클라이언트측 커서 서비스를 통해 ADO 레코드 집합을 적용하기 위해 수 많은 시스템이 변환되었습니다. OLE DB는 특히 상호 작용 모델 개념을 포함하고 있지 않기 때문에 ADO는 중간 OLE DB 서비스를 통해 확장됩니다.

기본 제공된 아키텍처의 융통성을 이용하여 OLE DB는 연결이 끊긴 상태에서도 작업을 수행할 수 있습니다. 그렇지만 가장 좋은 작업 방식은 아닙니다. 이러한 구현의 또 다른 미묘한 한계는 ADO 레코드 집합이 모든 작업을 항상 순조롭게 수행할 수 없는 너무 많은 것에 의존한다는 것입니다. 디스크에서 조작하거나 로드할 경우, 연결되거나 연결이 끊긴 상태에서 또는 XML을 사용하거나 사용하지 않고 작업할 때 이와 같은 개체를 어떻게 신속하게 처리할 수 있을까요?

또한 ADO 기능이 원시 OLE DB SDK와 완전히 다르다는 것을 고려하면 OLE DB에는 상당한 일관성의 결여가 불가피합니다.

따라서 ADO.NET은 데이터 액세스 기술 발전 과정의 다음 단계라고 할 수 있습니다. 이름에서도 알 수 있듯이 겉보기에 ADO.NET은 ADO의 계승자입니다. .NET에서 OLE DB에 대해서는 어떻게 생각합니까?


.NET 관리 공급자
=================
시대를 초월한 다윈의 진화론 법칙에 따라 이제 OLE DB 기술은 새 사용자 요구에 부응해야 하는 단계로 이동해야 할 시점에 있습니다. .NET에서 웹 응용 프로그램은 주로 연결이 끊긴 응용 프로그램으로 데이터를 관리하기 위해 새롭게 설계된 임의 도구를 사용할 수 있습니다.

.NET 프레임워크를 사용하여 데이터에 대한 클래스 작업을 할 수 있습니다. 특히 ADO.NET 및 XML 이름 공간과 같은 클래스는 수집, 읽기 및 쓰기를 제공합니다. ADO.NET 및 XML 하위 시스템은 단일 언어 중립 방식으로 데이터를 가져오고 설정할 수 있도록 ADO 및 OLE DB SDK를 교체합니다.

ADO.NET 클래스는 ADO의 데이터베이스 중심 모델과는 반대로 완전한 데이터 중심 설계이기 때문에 ADO 보다 많이 데이터 원본을 추상화합니다.

OLE DB 공급자의 .NET 사본을 관리 공급자라고 합니다. 다음 그림은 공급자의 역할을 설명한 것입니다.

그림 1. 관리 공급자의 아키텍처 다이어그램


OLE DB에는 상호 작용하는 두 개의 계층인 관리 소비자 계층과 관리 공급자 계층이 있습니다. 따라서 데이터를 조작하기 위해 .NET 응용 프로그램에서 소비자 모듈 역할을 하는 특정 클래스나 구성 요소를 찾을 필요가 없습니다.
.NET 응용 프로그램은 원시 프레임워크에서 단지 DataSet 또는DataReader 개체를 사용하며 곧 바로 "관리" 데이터 소비자 역할을 수행합니다. 데이터를 물리적으로 가져오려면 DataSetCommand 및 DBCommand에서 상속받은 특수 클래스의 인스턴스를 사용합니다. 이 클래스는 데이터 원본에 대한 연결을 나타냅니다.

제공된 공급자를 이용하기 위해 일반적인 개체를 사용하는 대신에, 제공된 공급자를 처리하는 방법을 이미 알고 있는 파생된 클래스를 사용합니다. SQLDataSetCommand는 SQL Server 데이터베이스를 처리하고 ADODataSetCommand는 모든 기존 OLE DB 공급자를 포장합니다.

따라서 DataSetCommand와 같은 클래스에 의해 관리 공급자의 역할은 없어지게 됩니다. 프로그래머는 이와 같은 클래스의 역할 수행을 인식할 수 없으며 알 필요도 없습니다. 단지 클래스를 사용하고 속성만 설정하면 됩니다.

위의 그림에서 관리 공급자 계층은 상호 작용 모델을 사용하며, 이 모델은 ODBC 및 OLE DB에서 사용한 모델과 거의 비슷합니다. 소비자 명령 클래스는 데이터 원본을 포장하는 특정 구성 요소를 대상으로 하기 때문에 데이터 원본 행에 대해 읽기/쓰기를 수행하는 해당 프로토콜을 알고 있습니다. 그리고 .NET 클래스가 처리할 방법을 완전히 알고 있는 형식으로 결과를 반환합니다.

이해를 돕기 위해서 OLE DB 및 .NET에서 데이터 검색을 할 때 수행되는 요소를 검토해 봅시다.

대상 공급자를 OLE DB의 COM progID로 확인하고 .NET에서는 접근자 클래스가 그 역할을 수행합니다.
OLE DB 공급자는 주로 IRowset 인터페이스를 제공하는 COM 개체인 행 집합을 항상 반환합니다. ADO을 통해 데이터를 액세스할 경우 행 집합은 보다 다양하고 스크립트가 가능한 개체인 레코드 집합으로 변환됩니다.

.NET 응용 프로그램은 단지 다른 기능을 수행하는 다른 클래스를 사용합니다. DataReader 클래스는 연결된 상태에서 수행하는 간단하고 속도가 빠른 전진 전용 커서로 레코드 단위 기반 액세스를 제공합니다. 그리고 작업을 완료하면 명시적으로 연결을 끊어야 합니다. 반대로 DataSet 개체는 메모리 내부에 있는 연결이 끊긴 테이블의 컬렉션입니다. DataSetCommand 클래스에 의해 채워집니다. DataSet 개체의 컨텐트는 데이터 원본에서 복구된 DataSetCommand 클래스인 XML 스트림을 따릅니다.

다음 컬럼에서는 DataReader 및 DataSet 클래스에 대해 자세히 설명합니다.

데이터는 이진 형식을 사용하여 공급자에서 소비자로 이동합니다. OLE DB를 설치한 경우에는 COM 마샬링을 통해 이동하며 .NET에서는 관리 공급자가 XML 스트림을 반환합니다.

모든 공급자는 공급업체용 소유권으로 SQL에서 일반적으로 사용하는 쿼리 언어를 지원합니다. 이 쿼리 언어를 사용하여 데이터 원본의 업데이트 및 질의를 수행할 수 있습니다.

그러면 OLE DB 데이터 공급자와 .NET 데이터 공급자는 어떤 점이 다릅니까? 추상적으로 보면 두 공급자는 동일한 데이터 액세스 비전을 공유합니다. 그러나 관리 공급자는 더 간단하고 특수화되었기 때문에 다음과 같은 두 가지 이유로 더 나은 성능을 수행합니다. 첫째, 관리 공급자는 데이터를 가져오고 설정하기 위해 COM Interop 브리지를 사용하지 않습니다. 반면 OLE DB 공급자는 COM 구성 요소가 있으므로 이 단계에서는 선택할 사항이 없습니다. 둘째, 관리 공급자는 더 신속하게 행을 가져오고 설정하기 위해 일반적으로 데이터 원본 내부의 공급업체 정보를 사용합니다. 이 점은 또한 OLE DB 공급자가 어떤 기능을 수행하는지 보여주고 있습니다. 그러나 .NET의 OLE DB 공급자에서 사용하는 경우 COM 기반의 특성에 대한 대가를 지불해야 하며 데이터를 .NET 전용 클래스로 변환하기 위해 추가 코드가 필요합니다.


기존 관리 공급자
=================
.NET 프레임워크 베타 1에는 두 가지 관리 공급자가 있습니다. 하나는 SQL Server용(버전 7.0 이상)이고 다른 하나는 OLE DB 공급자를 통해 접근할 수 있는 모든 데이터 원본용입니다.

SQL Server 관리 공급자는 SQLDataReader, SQLDataSetCommand 및 SQLCommand와 같은 특정 클래스 뒤에 숨겨져 있습니다. 이러한 클래스는 저수준 SQL Server 파일 시스템에 직접적인 액세스를 수행합니다. 다음 그림은 이전의 일반 스키마를 SQL Server의 관리 공급자와 매핑한 공급자의 클래스 다이어그램입니다.

그림 2. SQL Server 관리 공급자의 클래스 다이어그램


OLE DB 관리 공급자는 Windows DNA 시스템의 ODBC에 대한 OLE DB 공급자처럼 .NET에서 동일한 역할을 수행합니다. 기본적으로 이전 버전과의 호환성을 포함하고 있으며, 그 실례로 모든 .NET 응용 프로그램은 기존 OLE DB 기반 데이터 원본을 대상으로 수행할 수 있습니다. 다음 그림은 OLE DB 관리 공급자의 클래스 다이어그램입니다.

그림 3. OLE DB 관리 공급자의 클래스 다이어그램


ADOxxx 클래스는 베타 2에서 OleDbxxx로 이름이 변경됩니다.
OLE DB 관리 공급자는 해당 호출자에게 .NET 클래스를 제공하지만 행을 가져오기 위해 지정된 OLE DB 공급자를 사용합니다. .NET 응용 프로그램과 기본 OLE DB 공급자(COM 개체) 간의 통신은 COM Interop 브리지를 통해 이루어집니다.

그리고 .NET에서 이 두 공급자를 통해 SQL Server 7.0 (또는 그 이상 버전) 테이블을 액세스할 수 있습니다. SQL Server의 관리 공급자는 데이터를 요청하기 위해 곧바로 DBMS 파일 시스템으로 이동합니다. 대신에 OLE DB 관리 공급자는 추가 코드 계층이 통과되도록 하는 SQLOLEDB OLE DB 공급자의 서비스에 의존합니다.

SQL Server가 아니라 다른 데이터 원본을 대상으로 하고 있는 경우 OLE DB 관리 공급자를 사용하는 것이 유일한 방법입니다. 이와 같은 동일한 채널을 통해 모든 ODBC 데이터 원본에 접근할 수 있습니다.

OLE DB 관리 공급자는 원시 OLE DB 공급자를 호출하는 COM Interop 브리지 위에 설치된 얇은 래퍼입니다. 호출을 설정하고 종료하는 것 외에 모듈은 나중에 .NET에서 처리할 DataSet 또는 ADODataReader 개체에 반환된 행 집합을 압축합니다.

.NET 코드 수준에서 원시 관리 공급자 또는 OLE DB 공급자를 통해 SQL Server 테이블을 액세스하는 것은 필수적으로 관련된 클래스의 접두사를 변경해야 합니다. 다음은 SQL Server의 코드 예제입니다.

Dim strConn, strCmd As String
strConn = "DATABASE=Northwind;SERVER=localhost;UID=sa;PWD=;"
strCmd = "SELECT * FROM Employees"
Dim oCMD As New SQLDataSetCommand(strCmd, strConn)
Dim oDS As New DataSet
oCMD.FillDataSet(oDS, "EmployeesList")

그리고 다음은 OLE DB 공급자 코드이며 볼드체는 SQL Server의 코드와의 차이점을 표시한 것입니다.


Dim strConn, strCmd As String
strConn = "Provider=SQLOLEDB;"
strConn += "DATABASE=Northwind;SERVER=localhost;UID=sa;PWD=;"
strCmd = "SELECT * FROM Employees"
Dim oCMD As New ADODataSetCommand(strCmd, strConn)
Dim oDS As New DataSet
oCMD.FillDataSet(oDS, "EmployeesList")

위의 두 코드를 보면 알 수 있듯이, 연결 스트링 및 명령 클래스에 대해서만 아주 근소한 차이가 있을 뿐입니다. 클래스 하나 또는 다른 클래스를 적용하여 차이가 나게 구성할 수도 있습니다.


OLE DB의 존재에 대한 질문
========================
.NET 관리 공급자는 데이터 액세스 기술 발전의 다음 단계라고 할 수 있습니다. 그러나 베타 1에는 데이터 원본용 관리 공급자를 작성하기 위한 문서화된 SDK가 없습니다. 베타 2를 기대하면서 OLE DB 및 .NET 에 대한 몇 가지 기본적인 질문을 살펴보겠습니다.

OLE DB를 위해 개발된 코드는 단지 레거시 코드인가? 기업들이 자체 데이터에 대해 공급자를 작성하려고 모든 노력을 하는 이유는 무엇인가?

OLE DB는 사장된 기술이 아닙니다. OLE DB는 여전히 다양한 기능, 범용 및 .NET 독립적 프로그래밍 인터페이스를 위한 기초적인 사양입니다. .NET에만 한정되는 것은 아니지만 잘 지원됩니다.

제공해야 할 사용자 지정 데이터가 있는 경우 .NET 및 관리 공급자의 역할을 무시할 수 없습니다. 그러면 데이터 공급자를 이용할 수 있는 가장 좋은 인터페이스는 무엇인가? 예를 들어 다음 주 월요일 오전 8시에 데이터를 제공하려면 어떻게 계획을 세워야 하는가?

.NET은 개방 표준을 사용하며 전적으로 XML을 기본으로 합니다. 소유권이 있는 경우 텍스트 기반 데이터를 제공하기 위해서는 사용자 지정 스키마 및 XML을 사용하여 게시를 고려할 수 있습니다. .NET에는 래퍼 클래스를 비롯하여 XML 데이터와 수행할 수 있는 많은 기능이 있습니다.

더 복잡한 데이터 저장소인 경우에는 .NET에 바운드되지 않을지도 모르는 더 많은 사용자를 접근해야 하기 때문에 OLE DB 공급자는 여전히 중요합니다. .NET 전용 응용 프로그램을 위해 관리 공급자는 안정적인 성능을 제공합니다. 관리 공급자용 SDK는 아직 출시되지 않았다는 것을 기억하십시오. 그러나 Microsoft는 곧 제공할 것을 약속합니다.

다음 컬럼에 소개할 데이터 공급자에서는 두 가지의 OLE DB 관리자 및 XML의 NET 래퍼 클래스에 대해 설명합니다. 저자의 견해는 COM Interop을 통해 OLE DB 공급자가 래핑된 .NET 클래스를 사용하는 것이 좋지 않다는 것입니다. 동일하면서도 잘 적용되는 원본 코드를 도입하는 것이 낫습니다. 이 경우 "물리적" 코드 재사용의 기능을 사용하려면 관리 C++가 아마 가장 적합한 언어일 것입니다.


OLE DB의 행로
=============
지금부터 약 2년 후에 증명될 다음과 같은 예측을 해봅시다. 결국 OLE DB는 XML의 선구자인 SGML(Standard Generalized Markup Language)과 같은 비교적 나쁜 결말이 될지도 모릅니다.

데이터 교환 기술 분야의 구원자로서 소개된 SGML은 일반인이 사용하기에 너무 어렵고 복잡했기 때문에 완전한 표준이 되지 못했습니다. 사실 SGML의 원리는 간소화되고 특수화된 XML이 소개된 이후에 많은 분야에 적용되었습니다.

저자의 예상으로는 .NET이 곧 업계를 주도할 것이고 OLE DB는 점차 그 중요성을 잃게 되어 사라지게 될 것입니다. 이러한 변화가 실제로 언제 나타날지 모르지만 확신합니다.

사례를 조만간에 소개할 것입니다. 계속 지켜봐 주십시오.


대화 상자: 레거시 코드
=====================
여러분은 아마 또 다른 차원의 시대에 살고 있는지도 모릅니다! 대부분의 경우 6개월 전 또는 후에 쓰여진 기존 ADO 코드로서 레거시 코드를 어떻게 정의할 수 있습니까? 베타 프로그램의 두 번째 단계도 아닌 .NET이라는 기술/플랫폼의 이름으로 어떻게 정의할 수 있습니까?

일상 생활에서도 어떤 활력소가 필요합니다.

현재 많은 DNA 시스템에서 사용되는 ADO 코드로 레거시 코드를 정의할 수 있습니까? 저자의 대답은 여전히 "예, 해야 할 작업입니다."이지만 확실히 당혹스런 답변입니다.

코드에 있어서 "레거시 코드"는 더 이상 플랫폼을 호스트하는 핵심 요소가 될 수 없습니다. 즉, NET의 출현으로 인해 이런 현상이 발생할 것입니다. 물론 .NET에서 기존 코드, 구성 요소 및 응용 프로그램을 통합하는 방식이 있을 것입니다.

.NET은 일종의 비폭력 혁명과 같이 앞으로 몇 년안에 Windows에서 현존하는 모든 소프트웨어의 인스턴스를 흡수할 것입니다. 이것은 대세이며 곧 적응될 것입니다. 앞에서 레거시 코드를 정의한 바와 같이, 코드의 수명에 관계없이 레거시 코드는 원본과 런타임 간의 정렬입니다.

.NET은 Windows 런타임을 변경합니다. COM 및 Windows SDK는 사장되지 않았지만 다른 모델을 기반으로 코드를 작성해야 합니다. 이 새로운 런타임 토대에 관계없이 처리할 수 있는 새 모델이 있습니다. 그리고 이 모델은 차후 Windows 모델이 될 것입니다.

Windows는 사장되지 않았지만 변경될 것입니다. COM도 사장되지 않았지만 .NET 클래스를 적용해야 하며, ADO도 아직 사용되고 있지만 ADO.NET의 .NET 기능이 ADO의 미래입니다.

.NET은 단순히 Windows 6.0이 아니며 ADO.NET은 ADO 3.0으로 명명할 수 있는 차원이 아닙니다. ADO.NET은 완전히 다른 새로운 플랫폼입니다. 그리고 나머지는 모두 다른 플랫폼 또는 통합된 경우 레거시 코드입니다.

레거시 코드는 제한된 수명이 없습니다. .NET이 실제로 출시되는 경우에도 사용자들은 이번 주 또는 6개월 후에 DNA 시스템을 작성하고 있을 것입니다. 하지만 이것이 확실히 잘못되었다고 또는 피해야 한다고 말할 수는 없습니다. 한마디로 시류에 역행한다고 볼 수 있습니다.

============================================
<마이크로소프트>사 자체의 보고서 내용, 땅야땅야님 블로그에서 퍼옴..
반응형

+ Recent posts