728x90

https://msdn.microsoft.com/en-us/library/323b6b3k.aspx?f=255&MSPPError=-2147217396


참고



size_t는 대상 플랫폼에 따라 unsigned __int64 또는 unsigned integer를 뜻한다.

CRTDEFS.H 또는 다른 include 파일에 의해 정의된다.



vcruntime.h

// Definitions of common types
#ifdef _WIN64
    typedef unsigned __int64 size_t;
    typedef __int64          ptrdiff_t;
    typedef __int64          intptr_t;
#else
    typedef unsigned int     size_t;
    typedef int              ptrdiff_t;
    typedef int              intptr_t;
#endif


#define의 유용성을 생각해보면 필요해 따라 type을 바꿔 쓸 수도 있을 것이다.

'Study > C' 카테고리의 다른 글

enum, auto, 구조체  (0) 2017.03.24
C 복습-콘솔 입출력  (0) 2017.02.11
c 복습  (0) 2016.11.03
파일의 분할과 헤더파일의 디자인  (0) 2016.08.30
선행처리기와 매크로2  (0) 2016.08.30
728x90

Arduino IDE 다운로드

https://www.arduino.cc/en/Main/Software




아두이노 웹 시뮬레이터

https://circuits.io/lab


// led 번갈아 깜박


led의 긴 핀은 Cathode(전류가 흘러나오는 쪽), 짧은 쪽이 Anode(전류가 흘러들어가는 쪽)이다.

led의 긴핀 (다리가 구부러진 쪽)을 D13에 짧은 쪽을 저항을 통해 GND에 연결한다.



void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second

  digitalWrite(12, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(12, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}



// fnd 0~9 표시



int a = 2, b = 3, c = 4, d = 5, e = 6, f = 8, g = 7;  // 선을 꽂을 때, 교차되지 않도록 f와 g를 바꿈
int led[7] = { a, b, c, d, e, f, g };

int digit[10][7] = { {1, 1, 1, 1, 1, 1, 0}, // 0
                     {0, 1, 1, 0, 0, 0, 0}, // 1
                     {1, 1, 0, 1, 1, 0, 1}, // 2
                     {1, 1, 1, 1, 0, 0, 1}, // 3
                     {0, 1, 1, 0, 0, 1, 1}, // 4
                     {1, 0, 1, 1, 0, 1, 1},
                     {0, 0, 1, 1, 1, 1, 1},
                     {1, 1, 1, 0, 0, 1, 0},
                     {1, 1, 1, 1, 1, 1, 1},
                     {1, 1, 1, 0, 0, 1, 1} };

void setup() {
  // put your setup code here, to run once:
  pinMode(a, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(c, OUTPUT);
  pinMode(d, OUTPUT);
  pinMode(e, OUTPUT);
  pinMode(f, OUTPUT);
  pinMode(g, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  for (int i=0; i<10; i++) {
    for (int j=0; j<7; j++) {
      digitalWrite(led[j], digit[i][j]);
    }
    delay(1000);
  }
}


// 건전지 전압 측정



//  택트 스위치로 LED 끄고 켜기


int sw = 2;
int led = 13;

void setup() {
  pinMode(sw, INPUT);
  pinMode(led, OUTPUT);
}

void loop() {
  if (digitalRead(sw) == HIGH)
  {
    digitalWrite(led, LOW);
  }
  else
  {
    digitalWrite(led, HIGH);    
  }
}



// pwm LED 단계적으로 밝아지게

아두이노에 pwm 표시가 있는 포트에 연결 (pwm 지원 아날로그 출력 포트에 연결)


analogWrite 함수를 사용한 pwm은 490Hz 주파수(1/490 sec 간격)로 HIGHT와 LOW를 오가며 전압을 변화시킨다.


밝기를 변화시킬 LED와 함께 사용할 저항 값은 다음과 같이 계산한다.


LED와 함께 사용할 저항 값 (Ω) = ( 전원 전압(V) - LED 규격 전압(V) )  /  정격 전류 (A)

     85 Ω =                   ( 5 V - 3.3 V )                 /   0. 02            


저항값이 꼭 정확히 맞아야 하는건 아니므로, 밝기 변화 단계는 적어지지만 무난하게 100 Ω 을 사용하면 된다.

byte n = 5;

void setup() {
  // put your setup code here, to run once:  
}

void loop() {
  for (int x = 0; x<n; x++)
  {
    analogWrite(9, x * 255 / n);  // pwm 아날로그 출력
    delay(1000);
  }
}


// 기울기 센서

void setup() { 
  pinMode(2, INPUT_PULLUP);
  pinMode(13, OUTPUT);
} 

void loop()
{ 
  boolean sw = false;

  while (sw == digitalRead(2));
  digitalWrite(13, LOW);
  delay(3000);
  digitalWrite(13, HIGH);
}


// piezo 스피커로 소리 출력

byte n = 5;

void setup() {
  // put your setup code here, to run once:  
}

void loop() {
  analogWrite(9, 255 / 2);
}


// PWM 아날로그 출력을 통한 모터 작동


int INA = 9; 
 
void setup() { }
 
void loop() { 
  for (int i=0; i<256; i+=5)  {
    analogWrite(INA, 255 - i);
    delay(100);
  }      
  delay(1000); 
}



'Study > Embedded' 카테고리의 다른 글

라즈베리 파이3, 기본 설정  (0) 2017.06.10
아두이노 LCD  (0) 2017.06.01
ATMEGA USART-C# App 연동  (0) 2016.12.12
7/21 Atmega128 포트/ win32 api  (0) 2016.07.21
7/8 LCD제어2  (0) 2016.07.08
728x90

사운드 관련 클래스 정의

using System.Runtime.InteropServices;
public class Win32
        {
            #region 사운드 관련
            [DllImport("winmm.dll")]
            public static extern int waveOutGetVolume(IntPtr hwo, out uint dwVolume);
 
            [DllImport("winmm.dll")]
            public static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume);
 
            public static void SetSoundVolume(int volume)
            {
                try
                {
                    int newVolume = ((ushort.MaxValue / 10* volume);
                    uint newVolumeAllChannels = (((uint)newVolume & 0x0000ffff| ((uint)newVolume << 16));
                    waveOutSetVolume(IntPtr.Zero, newVolumeAllChannels);
                }
                catch (Exception) { }
            }
 
            public static int GetSoundVolume()
            {
                int value = 0;
                try
                {
                    uint CurrVol = 0;
                    waveOutGetVolume(IntPtr.Zero, out CurrVol);
                    ushort CalcVol = (ushort)(CurrVol & 0x0000ffff);
                    value = CalcVol / (ushort.MaxValue / 10);
                }
                catch (Exception) { }
                return value;
            }
            #endregion
        }



폼의 생성자

public Form1()
        {
            InitializeComponent();
            formInit();
 
            lobbyBgm.PlayLooping();
            Win32.SetSoundVolume(5);    // 초기 볼륨 설정 (0~10)
 
            trackBar1.Value = Win32.GetSoundVolume();   // 트랙바의 값을 현재 볼륨값으로 설정
        }


트랙바 스크롤 이벤트

private void trackBar1_Scroll(object sender, EventArgs e)
        {
            int volume;
            volume = trackBar1.Value;
            
            Win32.SetSoundVolume(volume);
        }


'Study > C#' 카테고리의 다른 글

c# docx 에서 텍스트 얻기  (0) 2020.10.28
IP 주소 정수로 변환  (0) 2017.05.16
C# Thread  (0) 2017.04.24
C# MS-SQL 연동  (0) 2017.04.14
C# 네트워크 기본  (1) 2017.04.12
728x90
public string BringIP()
        {
            IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
            string ip = string.Empty;
 
            for (int i = 0; i < host.AddressList.Length; i++)
                if (host.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
                    ip = host.AddressList[i].ToString();
 
            return ip;
        }
      
 
        public Form1()
        {
            InitializeComponent();
            
            byte[] ip = BringIP().Split('.').Select(s => Byte.Parse(s)).ToArray();
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(ip);
            }
            uint num = BitConverter.ToUInt32(ip, 0);
 
            txtServerIP.Text = num.ToString();
        }


'Study > C#' 카테고리의 다른 글

c# docx 에서 텍스트 얻기  (0) 2020.10.28
c#트랙바를 통한 볼륨 조절  (0) 2017.05.18
C# Thread  (0) 2017.04.24
C# MS-SQL 연동  (0) 2017.04.14
C# 네트워크 기본  (1) 2017.04.12
728x90

Thread 관련 예제


using System;
using System.Threading;
 
namespace Study_CS_ConsoleApp
{
    class Program
    {
        static Thread threadA = new Thread(FuncA);
        static Thread threadB = new Thread(FuncB);
        static Thread threadC = new Thread(FuncC);
 
 
        static void FuncA()
        {
 
            for(int i=0; i<50; i++)
            {
                if (i > 30)
                    threadA.Abort();
 
                Console.WriteLine("A : Count = " + i);
            }
        }
 
        static void FuncB()
        {
            for (int i=0; i<50; i++)
            {
                System.Threading.Thread.Sleep(100);
                Console.WriteLine("B : Count = " + i);
            }
        }
 
        static void FuncC()
        {
            for (int i = 0; i < 50; i++)
            {   
                Console.WriteLine("C : Count = " + i);
                threadC.Suspend();
            }
        }
 
        static void Main(string[] args)
        {
            threadA.Start();
            threadB.Start();
            threadC.Start();
        }
    }
}



suspend()와 resume()


using System;
using System.Threading;
 
namespace Study_CS_ConsoleApp
{
    class Program
    {
        static Thread threadA = new Thread(FuncA);
        static Thread threadB = new Thread(FuncB);
        
        static void FuncA()
        {
 
            for(int i=0; i<=10; i++)
            {
                System.Threading.Thread.Sleep(100);
                Console.WriteLine("A : Count = " + i);
 
                if(i == 0)  // 조건문이 없으면 또 다시 Suspend
                threadA.Suspend();
            }
        }
 
        static void FuncB()
        {
            for (int i=0; i<=10; i++)
            {
                System.Threading.Thread.Sleep(100);
                Console.WriteLine("B : Count = " + i);
            }
            threadA.Resume();
        }
 
        static void Main(string[] args)
        {   
            threadA.Start();
            threadB.Start();
        }
    }
}


delegate


using System;
using System.Threading;
 
namespace Study_CS_ConsoleApp
{
    class Program
    {
        // 델리게이트 선언
        public delegate int cal(int a, int b);
 
        public static int Plus(int a, int b) { return a + b; }
        public static int Minus(int a, int b) { return a - b; }
 
        static void Main(string[] args)
        {
            cal plus = new cal(Plus);
            cal minus = new cal(Minus);
 
            Console.WriteLine(plus(46));
            Console.WriteLine(minus(115));
        }
    }
}



'Study > C#' 카테고리의 다른 글

c#트랙바를 통한 볼륨 조절  (0) 2017.05.18
IP 주소 정수로 변환  (0) 2017.05.16
C# MS-SQL 연동  (0) 2017.04.14
C# 네트워크 기본  (1) 2017.04.12
C# 예외처리, delegate  (0) 2017.04.10
728x90

192.168.35.1  로 접속


id : admin

pwd : (공유기 유선 MAC 뒷자리 6자)_admin     /* 예) 95E999_admin // admin을 제외한 문자열은 모두 대문자로 입력  */


인터넷 연결 설정에서 MAC Clone을 Enabled (활성화)


MAC Address List에서 다른 Num 체크박스에 체크 후 적용



728x90


using System;
using System.Data.SqlClient;
 
namespace CS_ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            SqlConnection con = new SqlConnection();
            //SqlCommand cmd = new SqlCommand();
            Console.WriteLine("연결시도");
 
            con.ConnectionString = "server=210.119.12.79,1617; database=ADO; uid=sa; pwd=it17";
 
            con.Open();
            SqlCommand cmd = new SqlCommand("SELECT * FROM ADO", con);
 
            Console.WriteLine("DB 연결 성공");
 
            /*
            Console.WriteLine("테이블 만들기 시도");
            cmd.Connection = con;
            cmd.CommandText = "CREATE table 성적표 (" +
                "번호 int primary key," +
                "이름 varchar(6) not null," +
                "국어 int," +
                "영어 int," +
                "수학 int)";
            
 
            cmd.ExecuteNonQuery();
            Console.WriteLine("테이블 만들기 성공");
            */
 
            Console.WriteLine("데이터 추가 시도");
            cmd.CommandText = "INSERT INTO 성적표 VALUES(1, '추경호', 95, 100, 85)";
            cmd.ExecuteNonQuery();
 
            cmd.CommandText = "INSERT INTO 성적표 VALUES(2, '조수현', 100, 80, 85)";
            cmd.ExecuteNonQuery();
            con.Close();
        }
    }
}



using System;
using System.Data.SqlClient;
 
namespace CS_ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            SqlConnection con = new SqlConnection();
            Console.WriteLine("DB 연결시도");
            con.ConnectionString = "server=210.119.12.79,1617; database=ADO; uid=sa; pwd=it4321";
            con.Open();
            Console.WriteLine("DB 연결 성공");
 
            SqlCommand cmd = new SqlCommand(); 
            
            cmd.Connection = con;
 
            Display(cmd);
 
            cmd.CommandText = "update 성적표 set 영어=@영어,수학=@수학 " +
                "where 이름='조수현'";
            cmd.Parameters.AddWithValue("@영어"99);
            cmd.Parameters.AddWithValue("@수학"88);
            cmd.ExecuteNonQuery();
            Display(cmd);
 
            cmd.CommandText = "DELETE FROM 성적표 WHERE 이름 = @이름";
            cmd.Parameters.AddWithValue("@이름""조수현");
            cmd.ExecuteNonQuery();
            Display(cmd);
 
            con.Close();
        }
 
        static void Display(SqlCommand cmd)
        {
            SqlDataReader sqlReader = null;
            cmd.CommandText = "select * from 성적표";
            sqlReader = cmd.ExecuteReader();
 
            for (int i = 0; i < sqlReader.FieldCount; i++)
            {
                Console.Write("{0,7}", sqlReader.GetName(i));
            }
            Console.WriteLine();
 
            string field = "";
            while (sqlReader.Read())
            {
                for (int i = 0; i < sqlReader.FieldCount; i++)
                {
                    field = sqlReader.GetName(i);
                    Console.Write("{0,8}", sqlReader[field]);
                }
                Console.WriteLine();
            }
            sqlReader.Close();
        }
    }
}



윈폼


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace DB3
{
    public partial class Form1 : Form
    {
        SqlConnection con;
        SqlDataAdapter mSqlDataAdapter;
        DataSet mDataSet;
        DataTable mDataTable;
 
        public Form1()
        {
            InitializeComponent();
 
            try
            {
                if (con == null)
                    con = new SqlConnection();
 
                textBox1.AppendText("DB연결 시도\r\n");
                con.ConnectionString =
                "server=PKNU1\\SQLEXPRESS;database=ADO;uid=sa;pwd=1234";
                con.Open();
                textBox1.AppendText("DB연결 성공\r\n");
            }
            catch { textBox1.AppendText("DB연결 실패\r\n"); }
            updateDataView();
        }
 
        public void updateDataView()
        {
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = con;
            cmd.CommandText = "select * from 성적표";
 
            mSqlDataAdapter = new SqlDataAdapter();
            mSqlDataAdapter.SelectCommand = cmd;
 
            mDataSet = new DataSet("성적관리");
            mSqlDataAdapter.Fill(mDataSet, "성적표");
 
            mDataTable = mDataSet.Tables["성적표"];
            dataGridView1.DataSource = mDataTable;
        }
    }
}




'Study > C#' 카테고리의 다른 글

IP 주소 정수로 변환  (0) 2017.05.16
C# Thread  (0) 2017.04.24
C# 네트워크 기본  (1) 2017.04.12
C# 예외처리, delegate  (0) 2017.04.10
C# 인터페이스  (0) 2017.04.07
728x90

Ctrl 누른채로 r + r : 이름 바꾸기


편집 관련 단축키

편집 관련 단축키들은 익혀두면 다른 문서를 작성 할때도 많이 도움이 될 것이다.

문서 편집 관련 단축키들은 사용하면 사용할 수록 코딩 속도가 빨라진다.

 

 

Ctrl + F : 찾기

중요도 : ★★★☆☆

활용 : 특정 클래스, 함수, 변수 등을 검색한다.

 

 

 

 

Ctrl + Shift + F : 파일에서 찾기

중요도 : ★☆☆☆☆

활용 : 특정 클래스, 함수, 변수 등을 검색한다. 현제 프로젝트가 아닌 파일에서도 찾을 수 있다.

 

 

 

 

Ctrl + Space : NameSpace

중요도 : ★★★★★

활용 : 현재 접근 가능한 클래스명, 함수명, DEFINE문 등의 목록을 보여준다.

         코드를 치는 도중 Ctrl + Space를 누르면 이전에 선언된 것과 

         가까운 목록을 보여주며 선택을 함으로써 쉽게 완성이 가능하다.

         목록이 하나뿐이라면 그것으로 자동 완성 해준다.

 

 

 

 

Ctrl + Shift + Space : Parameter

중요도 : ★★★★★

활용 : 커서가 클래스명의 뒤에 있을 때 접근가능한 변수, 함수 목록을 보여준다.

         코드를 치는 도중 Ctrl + Shift + Space를 누르면 이전에 선언된 것과

         가까운 목록을 보여주며 선택을 함으로써 쉽게 완성이 가능하다.

         목록이 하나뿐이라면 그것으로 자동 완성 해준다.

 

 

 

 

Home : 커서가 위치한 줄의 코드 시작 위치로

중요도 : ★★★★★

활용 : 커서의 위치와 관계없이 해당 줄의 코드 시작위치로 커서를 옮긴다.

         블록을 잡기 위해서, 커서의 빠른 이동 등에 많이 사용된다.

 

 

 

 

End : 커서가 위치한 줄의 코드 끝 위치로

중요도 : ★★★★★

활용 : 커서의 위치와 관계없이 해당 줄의 코드 마지막위치로 커서를 옮긴다.

 

 

 

 

Shift + Home : 커서가 위치한 줄 모두 블록

Shift + End : 커서가 위치한 줄 모두 블록

중요도 : ★★★★★

활용 : 커서 위치가 가장 앞에 있다면 Shift + End를 이용해 그 줄을 블록하고 

         커서 위치가 가장 뒤에 있다면 Shift + Home를 이용해 그 줄을 블록한다.

 

 

 

 

Shift + ← or → or ↑ or ↓ : 블록 잡기

중요도 : ★★★★☆

활용 : 여러 줄을 블록할 때 많이 사용한다.

 

 

 

 

드래그 + Alt : 현재 커서 위치부터 움직인 커서 위치까지 블록

중요도 : ★★★★☆

활용 : 마우스 드래그 중 Alt를 누르면 드래그하는 영역을 사각형으로 봤을 때 그 영역을 블록하게 된다.

         특정 부분을 선택하고 싶거나, 탭을 먹이고 싶을 때 많이 사용된다.

 

 

 

 

Ctrl + ←, → : 구분단위로 커서 이동

중요도 : ★☆☆☆☆

활용 : 현재 줄에서 커서를 좌우로 이동할 때 변수, 공백, 탭, 등의 구분단위로 이동하게된다.

         보다 빠른 커서위치를 조정하고, 블록할 때 사용된다.

 

 

 

 

Ctrl + Shift + ← or → : 구분단위로 블록

중요도 : ★☆☆☆☆

활용 : 현재 줄에서 블록을 할 때 변수, 공백, 탭 등의 구분단위로 블록영역을 설정한다.

         보다 빠르게 블록 영역을 설정할 때 편리하다.

 

 

 

 

Ctrl + M, L : 전체 + 버튼으로 만들기

중요도 : ★★★☆☆

활용 : 현재 소스 전체를 {}영역 별로 +버튼으로 만들어준다.

         +버튼은 소스가 삭제되는 것은아니라 감춰두는 것으로 볼 수 있다.

         소스가 길어 함수 정의나 클래스 정의 부분을 빨리 찾고 싶을 때 많이 사용된다.

 

 

 

 

Ctrl + M, M : 커서 위치가 속한 곳을 + 버튼으로 만들기

중요도 : ★★☆☆☆

활용 : 커서의 위치를 {}단위로 판단하여 커서가 속한 곳을 +버튼으로 만든다.

 

 

 

 

Ctrl + M, L : 선택된 곳을 +버튼으로 만들기

중요도 : ★★☆☆☆

활용 : 블록을 선택된 영역을 +버튼으로 만든다.

 

 

 

 

Shift + Delete : 커서가 위치한 줄 삭제

중요도 : ★★★★☆

활용 : 커서가 위치한 줄을 삭제한다.

         빠르게 현재 줄을 삭제할 때 많이 활용된다.

 

 

 

 

Ctrl + L : 커서가 위치한 줄 삭제, 선택된 줄단위로 삭제

중요도 : ★★★★☆

활용 : 위 단축키와 비슷하지만 영역을 선택했을 때 여러줄을 줄단위로 삭제 한다.

 

 

 

 

Ctrl + K, C : 선택 영역 주석 달기

중요도 : ★★★★☆

활용 : 선택 영역의 주석을 한 단계씩 추가한다.

 

 

 

 

Ctrl + K, U : 선택 영역 주석 없애기

중요도 : ★★★★☆

활용 : 선택 영역을 주석을 한 단계씩 감소시킨다.

 

 

 

 

 

Alt + F8 : 선택 영역 코드 탭 정리하기

중요도 : ★★★★☆

활용 : 선택한 영역의 코드들의 탭이 뒤죽박죽일 때 사용하면 편리하다.

 

 

 

 

 

 

 

디버깅 관련 단축키

 

F7 : 빌드

중요도 : ★★★☆☆

활용 : 이번 빌드 상태와 비교하여 수정된 소스에 대해 다시 빌드한다.

 

 

 

 

Ctrl + Alt + F7 : 전체 다시 빌드

중요도 : ★★★☆☆

활용 : 현재 솔루션 전체를 다시 빌드한다. 링크가 꼬엿을 때 외엔 잘 사용하지 않는다.

 

 

 

 

F5 : 빌드 + 실행

중요도 : ★★★★★

활용 : F7을 누른후 실행한 결과와 같다.

 

 

 

 

Ctrl + F5 : 빌드 없이 실행

중요도 : ★☆☆☆☆

활용 : 최근에 빌드된 상태의 실행 파일을 실행시킨다.

         소스 수정없이 다시 실행 시키고 싶을 때 빌드 시간 없이 실행 하므로 빠르다

 

 

 

 

F9 : 브레이크 포인트 설정

중요도 : ★★★★★

활용 : 현재 커서가 위치한 줄에 중단점을 설정한다.

         중단점이 걸리면 디버그시 해당 코드를 실행하기전에 중지되어 사용자에게 코드 위치를 보여준다.

 

 

 

 

F10 : 줄단위 실행

중요도 : ★★★★★

활용 : 디버깅 모드에서 현재 디버깅하고있는 소스의 줄단위로 진행 시킨다.

 

 

 

 

F11 : 코드 단위 실행

중요도 : ★★★★★

활용 : 디버깅 모드에서 현재 진행중인 커서위치의 코드를 실행한다.

         커서위치의 코드내에 함수가 있다면 그 함수의 내부로 들어가게 된다.

 

 

 

 

F12 : 정의로 이동

중요도 : ★★★★★

활용 : 변수, 함수, 클래스 등의 선언부로 이동한다.

         눈에 보이는 변수, 함수 등의 정체를 확인하는데 많이 사용된다.

 

 

 

 

Ctrl + '-'키 : 이전 커서 위치로

중요도 : ★★★★★

활용 : 이전 커서위치로 이동하게 된다.

         보통 F12로 변수를 탐색한후, 다시 돌아오는데 많이 사용한다.

 

 

 

 

Ctrl + Shift + '-'키 : 다음 커서 위치로

중요도 : ★☆☆☆☆

활용 : 위의 단축키와 반대 되는 개념이다.

 

 

 

 

Ctrl + F2 : 커서가 위치한 줄에 책갈피 설정

중요도 : ★★★☆☆

활용 : 현재 문서에서 커서가 위치한 줄에 책갈피를 설정한다.

         책갈피는 관심있는 코드를 메모해놓고 쉽게 접근하기 위해 사용한다.

 

 

 

 

F2 : 다음 설정된 책갈피로 커서 이동

중요도 : ★★★☆☆

활용 : 현재 문서에서 설정된 책갈피가 있을 때 순차적으로 책갈피를 탐색한다.

 

 

 

 

Ctrl + Shift + F2 : 설정된 책갈피 모두 삭제

중요도 : ★★★☆☆

활용 : 현재 문서에 설정되어 있는 책갈피를 모두 삭제한다.

 

 

 

 

Ctrl + F10 : 커서 위치까지 실행

중요도 : ★★☆☆☆

활용 : 현재 커서가 위치한 곳까지 실행하게 된다.

         편집상태라면 빌드 + 커서 위치까지 실행된다.

         한손으로 누르기 힘든 단축키라 우클릭 메뉴를 이용해도 좋다.

 

 

 

 

 

 

 

기타

 

마우스 우클릭 - Find All Refrence : 모든참조 찾기

중요도 : ★★★★☆

활용 : 현재 커서가 위치한곳의 변수나 함수등이 사용된 곳을 프로잭트에서 모두 찾아 표시한다.

         LifeCycle 을 알아보는데도 좋다.

 

 

 

 

Alt + P + P : 프로젝트 속성

중요도 : ★☆☆☆☆

활용 : 프로젝트의 속성을 본다. 프로젝트 속성을 보는일은 많이 없으므로 큰 활용도는 없다.

 

 

 

 

마지막으로 지금까지 단축키 목록을 나열하겠다.

 

Ctrl + F : 찾기

Ctrl + Shift + F : 파일에서 찾기

Ctrl + Space : NameSpace

Ctrl + Shift + Space : Parameter

Home : 커서가 위치한 줄의 코드 시작 위치로

End : 커서가 위치한 줄의 코드 끝 위치로

Shift + Home : 커서가 위치한 줄 모두 블록

Shift + End : 커서가 위치한 줄 모두 블록

Shift + ← or → or ↑ or ↓ : 블록 잡기

드래그 + Alt : 현재 커서 위치부터 움직인 커서 위치까지 블록

Ctrl + ←, → : 구분단위로 커서 이동

Ctrl + Shift + ← or → : 구분단위로 블록

Ctrl + M, L : 전체 + 버튼으로 만들기

Ctrl + M, M : 커서 위치가 속한 곳을 + 버튼으로 만들기

Ctrl + M, L : 선택된 곳을 +버튼으로 만들기

Shift + Delete : 커서가 위치한 줄 삭제

Ctrl + L : 커서가 위치한 줄 삭제, 선택된 줄단위로 삭제

Ctrl + K, C : 선택 영역 주석 달기

Ctrl + K, U : 선택 영역 주석 없애기

 

F7 : 빌드

Ctrl + Alt + F7 : 전체 다시 빌드

F5 : 빌드 + 실행

Ctrl + F5 : 빌드 없이 실행

F9 : 브레이크 포인트 설정

F10 : 줄단위 실행

F11 : 코드 단위 실행

F12 : 정의로 이동

Ctrl + '-'키 : 이전 커서 위치로

Ctrl + Shift + '-'키 : 다음 커서 위치로

Ctrl + F2 : 커서가 위치한 줄에 책갈피 설정

F2 : 다음 설정된 책갈피로 커서 이동

Ctrl + Shift + F2 : 설정된 책갈피 모두 삭제

Ctrl + F10 : 커서 위치까지 실행

Alt + F8 : 선택 영역 코드 탭 정리하기

 

마우스 우클릭 - Find All Refrence : 모든참조 찾기

Alt + P + P : 프로젝트 속성



728x90


C# 네트워크 프로그래밍


참고 도서 : 가볍게 시작하는 리얼 C# 프로그래밍


실 세계의 집주소는 네트워크에서는 IP 주소에 비유할 수 있다.

192.168.0.32


192는 가장 큰 범위 주소, 뒤로 갈수록 작은 범위의 주소이다.

ip주소와 Port 번호를 이용해 연결하며, Port 번호는 이름이라고 할 수도 있을 것이다.


TCP

TCP는 연결 지항형 서비스로, 데이터 전송 전에 Hand Shake를 통해 상대방과 연결을 형성한다.



UPD

UDP는 Hand Shake가 필요하지 않으며, 비연결형 서비스이므로 상대방과 1:1 회선이 형성되지 않는다. 

패킷에 상대방의 주소를 입력해 네트워크를 전송하며, 이는 편지에 비유할 수 있다. 통화는 바로 서로간 연결을 하지만, 편지는 써서 우체통에 넣을 뿐이니 말이다.



TCP의 혼잡 제어(Congestion Control)

특정 TCP 연결이 과도한 양의 데이터를 전송하려하면, 송신측의 TCP가 전송하려는 양의 데이터를 조절해서 (통신하는 호스트들 사이에)
네트워크 자원이 폭주되는 것을 방지한다.


TCP의 신뢰적 데이터 전달(Reliable data transfer)

TCP는 데이터가 순서대로, 정확하게 전달되는 것을 보장한다. TCP 연결이 이렇듯 많은 기능을 지원하지만, 

UPD에 비해선 연결이 무겁고 데이터 전송에 더 큰 비용이 든다. (흐름 제어, 순서번호, 확인 응답 등의 메커니즘을 사용하므로)


이런 이유로 UDP는 화면 공유 등에 주로 이용되고, TCP는 채팅 프로그램에 많이 사용된다.






내 PC의 IP 주소 출력하기

using System;
using System.Net;
 
 
namespace Network
{
    class Program
    {
        static void Main(string[] args)
        {
            string hostName = Dns.GetHostName();
            Console.WriteLine(hostName);
 
            IPHostEntry host = Dns.GetHostEntry(hostName);
            Console.WriteLine(host.AddressList[1].ToString());
 
            for (int i = 0; i < host.AddressList.Length; i++)
            {
                string myIPAddress = host.AddressList[i].ToString();
                Console.WriteLine(myIPAddress);
            }
        }
    }
}



네트워크 프로그래밍의 여러 클래스들


IPAddress 클래스


 도트 4자리 표기법의 IP 주소 예) 192.168.210.21


IPAddress 객체의 초기화 

IPAddress ipAddress = IPAddress.Parse("192.168.210.21");

IPAddress(Int64) // Int64로 지정된 주소 사용


.Parse // IP 주소 문자열을 IPAddress 인스턴스로 변환



IPEndPoint 클래스

하나의 컴퓨터에는 여러 프로그램이 동시 동작하므로, 원하는 프로그램을 찾기위해 포트 번호가 필요하다.

IPEndPoint는 특정 컴퓨터의 프로그램을 가리키는 클래스이다.


IPAddress ipAddress = IPAddress.Parse("192.168.210.21");
            IPEndPoint ipep = new IPEndPoint(ipAddress, 9999);

소켓 클래스

소켓 클래스는 실제 서버와 클라이언트를 구축하기 위해 필요한 인터페이스이다. 

소켓은 서로 다른 OS간에 네트워크 통신을 가능하게 해주며, 네트워크 전문 지식이 없이도 프로그래밍이 가능하게 한다.


이 과정을 크게 잡으면 다음과 같다.

1. 서버에서 소켓 생성 및 서버 설정 후 접속 대기

2. 접속이 일어나면 데이터 전송이 발생하고 소켓을 닫음



서버의 구현


이미지나 동영상 등의 전송을 위해선 byte로 데이터를 주고 받아야 한다.

using System; using System.Text; using System.Net; using System.Net.Sockets; namespace TCP_Server {     class Program     {         static void Main(string[] args)         {             Socket server = null;             Socket client = null;             byte[] data = new byte[1024];             // 3317포트에 대해선 모든 형태의 ip에 접속 허가             IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9999);             server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);             server.Bind(ipep);  // ipep를 통해 서버 소켓과 결합             server.Listen(10);  // 최대 접속 가능한 클라이언트의 수를 지정 후, 대기             Console.WriteLine("서버 시작 \n 클라이언트 접속 대기.");             // 클라이언트 접속 대기, 동기화 상태 진입. 접속이 일어나면 클라이언트 소켓이 반환             client = server.Accept();             Console.WriteLine("클라이언트 접속 완료.");             // 접속한 클라이언트로부터 데이터 수신, DATA 변수 BYTE 배열 형태로 저장             client.Receive(data);             Console.WriteLine("클라이언트로부터 데이터 수신. \n 메시지 : "                 + Encoding.Default.GetString(data));             // 클라이언트와 서버 소켓을 각각 닫는다.             client.Close();             server.Close();         }     } }



클라이언트의 구현

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
 
namespace TCP_Client
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] data = new byte[1024];
 
            IPAddress ipAddress = IPAddress.Parse("210.119.12.79"); // 접속할 서버의 IP 주소            
            IPEndPoint ipep = new IPEndPoint(ipAddress, 9999); // 1433은 port번호, 특정 애플리케이션을 지정
 
            // 서버 소켓 생성
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
                ProtocolType.Tcp);
 
            Console.WriteLine("서버 접속...");
 
            // 서버 접속
            server.Connect(ipep);
            Console.WriteLine("서버 접속 완료.");
 
            data = Encoding.Default.GetBytes("클라이언트에서 보내는 메시지");
            server.Send(data);
            Console.WriteLine("서버에 데이터 전송");
 
            server.Close();
        }
    }
}


비동기화를 위한 thread 적용

동기화는 어떤 입력이 들어올 때까지 프로그램의 제어가 멈추어져 있으므로, 네트워크 접속에서는 비효율적이고 불편함을 초래한다.

반면에, 비동기화는 작업을 요청한 뒤 결과의 수신 여부와 상관없이 다음 작업을 곧바로 진행하므로 실시간 처리와 다중 접속 형태에 알맞다.


비동기화를 위해 thread를 이용할 수 있으며, 하나의 프로그램을 두 개 이상의 흐름으로 나누어 병렬로 실행할 수 있게 된다.

(하나의 thread는 Accept() 메소드를 실행하고, 기존의 프로그램 제어는 다른 thread가 담당)



커널 버퍼

https://colorscripter.com/s/dbnDSsE

위의 소스에서 Receive() 메소드는 상대에게서 바로 데이터를 받아오는 것이 아니다. 


Receive() 메소드를 호출하기 전에 이미 커널 버퍼에 데이터는 수신되어 있고, Receive() 메소드를 호출함으로써 가져오는 것이다.

이는 자원을 효율적으로 가져오기 위함이지만 문제가 있다. 


몇 번의 데이터를 수신하였는지 알 수 없고,  얼마 만큼 데이터를 한번에 처리해야 할지 알수 없는 것이다. 

이를 해결하기 위해서 패킷을 정의할 필요가 있다.



패킷의 정의

패킷은 네트워크 전송에 있어서 하나의 단위이다.


보통 TCP 통신을 통해 패킷을 전송할 때는 크게 두 가지 형태가 있다. 


여러 패킷을 모아 한번에 전송하거나, 하나의 패킷을 나누어서 여러 번에 걸쳐 전송하는 것이다. 

첫 번째는 데이터 크기가 작을 때 자원을 효율적으로 사용하기 위함이고, 두 번째는 데이터 크기가 클 때 내부 버퍼 용량과 전송 실패시의 부담을 고려한 것이다.



패킷의 정보 구성

데이터 패킷은 Header와 Body로 구성된다. 


헤더에는 한 패킷의 크기를 나타내는 정보가 담겨있다. 데이터 처리시 이 부분을 먼저 읽게 된다. 

바디에는 데이터가 들어있다.



필요에 따라 하나의 패킷이 다른 패킷에 포함될 수도 있다. 


패킷을 수신할 때, 패킷을 처리해 원하는 결과값을 얻을 것이다. 데이터의 종류는 수신 메시지 외에도 여러가지가 있다.

그렇기 때문에 패킷에는 데이터의 종류를 나타내는 정보도 담을 필요가 있다.


패킷 2는 데이터의 종류를 나타내는 헤더와 패킷 1로 구성될 수도 있다. 

(패킷 2 = 데이터의 종류를 나타내는 헤더 + 헤더와 데이터로 구성된 패킷 1)


패킷2의 헤더를 읽고 난 뒤에는 데이터의 종류를 알기에 패킷1의 데이터를 어디에서 처리할지 알 수 있다.

그 다음은 패킷1의 헤더를 통해 실제 데이터 크기를 알고 남은 데이터를 읽게 된다.



패킷1의 헤더에는 데이터의 총 크기가 담겨 있다. 

만약 수신한 데이터가 총 크기보다 작을 경우, 남은 데이터를 모두 읽을 때까지 반복하여 Receive() 함수를 호출하면 될 것이다.



패킷 개념을 적용한 소스는 다음과 같다. 우선 패킷으로 데이터를 수신하도록 Receive 함수의 일부분이 바뀌었다.

private void Receive()  // 상대 호스트로부터 데이터 수신 {     ( ... 생략)         //패킷 개념 적용을 위해 주석처리         //mClientSocket.Receive(data, SocketFlags.None);          data = ReceiveData();   // 정의한 패킷으로 데이터 수신                                                      message = Encoding.Default.GetString(data); // 수신데이터 string 형태로 데이터 변환         mChatWnd.ReceiveMessage(message);   // chat창에 메시지 전달                                     } }

다음과 같이 Send() 메소드의 일부분이 바뀌고 실질적인 데이터 전송은, 추가된 SendData 메소드를 통하도록 바뀌었다.

public void Send(string message)
{
    (... 생략)
 
    data = Encoding.Default.GetBytes(message);
    //mClientSocket.Send(data, 0, data.Length, SocketFlags.None);
    SendData(data);
}    


패킷 헤더의 크기를 상수로 정의하고 다음과 같이 패킷을 통한 전송/수신 메소드들을 추가하도록 한다.

private const int PACKET_HEADER_SIZE = 4;               // 패킷 해더 크기
 
        private byte[] ReceiveData()
        {
            byte[] headerBuffer = new byte[PACKET_HEADER_SIZE];
            byte[] dataBuffer = null;
 
            int totalDataSize = 0;  // 전체 데이터 크기
            int accumulatedDataSize = 0// 누적 수신한 데이터 크기
            int leftDataSize = 0;       // 미 수신 데이터 크기
            int receivedDataSize = 0;   // 총 수신한 데이터 크기
 
            // 데이터 수신. Receive 메소드 호출로 수신한 데이터 크기 저장
            receivedDataSize = mClientSocket.Receive(headerBuffer, 0, 
                PACKET_HEADER_SIZE, SocketFlags.None);
 
            // BitConverter 클래스의 메소드를 사용하기 위해 using System; 추가
            totalDataSize = BitConverter.ToInt32(headerBuffer, 0);
 
            leftDataSize = totalDataSize;
            dataBuffer = new byte[totalDataSize];
 
            while (leftDataSize > 0)
            {                
                receivedDataSize = mClientSocket.Receive(dataBuffer, accumulatedDataSize,
                    leftDataSize, 0); // 데이터 수신
 
                accumulatedDataSize += receivedDataSize; // 총 누적 수신 데이터
                leftDataSize -= receivedDataSize; // 남은 미 수신 데이터
            }
 
            return dataBuffer;  // 수신된 데이터 반환
        } 
 
        private void SendData(byte[] dataBuffer)
        {
            byte[] headerBuffer = new byte[PACKET_HEADER_SIZE];
 
            int totalDataSize = 0;  // 전체 데이터 크기
            int accumulatedDataSize = 0// 누적 전송한 데이터 크기
            int leftDataSize = 0;       // 미 전송 데이터 크기
            int sentDataSize = 0;   // 전송한 데이터 크기
 
            totalDataSize = dataBuffer.Length;
            leftDataSize = totalDataSize - sentDataSize;
                        
            headerBuffer = BitConverter.GetBytes(totalDataSize); // 전송할 데이터 총 크기
            mClientSocket.Send(headerBuffer);   // 전체 데이터 크기 전송
            
            while (leftDataSize > 0)
            {
                sentDataSize = mClientSocket.Send(dataBuffer, accumulatedDataSize,
                    leftDataSize, SocketFlags.None); // 데이터 전송
 
                accumulatedDataSize += sentDataSize; // 총 누적 전송 데이터
                leftDataSize -= sentDataSize; // 남은 미 전송 데이터
            }
        }

이렇게 패킷 개념을 적용해 프로그램을 작성하면 대용량의 데이터 전송/수신시에도 더 안정적으로 작동할 수 있게 된다.

좀 더 세심하게 예외처리까지 한다면 훨씬 안정적인 프로그램이 될 것이다.



c# winform 텍스트 박스 글씨 *로 보이기

TextBox 속성 중 PasswordChar에 *를 입력하면 된다. 이는 로그인 폼의 패스워드 입력을 위한 것이다.

'Study > C#' 카테고리의 다른 글

C# Thread  (0) 2017.04.24
C# MS-SQL 연동  (0) 2017.04.14
C# 예외처리, delegate  (0) 2017.04.10
C# 인터페이스  (0) 2017.04.07
C# 클래스, 메소드  (0) 2017.04.04
728x90

try~catch~finally

using System;
 
namespace Study
{
    class Program
    {
 
        static void Main(string[] args)
        {
            Console.WriteLine("입력 : ");
            string input = Console.ReadLine();
 
            try
            {
                int index = int.Parse(input);
                Console.WriteLine("입력 숫자 : " + index);
            }
            catch (Exception e)
            {
                Console.WriteLine("예외 발생 (int형이 아님)");
                Console.WriteLine(e.GetType());
                return;
            }
            finally
            {
                Console.WriteLine("프로그램 종료");
            }
        }
    }
}

catch에서 return하여 finally 절은 무조건 실행된다.(finally 가 없다면 "프로그램 종료" 문구가 나타나지 않고 종료될 것이다).

finally 절에서 return 키워드 같이 finally 절의 본문을 벗어나는 키워드는 사용할 수 없다.



throw 키워드


예외를 강제로 발생시킨다.

throw new Exception();



윈폼 예외처리


위와 같이 리스트 박스와 콤보박스를 이용해 윈폼을 디자인한다. 


그 다음 Product 클래스를 만들고 다음과 같이 작성한다.

class Product
{
    public string Name { getset; }
    public int Price { getset; }
}



콤보박스와 리스트 박스에 데이터 바인딩을 한다. 데이터 바인딩된 항목 사용에 체크하고 데이터 개체는 Product클래스를 선택한다.


각각 멤버와 값을 선택한다. 



이제 다음과 같이 데이터를 추가하면 데이터 박스와 리스트 박스에, 바인딩 된 데이터가 출력될 것이다.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
 
        productBindingSource.Add(new Product() { Name = "감자", Price = 500 });
        productBindingSource.Add(new Product() { Name = "사과", Price = 700 });
        productBindingSource.Add(new Product() { Name = "고구마", Price = 400 });
        productBindingSource.Add(new Product() { Name = "배추", Price = 600 });
        productBindingSource.Add(new Product() { Name = "감자", Price = 500 });
    }
}

데이터 그리드뷰도 마찬가지로 데이터 소스를 추가해 활용할 수 있다.




delegator (대리자)


델리게이트는 메소드의 매개변수로 메소드를 전달하기 위한 것이다. 델리게이터는 대리자라고 번역하기도 한다. 

말 그대로 어떤 행위를 대신 한다는 것으로, 행위(메소드)를 저장하고 전달하기 위해 나온 개념이다.


델리게이터 선언

delegate void TestDelegate();


델리게이터 자료형으로 변수 초기화

TestDelegate testDelegate = <메서드 이름, 무명 델리게이터, 람다> ( 이것은 델리게이터 변수를 초기화하는 방법이다)



Comparison 델리게이터 ( MSDN : https://msdn.microsoft.com/ko-kr/library/tfakywbh(v=vs.110).aspx )

public delegate int Comparison<in T>(
	T x,
	T y
)



다음은 Comparison 델리게이터를 이용해 상품의 가격을 정렬하는 예제이다. 

아래 예제에서는 Sort 메서드의 매개변수로 SortWithPrice 메소드를 전달한다.

namespace Delegate
{
    class Product
    {
        public string Name { getset; }
        public int Price { getset; }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            List<Product> products = new List<Product>()
            {
                new Product() {Name="감자", Price=500},
                new Product() {Name="사과", Price=700},
                new Product() {Name="상추", Price=300},                
            };
 
            products.Sort(SortWithPrice);
 
            foreach (var item in products)
            {
                Console.WriteLine(item.Name + " : " + item.Price);
            }          
        }
 
        static int SortWithPrice(Product a, Product b)
        {
            return a.Price.CompareTo(b.Price);
        }   
    }
}

Comparison은 델리게이트(대리자)로 형식에 맞는 함수를 따로 정의해 두어야 한다.

1
2
3
4
public static int Compare(float a, float b)
{
    return a.CompareTo(b); 
}
cs




'Study > C#' 카테고리의 다른 글

C# MS-SQL 연동  (0) 2017.04.14
C# 네트워크 기본  (1) 2017.04.12
C# 인터페이스  (0) 2017.04.07
C# 클래스, 메소드  (0) 2017.04.04
c# 복습  (0) 2017.03.31

+ Recent posts