'강좌 > C#' 카테고리의 다른 글
멀티플렉싱(multiplexing) (0) | 2012.01.18 |
---|---|
Stream, Dgram 설명 (0) | 2012.01.18 |
TCP/IP Socket with C# (0) | 2012.01.18 |
델리게이트 선언뒤에 할당 (0) | 2012.01.18 |
Delegate(5) : 람다식 (0) | 2012.01.17 |
멀티플렉싱(multiplexing) (0) | 2012.01.18 |
---|---|
Stream, Dgram 설명 (0) | 2012.01.18 |
TCP/IP Socket with C# (0) | 2012.01.18 |
델리게이트 선언뒤에 할당 (0) | 2012.01.18 |
Delegate(5) : 람다식 (0) | 2012.01.17 |
디렉터리 서비스(directory service)는 클라이언트가 디렉터리 구조를 통해 서버가 제공하는 서비스와 서버 내부의 장소들을 열람하는 서비스.
// IP네트워크가 갖는 하나의 인터페이스에 대한 주소를 반환
public IPAddress(long address);
public static short HostToNetworkOrder?(short);
public static int HostToNetworkOrder?(int);
public static long HostToNetworkOrder?(long);
public static short NetworkToHostOrder?(short);
public static int NetworkToHostOrder?(int);
public static long NetworkToHostOrder?(long);
public static IPAddress Parse(string address);
// 도트 표기로 된 스트링 형태의 IP주소를 IPAddress인스턴스로 변환
public static readonly IPAddress Any; // 0.0.0.0
public static readonly IPAddress Broadcast; // 255.255.255.255
public static readonly IPAddress Loopback; // 127.0.0.1
// Dns 클래스의 GetHostByName?(), GetHostByAddress?(), GetHostEntry?()로 반환되는 컨테이너 클래스
public string HostName? { get; set; }
public string[] Aliases { get; set; }
public IPAddress[] AddressList? { get; set; }
// DNS로 부터 호스트명 또는 IP주소와 관련된 정보를 수집할 수 있는 여러 정적 메소드
public static IPHostEntry? GetHostByAddress?(IPAddress address);
public static IPHostEntry? GetHostByAddress?(string address);
public static IPHostEntry? GetHostByName?(string hostname);
public static string GetHostName?();
public static IPHostEntry? GetHostEntry?(IPAddress address);
public static IPHostEntry? GetHostEntry?(string hostname);
// 소켓 하위클래스, TCP연결을 통해 다른 호스트와 접속하고, 데이터를 전송하고 수신하는데 사용되는 여러 메소드를 제공
public TcpClient?();
public TcpClient?(IPEndPoint? localEP);
public TcpClient?(string hostname, int port);
public void Close();
public void Connect(IPEndPoint? endpoint);
public void Connect(IPAddress address, int port);
public void Connect(string hostname, int port);
public NetworkStream? GetStream?();
protected Socket Client { get; set; }
public 속성으로 설정 가능한 소켓 옵션
LingerState? // 소켓의 지연시간 설정
NoDelay? // 전송이나 수신 버퍼가 꽉 차지 않을 경우 지연을 방지하는 변수값을 설정
ReceiveBufferSize? // 수신 버퍼의 크기 설정
ReceiveTimeout? // 읽기 작업시 데이터를 수신하기까지 기다리는 시간 설정
SendBufferSize? // 전송 버퍼의 크기 설정
SendTimeout? // 쓰기 작업 시작시 데이터를 송신완료까지 기다리는 시간 설정
// IPEndPoint?의 추상 클래스
// IP주소와 포트번호 형태로 TCP/IP 엔드 포인트를 나타낸다.
public IPEndPoint?(long address, int port);
public IPEndPoint?(IPAddress address, int port);
public IPAddress Address { get; set; }
public int Port { get; set; }
// TCP네트워크 클라이언트로부터 들어오는 연결 요청을 대기한다.
public TcpListener?(IPEndPoint? localEP);
public TCpListener?(IPAddress address, int port);
public Socket AcceptSocket?();
public TcpClient? AccepTcpClient?();
public bool Pending(); // 수락 가능한 연결 요청 있을 경우 true
public void Start();
public void Stop();
public EndPoint? LocalEndpoint? { get; }
protected Socket Server { get; }
// Stream 클래스의 하위 클래스
public virtual void Close();
public abstract int Read(byte[] buffer, int offset, int length);
public abstract void Write(byte[] buffer, int offset, int length);
public virtual bool DataAvailable? { get; } // 스트림으로부터 읽어들일 데이터가 존재하는 경우 true
public UdpClient?();
public UdpClient?(int port);
public UdpClient?(IPEndPoint? localEP);
public UdpClient?(string hostname, int port);
public void Close();
public void Connect(IPEndPoint? endpoint);
public void Connect(IPAddress addr, int port);
public void Connect(string hostname, int port);
public byte[] Receive(ref IPEndPoint? remoteEP);
public int Send(byte[] dgram, int length);
public int Send(byte[] dgram, int length, IPEndPoint? endPoint);
public int Send(byte[] dgram, int length, string honstname, int port);
protected Socket Client { get; set; }
public Socket(AddressFamily?, SocketType?, ProtocolType?);
// TCP 사용시 (Address.Family.InterNetwork?, SocketType?.Stream, ProtocolType?.Tcp)
public Bind(EndPoint? localEP); // 소켓을 결합한다. IPAddress.Any(0,0,0,0)객체와 명시된 포트번호로 구성된 IPEndPoint?인스턴스를 파라미터로 받아서 로컬주소와 포트에 결합한다.
public void Close();
public Connect(EndPoint? remoteEP);
public object GetSocketOption?(SocketOptionLevel?, SocketOptionName?);
public void GetSocketOption?(SocketOptionLevel?, SocketOptionName?, byte[]);
public byte[] GetSocketOption?(SocketOptionLevel?, SocketOptionName?, int);
public void Listen(int backlog); // 연결 요청 큐의 최대 길이
public bool Poll(int microsecond, SelectMode? mode);
// 객체의 상태 확인. SelectMode?.SelectWrite? 쓰기 가능한지 확인, SelectMode?.SelectRead? 읽기 가능한지 확인, SelectMode?.SelectError? 오류 존재 여부 확인
public int Receive(byte[] buffer);
public int Receive(byte[] buffer, SocketFlags? flags);
public int Receive(byte[] buffer, int length, SocketFlags? flags);
public int Receive(byte[] buffer, int offset, int length, SocketFlags? flags);
public int ReceiveFrom?(byte[] buffer, ref EndPoint? remoteEP);
public int ReceiveFrom?(byte[] buffer, SocketFlags? flags, ref EndPoint? remoteEP);
public int ReceiveFrom?(byte[] buffer, int length, SocketFlags? flags, ref EndPoint? remoteEP);
public int ReceiveFrom?(byte[] buffer, int offset, int length, SocketFlags? flags, ref EndPoint? remoteEP);
public static void Select(IList readableList, IList writeableList, IList errorList, int microseconds);
public int Send(byte[] buffer);
public int Send(byte[] buffer, SocketFlags? flags);
public int Send(byte[] buffer, int length, SocketFlags? flags);
public int Send(byte[] buffer, int offset, int length, SocketFlags? flags);
public int SendTo?(byte[] buffer, ref EndPoint? remoteEP);
public int SendTo?(byte[] buffer, SocketFlags? flags, ref EndPoint? remoteEP);
public int SendTo?(byte[] buffer, int length, SocketFlags? flags, ref EndPoint? remoteEP);
public int SendTo?(byte[] buffer, int offset, int length, SocketFlags? flags, ref EndPoint? remoteEP);
public void SetSocketOption?(SocketOptionLevel? optionLevel, SocketOptionName? optionName, byte[] optionValue);
public void SetSocketOption?(SocketOptionLevel? optionLevel, SocketOptionName? optionName, int optionValue);
public void SetSocketOption?(SocketOptionLevel? optionLevel, SocketOptionName? optionName, object optionValue);
/*
SocketOptionLeve? 열거체
옵션이 적용될 계층을 정한다.
IP
Socket
Tcp
Udp
SocketOptionName?
http://dotgnu.org/pnetlib-doc/System/Net/Sockets/SocketOptionName.html
SocketFlags?
DontRoute? 라우팅 테이블을 사용하지 않고 전송한다.
MaxIOVectorLength? 데이터를 전송하고 수신하는데 사용할 WSABUF 구조의 개수에 대한 표준수치를 제공한다.
None
OutOfBand? 대역외(out-of-band) 데이터를 처리한다.
Partial 메시지의 일부를 전송하고 수신할 수 있다.
Peek 현재 수신중인 메시지를 확인한다.
*/
public void Shutedown(SocketShutdown? how);
// 데이터를 전송하고 수신하는 기능을 중단시킨다. SocketShutdown?.Send, SocketShutdown?.Receive, SocketShutdown?.Both
public bool Connected { get; } // 가장 최근 입출력 작업후 객체가 원격 리소스에 연결되어 있는지 나타낸다.
public EndPoint? LocalEndPoint? { get; } // 로컬 엔드 포인트를 가져온다.
public EndPoint? RemoveEndPoint? { get; } // 원격 엔드 포인트를 가져온다.
public override int ErrorCode? { get; } // WinSock? 2.0 에러코드와 일치한다.
public virtual string Message { get; } // 사용자가 읽을 수 있는 오류 메시지
BufferedStream? // 입출력 최적화를 위한 버퍼링을 시행
BinaryReader?/BinaryWriter? // 기본 데이터 타입의 읽기/쓰기를 처리
MemoryStream? // 메모리를 백킹 스토어(backing store)로 하는 스트림을 생성하고, 임시 버퍼와 파일 대용으로 사용할 수 있다.
Stream // 모든 스트림에 대한 기본 추상 클래스
StreamReader?/StreamWriter? // 특정 인코딩을 캐릭터 입출력을 스트림에 대해서 처리
StringReader?/StringWriter? // 특정 인코딩을 캐릭터 입출력을 스트림에 대해서 처리
TextReader?/TextWriter? // 캐릭터 입출력에 대한 기본 추상 클래스로서 StreamReader?/StreamWriter?클래스와 StringReader?/StringWriter?클래스들의 부모클래스이다.
(1) 입출력 상태를 사전에 점검
TcpClient?클래스로부터 데이터를 읽어들이는 과정에서 NetStream?의 DataAvailable?속성이 true이면 읽을 데이터가 존재하는 것
TcpListener? 클래스로부터 Pending()메쏘드 사용하여 AcceptTcpClient?()메소드 또는 AcceptSocket?() 메소드를 호출하기 전에 연결 요청이 있는지를 점검 있으면 true.
Socket 클래스의 int타입의 Available속성을 통해 읽어들일 데이터의 존재 여부 확인. 네트워크로 부터 수신 했지만, 아직 읽어들이지 않은 데이터량을 바이트 단위의 정수로 기억. 즉 Available 속성이 0보다 클 경우 읽기 동작은 블록을 걸지 않는다.
(2) 블로킹 타임아웃 콜
Socket 클래스의 Poll()메소드. 메소드 인자의 시간 만큼 블록하여 요청을 대기한다.
Socket 클래스의 SetSocketOption?()메소드로 타임아웃(timeout)을 설정한다. TcpClient도? ReceiveTimeout? 속성을 통해 타임아웃을 설정할 수 있다.
(3) 넌 블로킹 소켓
Socket 클래스의 Blocking 속성을 false로 변경한다.
NetworkStream? 클래스의 비동기 형태 Write, Read
public override IAsynResult? BeginRead?(byte[] buffer, int offset, int size, AsyncCallback? callback, object state);
public override IAsynResult? BeginWrite?(byte[] buffer, int offset, int size, AsyncCallback? callback, object state);
public override int EndRead?(IAsyncResult? asyncResult);
public override void EndWrite?(IAsyncResult? asyncResult);
AsyncCallback? ac = new ASyncCallback?(myMethodToCall?);
...
public static void myMethodToCall?(IAsyncResult? result);
{
}
이런 콜백외의 비동기 콜작업은 효용이 없다.
사용법은 유니캐스트와 같으며 목적지 주소를 브로드캐스트 주소로 변경하면 된다.
SocketOptionName?.MuilticastTimeToLive?옵션에서 TTL을 설정하며
SocketOptionName?.AddMembership?옵션과 SocketOptionName?.DropMembership?옵션과
UdpClient?의 JoinMulticastGroup?()메소드나 DropMulticastGroup?()메소드로 그룹을 가입하거나 탈퇴하여 멀티캐스트 메시지 수신이 가능하다.
그리고 SocketOptionName?.ReuseAddress?을 적용해야 호스트로부터 동시에 두 개이상의 멀티캐스트 메시지를 수신할수 있다.
SocketOptionName?.Linger 은 Close()메소드가 종료 핸드쉐이크를 완료되기를 대기하면 반환하지 않는 시간을 제어한다. 타임아웃을 초단위로 설정한다.
TCP연결을 종료하는데 있어 시간 대기 상태(Time-Wait State)가 있다.
소켓 종료후 네트워크상 똑같은 소켓으로 다시 생성이 되어 전송을 하여 이전 소켓으로 전송된 데이터가 네트워크상 딜레이 있을 경우 어느 소켓에서 발생된 데이터인지 오인이 생길수 있다.
이 대기 시간(quiet time)은 구현에 따라 다르게 설정되는데 적게는 30초에서 4분까지가 된다.(패킷이 네트워크상 존재할 수 있는 최대 시간의 두배)
윈도우는 4분이 기본값이다.
문제는 같은 포트로 소켓을 생성할 수 없다는 점이다. ErrorCode? 값이 10048에 해당하는 Exception을 발생시킨다.
컴파일시 실행파일에 속성변수를 설정함으로 CLR JIT컴파일러로 하여금 코드를 추적하게 만들고, 이로써 디버거에서 참고할 추적 정보를 기록할 프로그래머 데이터베이스(PDB : Programmer DataBase?) 파일을 생성하게된다.
여기서 설정되는 속성 변수는 JITTracking 플래그라 부른다. 이 플래그는 컴파일러로부터 생성된 네이티브 코드를 MSIL명령어로, 또 이 명령어를 결국 원래의 소스 코드로 디컴파일해야 한다는 정보를 CLR JIT컴파일러에 전달한다. 이 모든 정보는 실행 파일에 대한 PDB 파일에 저장된다.
dbgclr (GUI 디버거)
visual studio와 유사한 형식
cordbg (커맨드라인 디버거)
s 소스 코드 한 개 라인을 실행
si 소스 코드 한 개 라인을 실행
so 소스 코드 한 개 라인을 건너뜀
ss 다음 네이티브 또는 IL 명령을 실행
p <arg> 변수 현재 값을 출력
pro 프로그램 실행에 대한 시스템 프로세스 정보를 출력
reg 현재 쓰레드에 대한 CPU 레지스터 정보 출력
run <prog> 디버거에서 prog 프로그램을 실행
break 소스에 브레이크지점 설정 또는 출력
sh 현재 실행중인 코드 라인과, 전후 5개 라인을 출력
IL DASM(Microsoft Intermediate Language Disassembler)
Politecnico di Torino 의 NetGroup?팀이 개발한 모든 윈도우즈 시스템에서 네트워크 패킷을 수집할 수 있도록 설계.
커맨드 라인 옵션
-a 네트워크와 브로드캐스트 주소를 네임으로 변경
-B size 수신 버퍼 크기를 size로 수정
-c count 패킷을 count만큼만 수집
-D 시스템에서 사용가능한 모든 네트워크 인터페이스를 표시
-e 각 출력줄에 링크 레벨의 정보를 출력
-F file File 파일에 정의된 필터를 적용
-i interface interface네트워크를 모니터링 하는데, interface는 인터페이스 이름 혹은 ?D 명령어로 지정된 인터페이스 번호가 될 수 있다.
-n 주소를 이름으로 변화하지 않도록 설정
-N FQDN(Fully Qualified Domain Name)을 출력하지 않도록 설정
-q 간단한 형태로 패킷 정보를 출력
-r file 덤프 파일 file로부터 패킷을 읽어들임
-S 절대 TCP일련 번호를 출력
-s snaplen 패킷으로 부터 snaplen 만큼의 바이트를 수집. 기본 수치는 68이다.
-t 각 라인에 시간을 출력하지 않음
-w file 결과를 file에 출력
-X 각 패킷을 hex형태와 ASCII형태로 출력
-x 각 패킷을 hex형태로 출력
필터 조건문 적용
windump ip // 네트워크에 흐르는 ip패킷만을 수집
windump ip host 203.241.228.251 // 특정 ip주소로부터 오가는 네트워크 패킷 수집
windump ip src 203.241.228.251 // 특정 ip주소로부터 오는 네트워크 패킷 수집
windump ip host 203.241.228 // 특정 서브넷으로부터 오가는 패킷 수집
DDN(Dotted Decimal Notaion)으로 표현하면
1. IPConfig 사용
2. 레지스트리 사용
3. WMI 사용 (Windows Management Instrumentation)
마이크로소프트가 구현한 Web-Based Enterprise Management(WBEM)의 한종류 이다. WBEM은 Distributed Management Task Force. Inc(DMTF) 에서 개발한 것으로 네트워크 환경에서 시스템 정보를 접근하는 표준
윈도우 2000이후, 지원하고 이전 윈도우즈는 WMI Software Developers Kit 를 통해 WMI 시스템을 별도로 설치 할 수 있다. (http://www.microsoft.com/downloads/search.asp?로 부터 다운)
WMI 내에 있는 WMI Win32_NetworkAdapterConfiguration? 표는 시스템에서 설치된 네트워크 장치와 관련된 정보를 기록하고 있다.
using System.Management;
...
ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'");
ManagementObjectCollection queryCollection = query.Get();
foreach(ManagetmentObject mo in queryCollection)
{
...
Console.WriteLine( (string[])mo["IPAddress"] );
}
BitConverter? Class
public static byte[] GetBytes([TYPE] value); // 특정 타입을 바이트 배열로 반환
public static [TYPE] To[TYPE](byte[] value, int startIndex); // 바이트를 특정 타입으로 변환
// string형은 Encoding 클래스의 Encoding.ASCII.GetString()함수 사용
Buffer Class // 기본 형식 배열을 조작
public static void SetByte(Array array, int index, byte value); // 배열 특정 위치의 값을 변경
public static void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count); // 배열의 블록 단위 복수
public static Process GetCurrentProcess();
public static Process[] GetProcesses(); // 실행중인 프로세스 전부를 찾는다.
public static Process GetProcessById(int); // 실행중인 프로세스 찾기
public static Process[] GetProcessesByName(string); // 실행중인 프로세스 찾기
public static Process Start(string); // 오버로드 되어있음. 프로그램 이름으로 실행하는 방법외에 인자 넣을수도 있고 ProcessStartInfo 클래스에 정보 채워서 실행 가능.
public void Kill(); // 프로세스 강제 종료
public bool CloseMainWindow(); // 메인 윈도우에 닫기 메시지를 전송하여 종료를 권유. 메인 윈도우가 없거나 모달 대화상자일경우 실패하기도 한다.
public void Close(); // 프로세스 종료. 강제 종료가 아니라 연결된 리소스 전부를 해제후 종료.
Process 클래스의 속성을 통해 Collection을 얻어온다.
public ProcessThreadCollection Threads {get;}
public Thread(ThreadStart start); //스레드 생성자 델리게이트형 ThreadStart를 요구한다.
public delegate void ThreadStart(); // 실행할 스레드 메소드를 지정한다.
public void Start();
public Thread(ParameterizedThreadStart start); // ParameterizedThreadStart로 등록하면
[ComVisibleAttribute(false)]
public delegate void ParameterizedThreadStart(Object obj);
public void Start(Object state); // 스레드에 Object형 매개변수를 전달할 수 있다.
ThreadPool? class
작업 항목 게시, 비동기 I/O 처리, 다른 스레드 대신 기다리기 및 타이머 처리에 사용할 수 있는 스레드 풀을 제공합니다.
생성자가 없고 모든 메소드는 정적이다.
메소드가 호출되면 운영체제는 자동으로 스레드 풀을 생성하고 25개의 스레드가 등록 가능한 상태가 된다.
타이머 큐 타이머와 등록된 대기 작업도 스레드 풀을 사용된다.
타이머 큐 타이머와 등록된 대기 작업의 콜백 함수는 스레드 풀에 대기하게 된다.
스레드 풀에 있는 스레드에서 작업 항목을 처리하도록 요청하려면
public static bool QueueUserWorkItem(WaitCallback callBack);
public static bool QueueUserWorkItem(WaitCallback callBack, Object state);
[Serializable]
public delegate void WaitCallback(object state);
사용예)
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc,state));
를 호출하여 사용하게된다. 작업항목을 큐에 대기시킨 후에는 취소할 수가 없다.
이하 시스템 프로그래밍 관련 부분...
// 제한 시간(밀리초)에 부호 있는 32비트 정수를 사용하여 WaitHandle을 기다리는 대리자를 등록합니다.
public static RegisteredWaitHandle RegisterWaitForSingleObject(WaitHandle, WaitOrTimerCallback, object, int, bool);
// WaitHandle 클래스
공유 리소스에 대한 단독 액세스를 기다리는 운영 체제 관련 개체를 캡슐화합니다
EditText of this page (last modified 2008-11-05 11:01:00)
FindPage by browsing, searching, or an index
Or try one of these actions: DeletePage, DeleteUploadedFile, LikePages, SpellCheck, UploadFile
Stream, Dgram 설명 (0) | 2012.01.18 |
---|---|
Invoke 개념 이해하기 (0) | 2012.01.18 |
델리게이트 선언뒤에 할당 (0) | 2012.01.18 |
Delegate(5) : 람다식 (0) | 2012.01.17 |
C# 람다식 (0) | 2012.01.17 |
Invoke 개념 이해하기 (0) | 2012.01.18 |
---|---|
TCP/IP Socket with C# (0) | 2012.01.18 |
Delegate(5) : 람다식 (0) | 2012.01.17 |
C# 람다식 (0) | 2012.01.17 |
람다식(Lambda Expression) (0) | 2012.01.17 |
어쨌건, 시작합니다. ㅎㅎ
프로젝트를 만들어주세요 ㅇㅅㅇ .. !
아래가 람다입니다. ㅇㅅㅇ
"헐킈, 먼가요 저게 ?"
『=>』요게 들어가면 람다입니다.
『간단하게 x 라는 인수를 x*x 로 리턴한다는 뜻입니다.』
실행 한번 해보죠 ㅎㅎ
100 이 출력 되는 것을 볼 수 있습니다.
지금.. 제 생각에는..
"아놔, 리턴도 안 했는데, 뭐 위의 결과가 뜹니까?!" 하시는 분이 있을텐데요.
아래와 같이 return 을 써주셔도 됩니다 .ㅎㅎ
간단하게 X => Y 로 되어있는 람다식에서는 X 가 파라메터, Y 가 리턴값이 됩니다. >_<
아래와 같이 여러개를 넣을 수도 있지요 >_<
결과입니다. ㅎㅎ
근데 만약 파라메터가 2개라면... >_<
아래와 같이 해주시면 됩니다 .ㅇㅅㅇ...
무지 짧죠 ?
『귀차니즘의 역사』라고 말한 이유가 이것입니다.
점점점점점 짧아지죠... ㅎㅎ
그럼 이걸 어디다 쓰는지는 봐야죠 ㅇㅅㅇ...
그리고, 가끔 『=>』이게 나오면 "허걱... 이건 머임.." 하고 놀라시는 분이 있으시니, 조금 활용해보도록합시다. ㅎㅎ
우선 리스트에 Where 이라는 메서드가 있습니다.
조건에 맞는 녀석들을 뽑아서 다시 배열로 만들어주시는 분입니다.
보시면 파라메터로 Func<string, bool> predicate 를 달라고 하는데요.
뭔 개소리일까요 ㅇㅅㅇ ....
<string, bool> 의 뜻은 대충 『string을 박으면 bool 로 나오는 녀석』이라는 뜻입니다.
여기에, 리턴값이 bool 이고 파라메터가 string 인 메서드의 이름을 넣으셔도 됩니다.
근데, 길죠 ㅇㅅㅇ... 귀찮구 >_<
아래와 같이 람다식을 넣었습니다.
data 가 'A' 라는 글자를 가지고 있으면 true 를 리턴하게 되는 식입니다.
"아니, 왜 true 를 리턴하죠 ?!"
『Contains() 메서드는 맞으면 True 를 리턴하니까요 ㅇㅅㅇ』
자, 무지 짧아졌죠?
메소드 만들기는 『귀찮』으니까요 ... !
출력하시면 『1』이 나오겠지요 ~_~ ?
음... 결과 스크린샷을 찍었는데.... 없어졌네엥.. ;ㅁ;
어쨌건, 이번에는 MSDN 에 나오는 예제를 봅시다.
아래와 같이 썼어요.
Count() 메서드의 두번째 오버로딩 되는 녀석입니다.
위와 마찬가지로 해석하면요.
『int 를 박으면 bool 이 나오는 함수를 주렴 >_<』 이라는 뜻입니다.
메서드 만들기는 귀찮죠 ... ?
아래와 같이 람다식을 박으시면 됩니다. ㅇㅅㅇ...
람다식은 일단 연습해보는 것이 제일 좋습니다. ㅇㅅㅇ
많은 연습이 제일 중요하죠.
연습하면, 메소드를 만들어야하는 귀찮은 녀석들을 위와 같이 간단간단 20글자 내외로 끝낼 수 있습니다.
자, 그럼 ㅇㅅㅇ ...
C# Basic 강의 종강입니다. ㅎㅎ
괜히 마지막을 Delegate 으로 잡아서 끝을 못 내드리고 똥 안 닦고 나온 기분을 연출시켜드려 죄송합니다. ;ㅁ;
딜리게이트는 Windows Forms 강의에서나 다시 보실 수 있게 될겁니다. ;ㅁ;
끝 ㅎㅎ ... !
[출처] C# 42강 - Delegate(5) : 람다식|작성자 린트
TCP/IP Socket with C# (0) | 2012.01.18 |
---|---|
델리게이트 선언뒤에 할당 (0) | 2012.01.18 |
C# 람다식 (0) | 2012.01.17 |
람다식(Lambda Expression) (0) | 2012.01.17 |
매소드를 인수로 넘기기.. (0) | 2012.01.17 |
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace pLambdaLinQ
{
class cLambda
{
delegate int delObj();
delegate int delObjPara1(int
x);
delegate int delObjPara2(int
x, int y);
static public int RtnMethod(int
pInt)
{
return ++pInt;
}
static public void CallMethod()
{
/* 0. 간단한
람다식 */
/* 0.1. 람다식에서
메서드 호출 */
int x=10, y=20;
delObj doObj= () => { return RtnMethod(x); };
int i = doObj();
Console.WriteLine("(x, y) =>
return x + y; : {0}",
i);
/* 0.2. 람다식에서
메서드 만들기 */
doObj = () => {
return x + y; };
Console.WriteLine("return x + y : {0}",
doObj());
/* 0.3. 람다식에서
매개변수 1개 있는 메서드 만들기
*/
delObjPara1 dopObj1;
dopObj1 = (pX)
=> { return ++pX; };
Console.WriteLine("return ++pX : {0}",
dopObj1(4));
/* 0.4. 람다식에서
매개변수 2개 있는 메서드 만들기
*/
delObjPara2 dopObj2;
dopObj2 = (pX, pY)
=> { return pX + pY;
};
Console.WriteLine("return pX + pY : {0}", dopObj2(2,
8));
/* 0.5. 람다식
정의 형식
* 1. 델리게이트
선언 : 매개변수 목록·반환데이터타입이
람다식과 일치
* delegate
반환데이터타입
델리게이트이름(매개변수목록);
* 2. 람다식을
델리게이트 변수에 할당
* 델리게이트이름
변수이름 = (매개변수목록) => {메서드의 body}
*
* 0.6.
람다식
사용
* 변수이름(매개변수목록)
*/
}
}
}
델리게이트 선언뒤에 할당 (0) | 2012.01.18 |
---|---|
Delegate(5) : 람다식 (0) | 2012.01.17 |
람다식(Lambda Expression) (0) | 2012.01.17 |
매소드를 인수로 넘기기.. (0) | 2012.01.17 |
InvokeRequired (0) | 2012.01.17 |
Delegate(5) : 람다식 (0) | 2012.01.17 |
---|---|
C# 람다식 (0) | 2012.01.17 |
매소드를 인수로 넘기기.. (0) | 2012.01.17 |
InvokeRequired (0) | 2012.01.17 |
InvokeRequired & Cross Thread 처리방법 (0) | 2012.01.17 |
시작합시다. ㅎㅎ
프로젝트를 만들어주세요 ㅇㅅㅇ ...
우선 Delegate 만드는 방법입니다.
그냥 아래와 같이 일반 필드 만드는 듯이 하신 뒤에 뒤에 그냥 메소드를 박아주시면 됩니다. ㅎㅎ
그리고 아래와 같이 메소드를 넣어주시면 됩니다. ~_~...
정말 뭐에 쓰는지는 모르겠지만, 일단 이해는 쉽죠 ... ?
int FirstDelegate(int x, int y) 이니,
리턴타입이 int 고, 파라메터가 int 2개인 메소드를 대입할 수 있는거랍니다. ㅎ
아래와 같이 하시면요 ㅇㅅㅇ ...
뭐, 쓸 수 있는 겁니다.
fd = Method 니까, 10 + 20, 30을 리턴하겠지요.
그리고 아래와 같이 메소드를 인수로 넘길 수도 있는 것이지요 ~_~...
아래와 같이 보시면 메소드의 형태를 볼 수 있는데요.
아래와 같이 형태를 볼 수 있습니다.
보신 뒤 나올 예상 반응 100 %
"그래서요 ... ?"
『....인터페이스의 기본적인 것을 Basic 강의에서 다루구요.』
『활용방법 자체는 콘솔에서 볼 수 없습니다. 우선, 인터페이스를 약간 업 시켜서 이벤트는 중급 강의에서 볼겁니다 ~_~ ㅎㅎ』
어쨌거나 끄읏 ~
[출처] C# 38강 - Delegate(1) : 딜리게이트|작성자 린트
C# 람다식 (0) | 2012.01.17 |
---|---|
람다식(Lambda Expression) (0) | 2012.01.17 |
InvokeRequired (0) | 2012.01.17 |
InvokeRequired & Cross Thread 처리방법 (0) | 2012.01.17 |
인터페이스를 상속한 자신을 파라미터로 호출한 경우. (0) | 2012.01.17 |
간혹 쓰래드 안에서 혹은! 동적으로 만들어진 컨트롤이 다른 윈도우 컨트롤의 모양(레이아웃)을 건드리려 한다면!!
다음과 같은 에러가 발생한다.
System.UnauthorizedAccessException: Invalid cross-thread access
혹은
Cross-thread operation not valid: blah blah blah :p
그럴땐 어찌하는냐!!
Delegate를 써야한다.
윈도우 컨트롤에게 InvokeRequired라는 걸로 이렇게 물어본다.
"내가 니 몸뚱이 색깔 좀 바꿀려는데 좀 기다릴까?"
그러면 InvokeRequired가 true/false로 대답해 줄 것이다. ㅋㅋ
허나 질문에 주의하라! true면 기다리라는 것이므로 Delegate로 하나 더 날려준다.
그리고 false가 나오면 바꾸면 된다.
InvokeRequired는 바꾸려는 컨트롤의 것을 사용해야한다.
아래의 경우 패널을 바꾸기 위해 사용한 것. 그러므로 InvokeRequired는 패널에게 물어본다.
코드는 아래와 같다.
private Command PopupInvoke(Popup popup, ScreenPanel pnl)
{
if (pnl.InvokeRequired)
{
InvokeDelegate<Popup, ScreenPanel> id = new InvokeDelegate<Popup, ScreenPanel>(PopupInvoke);
pnl.Invoke(id, new object[]{popup, pnl});
}
else
{
popup.Size = pnl.Size;
pnl.Location = new Point(0, 0);
pnl.Parent = popup.pnlPopup;
popup.ShowDialog();
}
return null;
람다식(Lambda Expression) (0) | 2012.01.17 |
---|---|
매소드를 인수로 넘기기.. (0) | 2012.01.17 |
InvokeRequired & Cross Thread 처리방법 (0) | 2012.01.17 |
인터페이스를 상속한 자신을 파라미터로 호출한 경우. (0) | 2012.01.17 |
Interface 변수 상속한 하위 클래스 함수 호출. (0) | 2012.01.17 |
매소드를 인수로 넘기기.. (0) | 2012.01.17 |
---|---|
InvokeRequired (0) | 2012.01.17 |
인터페이스를 상속한 자신을 파라미터로 호출한 경우. (0) | 2012.01.17 |
Interface 변수 상속한 하위 클래스 함수 호출. (0) | 2012.01.17 |
스레드 콜백함수에 파라미터 보내는 방법 - 스레드, delegate 사용 (0) | 2012.01.17 |
InvokeRequired (0) | 2012.01.17 |
---|---|
InvokeRequired & Cross Thread 처리방법 (0) | 2012.01.17 |
Interface 변수 상속한 하위 클래스 함수 호출. (0) | 2012.01.17 |
스레드 콜백함수에 파라미터 보내는 방법 - 스레드, delegate 사용 (0) | 2012.01.17 |
Cross-thread operation not valid (0) | 2012.01.17 |
InvokeRequired & Cross Thread 처리방법 (0) | 2012.01.17 |
---|---|
인터페이스를 상속한 자신을 파라미터로 호출한 경우. (0) | 2012.01.17 |
스레드 콜백함수에 파라미터 보내는 방법 - 스레드, delegate 사용 (0) | 2012.01.17 |
Cross-thread operation not valid (0) | 2012.01.17 |
Delegate (0) | 2012.01.17 |
인터페이스를 상속한 자신을 파라미터로 호출한 경우. (0) | 2012.01.17 |
---|---|
Interface 변수 상속한 하위 클래스 함수 호출. (0) | 2012.01.17 |
Cross-thread operation not valid (0) | 2012.01.17 |
Delegate (0) | 2012.01.17 |
Hashtable, HashSet<T>, Dictionary<TKey, TValue> (0) | 2012.01.16 |
그것은 C# 프로그래밍의 첫걸음을 내디면서 만난 첫번째 난관이었다.
단지 쓰레드를 생성하고 그 안에서 폼에 붙어있는 레이블 컨트롤의 텍스트 속성만 바꿔주려 했을 뿐이었는데, 난데 없이 튀어나오는 예외메세지에 당황하지 않을 수 없었다. 원인을 찾아보니,
C# 스레드에선 다른 스레드의 컨트롤을 건드는 일은 하지 말아야 한다는 것이었다.
이래서 더더욱 난 C/C++이 좋을 수 밖에. C#은 너무 딱딱하다. 깐깐하다.
그럼 이런 상황을 가능하도록 만들려면? invoke를 통해 교차쓰레드접근을 우회하면 된다고 하는데,
무슨말인지, 나더러 어쩌라는건지 더더욱 당황스러워지고...인터넷 뒤져서 다른분들의 소스도 좀 찾아보고, 책도 보고, MSDN도 뒤져보고 나니 이렇게 하면 되는구나 하는 감이 오기는 하더라.
스포츠 뉴스에 보니, 퍼거슨이 나니를 팔일은 없을거라고 하던데...
어찌됬건간에 본론으로 돌아와서,
위의 예외창이 뜨는 경우의 예를 보면 다음과 같다.
public void threadfunc() { m_mainform.button1.Text = i.ToString(); } |
보시는데로, 이 함수는 메인폼 버튼의 텍스트를 설정해주는 코드다.
디버그모드로 빌드할 경우, 위 함수를 쓰레드로 돌리면 여지없이 예외박스가 출현해 주신다. 릴리즈 모드로 돌리면 잘 돌아가는것 처럼 보이는데 영 찜찜하다. 나중에 문제가 될지도 모르겠고, 비록 돌긴 돌아도 하지 말라는 짓이니 만큼 예외박스를 없애야 속이 편할 것 같다.
예외를 발생시키는 위 함수를 다음과 같이 고쳐보면,
public void threadfunc() { m_mainform.Invoke(new MethodInvoker(delegate() } |
어라, 잘 돈다. 쓰레드에서 버튼 텍스트를 직접 변경하는게 아니라, 폼의 Invoke 메소드를 통해서 버튼의 텍스트를 변경한다.
그리고 Invoke메소드를 사용하기 위해선 delegate를 인자로 제공해 주어야 한다. 위 예에선 MethodInvoker delegate가 제공되었는데, Microsoft.JScript 네임스페이스 안의 MethodInvoker 클래스와 혼동하지 말아야 겠다.
MethodInvoker delegate는 인자로 제공된 메소드를 실행하는 delegate를 나타내준다.
여기서 MethodInvoker에 제공된 인자는 바로,
"delegate(){m_mainform.button2.Text = i_1.ToString();}" 요놈이다.
메소드가 통째로 들어가 있다.
보기엔 안좋지만, 결국엔 폼의 Invoke메소드에 delegate를 인자로 제공하여 원하던 것을 할 수 있게 되었다.
한가지 불편한 점은 MethodInvoker delegate는 오로지 파라미터도 없고 리턴값도 없는 메소드만을 인자로 사용할 수 있다는 점인데, delegate 메소드에 파라미터를 넘겨야 할 경우엔 어떡해야 하나?
머리좀 굴려보면 굳이 파라미터가 필요 없더라도 같은 효과를 얻을 수 있을 것이고,
꼭 파라미터를 넘기고 싶다면 넘기면 된다. 어떻게?
다음과 같이 매개변수를 받은 함수의 타입의 delegate를 선언해준다.
delegate void SetObjectText_invoke3(int i);
이 예에선 int형의 변수를 파라미터로 취하는 함수타입으로 delegate를 선언했다.
C에서의 함수포인터의 개념과 비슷해보인다.
타입을 선언하였으면 그 타입으로 변수를 정의한다.
SetObjectText_invoke3 MI_SetText;
그리고, MI_SetText에 우리가 실제로 사용할 함수를 대입해넣는다.
MI_SetText = settext_invoke3;
settext_invoke3함수는 아래처럼 정의되어있다.
public void settext_invoke3(int i)
{
m_mainform.button4.Text = i.ToString();
}
역시, 매개변수로 받는 i를 이용해 버튼컨트롤의 Text를 바꾸는 코드다.
이제 쓰레드 안에서 다음처럼 사용하면 된다.
m_mainform.Invoke(MI_SetText, i);
샘플첨부.
Interface 변수 상속한 하위 클래스 함수 호출. (0) | 2012.01.17 |
---|---|
스레드 콜백함수에 파라미터 보내는 방법 - 스레드, delegate 사용 (0) | 2012.01.17 |
Delegate (0) | 2012.01.17 |
Hashtable, HashSet<T>, Dictionary<TKey, TValue> (0) | 2012.01.16 |
Generic 컬렉션 - List, Dictionary, Queue, Stack (0) | 2012.01.16 |
delegate 리턴타입 델리게이트명(파라미터);
델리게이트는 자신에게 연결된 함수를 대신 실행시켜주는 역할을 하는 일종의 함수 포인터이다.
즉 자신에게 할당된 함수를 대신 실행시켜준다.
델리게이트와 연결된 메서드의 목록을 확인할 때에는 GetInvocationList 메서드를 이용한다.
ex) foreach (var delegate in XXXXDelegate.GetInvocationList()) { // ... }
델리게이트는 익명 메서드, 람다 메서드와 궁합이 잘 맞는다.
익명 메서드, 람다 메서드는 표현식을 간결하게, 인라인의 형태로 가져감으로써 코드가 축약되고
경우에 따라 가독성이 향상된다.
1. 익명 메서드 (이름이 없는 메서드)
델리게이트에 의해 호출되는 함수가 단순한 작업을 수행하는 '짧은' 메서드라면 굳이 새롭게 메서드의 이름을 정의하고 구현하는 것보다 익명 메서드를 이용하는 것이 낫다.
ex)
delegate void SampleDelegate(string message);
SampleDelegate sample = delegate(string message)
{
Console.WriteLine(message);
};
sample("Hello, World");
2. 람다 메서드 (익명 메서드의 소집합)
람다식의 특징은 람다 연산자 '=>'에 있다.
1번의 예제 내용이 다음과 같이 축약됩니다.
ex)
SampleDelegate sample = (string message) => Console.WriteLine(message);
Delegate(대리자)
1] 함수의 기능을 대신해 주는 대리자 역할을 한다. 2] 여기서 대리자라 하면 자신에게 전달된 함수를 대신해 준다고 보면.. 3] Delegate를 선언하려면 함수의 시그너쳐를 일치 ==> 함수의 매개변수와 데이터 타입..... 4] 이벤트는 델리게이트 기반으로 만들어 졌다. Ex) this.버튼.click += .....(); |
Delegate 선언
delegate 리턴타입 델리게이트명(파라미터타입 변수); |
Delegate 생성 및 호출
델리게이트명 델리변수명 = new 델리게이트명(생성함수명);
{ // 코드 } |
Delegate 간단 예제_1
delegate void deleTest(string strParam); static void Main(string[] args) testDele_1("도망노비 테스트_1"); public static void dely(string strParam) |
Delegate 간단 예제_2
delegate void deleTest(string strParam); class Program deleTest dele_2 = new deleTest(classDele.DeleTest_2); class TestDele |
[출처] [C#] Delegate|작성자 에스이오케이
스레드 콜백함수에 파라미터 보내는 방법 - 스레드, delegate 사용 (0) | 2012.01.17 |
---|---|
Cross-thread operation not valid (0) | 2012.01.17 |
Hashtable, HashSet<T>, Dictionary<TKey, TValue> (0) | 2012.01.16 |
Generic 컬렉션 - List, Dictionary, Queue, Stack (0) | 2012.01.16 |
DictionaryEntry 구조체 (0) | 2012.01.16 |
Hashtable, HashSet, Dictionary 세 자료구조 모두 기본 알고리즘은 같다
해시코드를 사용하여 인덱스를 구하며 구조체와 배열에 데이터를 저장한다.
그럼 이 세놈의 차이점은 무엇일까? 간단히 정리해 보겠다. (내공이 부족하여 자세히는 못한다 ㅠㅠ)
Hashtable 과 Dictionary 는 둘 다 IDictionary 를 구현하고 있다.
다만 Hashtable 은 제너릭을 지원하지 않고, Dictionary<TKey, TValue> 는 제너릭을 지원한다.
HashSet<T> 은 제너릭은 지원하지만 키를 사용자에게 입력받지 않고
값을 이용하여 해시코드를 구한다.
이걸 어디에 쓸까 싶었지만, 중복값제거에 용의한듯하다.
김시억님께서 위의 주소에 문의하신 내용입니다.
중복제거에관한건데요 텍스트화일을 불러들여 중복제거를 하려고합니다
처음인데 막상시작하려하니 희안하게 로직이 잘 안떠오르는군요///
제가 1년좀 안되는데요 c#만 ....한번도 안해봐서 텍스트중복은;;;
aa
aa
bb
bb
이렇게 있다고 할경우 저 텍스트화일을 중복제거해서
aa
bb
이렇게만 결과물이 나오게하려면 어떻게 해야하나요?
쉬운거 같으면서도 막상코딩하려니 로직이 감이 잘 안잡히네요 ㅠ.ㅠ
답변부탁드립니다
가장 쉬운 방법은 .NET Framework 3.5에 HashSet을 사용하는 것입니다.
HashSet은 .NET Framework 3.5에 처음 추가된 Generic Class로 어셈블리는 System.Core.dll이고,
Namespace는 System.Collections.Generic 입니다.
(주의 .NET Framework 3.5가 설치되어 있지 않으면 당연히 위의 클래스를 사용할 수 없습니다.)
Hash 특성상 내부의 hash function으로 현재 collection 안에 들어있는 값을 찾는데 걸리는 시간이 적고,
Set 특성상 같은 내용을 중복으로 담고 있지 않아서 문의하신 내용에 가장 적합한 클래스입니다.
(그러나 Add 메소드는 상대적으로 다른 Collection보다 느릴 수 있기 때문에, 아주 긴 파일(수 MB가 넘는 파일)에는 적합하지
않을 수 도 있습니다.)
해당 내용은 아래와 같이 구현할 수 있습니다.
using System; using System.Collections.Generic; using System.Text; using System.Collections; using System.IO; namespace HashSetTest { class Program { static void Main(string[] args) { HashSet<string> set = new HashSet<string>(); using (TextReader reader = File.OpenText("test.txt")) { string line = reader.ReadLine(); while (string.IsNullOrEmpty(line) == false) { set.Add(line); line = reader.ReadLine(); } } foreach (string setItem in set) { Console.WriteLine(setItem); } } } }
aa bb aa cc aa bb
샘플 프로젝트 파일도 함께 첨부합니다.
Cross-thread operation not valid (0) | 2012.01.17 |
---|---|
Delegate (0) | 2012.01.17 |
Generic 컬렉션 - List, Dictionary, Queue, Stack (0) | 2012.01.16 |
DictionaryEntry 구조체 (0) | 2012.01.16 |
[C#] internal, protected internal (0) | 2012.01.16 |
Generic 형태의 컬렉션 구조를 사용하기
ArrayList |
= |
List<> |
Hashtable |
= |
Dictionary<> |
Queue |
= |
Queue<> |
Stack |
= |
Stack<> |
▼ Generic Collection |
using System.Collections; |
Cross-thread operation not valid (0) | 2012.01.17 |
---|---|
Delegate (0) | 2012.01.17 |
Hashtable, HashSet<T>, Dictionary<TKey, TValue> (0) | 2012.01.16 |
DictionaryEntry 구조체 (0) | 2012.01.16 |
[C#] internal, protected internal (0) | 2012.01.16 |
MSDN 참고로 공부중.... 당체 먼말?? ㅋㅋ
DictionaryEntry
==> 설정하거나 검색할 수 있는 사전 키/값 쌍을 정의
http://msdn.microsoft.com/ko-kr/library/system.collections.dictionaryentry(v=VS.100).aspx
언어의 foreach 문에는 컬렉션의 각 요소 형식이 필요합니다.
IDictionary의 각 요소가 키/값 쌍이므로 요소 형식은 키의 형식도, 값의 형식도 아닙니다.
대신 요소 형식은 DictionaryEntry입니다.
이곳으로 찾아가 보았다..
IDictionary 인터페이스는 키/값 쌍의 제네릭이 아닌 컬렉션에 대한 기본 인터페이스입니다
MSDN에 있는데 먼말인지는 알겟다..;;
[출처] [C#] DictionaryEntry 구조체 |작성자 도망노비
Cross-thread operation not valid (0) | 2012.01.17 |
---|---|
Delegate (0) | 2012.01.17 |
Hashtable, HashSet<T>, Dictionary<TKey, TValue> (0) | 2012.01.16 |
Generic 컬렉션 - List, Dictionary, Queue, Stack (0) | 2012.01.16 |
[C#] internal, protected internal (0) | 2012.01.16 |
public, private, protected 이외에 internal이라는 접근 제어자가 있다. 액션스크립트에서도 본적이 있는데 거의 쓸 일이 없어서 써본적이 없는것 같다.
internal은 어셈블리를 기준으로 나뉜다고 한다. 어셈블리라는 것은 한 프로젝트가 뽑아내는 결과물이다. exe가 됐던 dll 이 됐던 한 프로젝트는 결과물을 뽑아내고 이 결과물 내부에서는 public 처럼 접근이 가능하다고 한다.
접근이 불가능한 경우를 예로 들면 dll 프로젝트에서 internal로 선언된 클래스가 있다고 치면 다른 exe프로젝트에서 dll 을 참조하여 사용한다고 할 때 어셈블리가 다르기 때문에 internal 클래스에 접근 하지 못한다.
여기서 중요한 문제점 하나는 dll 을 참조하여 상속을 받으려 할 때이다. internal로 선언된 클래스는 외부 프로젝트에서 접근을 할 수 없기 때문에 외부 프로젝트에서 dll 을 참조하여 상속 받는 경우에 대한 대비책이 필요할 수 있다. 그래서 나온것이 protected internal이다. 어셈블리가 다르더라도 상속을 받게 된다면 슈퍼클래스의 protected internal속성을 접근 가능하게 된다. [출처] [C#] internal, protected internal|작성자 아오 |
Cross-thread operation not valid (0) | 2012.01.17 |
---|---|
Delegate (0) | 2012.01.17 |
Hashtable, HashSet<T>, Dictionary<TKey, TValue> (0) | 2012.01.16 |
Generic 컬렉션 - List, Dictionary, Queue, Stack (0) | 2012.01.16 |
DictionaryEntry 구조체 (0) | 2012.01.16 |