posted by 방랑군 2012. 1. 22. 00:14

1. byte[] 배열 합치기

C의 유연함에 익숙한 사용자는 갑갑할 수 밖에 없다. System.Array의 인스턴스는 특정 위치부터 배열을 복사하는 기능을 제공하지 않는데, 인터넷을 뒤져보니 그냥 for 루프로 돌리는 사람도 있고, CopyTo() 메서드를 잘못 이해해서 틀린 정보를 제공하는 사람도 있고 가지가지다.

 

<Array.CopyTo() 메서드의 틀린 사용 예>

byte[] a= new byte[3]{1,2,3};

byte[] b= new byte[4]{4,5,6,7};

byte[] c= byte[a.Length+b.Length];

a.CopyTo(c,0);

b.CopyTo(c,a.Length); 

 

 얼핏 보면 올바른 코드로 보이지만, CopyTo의 두 번째 인자는 목적 배열의 인덱스가 아니라 소스 배열의 인덱스라는데 이 코드의 치명적인 오류가 있다.

 즉, 위의 코드에의 결과는 c={7,2,3} 이 되어 버린다.

 

결론은 Array.Copy() 메서드를 사용한다.

 

위 코드는 아래처럼 바꾸면 된다.

Array.Copy(a, 0, c, 0, a.Length);

Array.Copy(b, 0, c, a.Length,b.Length);

 

2. htonl, ltons 소켓라이브러리 함수와 같은 기능을 하는 .NET 라이브러리는?

System.Net.IPAddress.HostToNetworkOrder()

System.Net.IPAddress.NetworkToHostOrder()

 

3. int, short 같은 정수를 byte[]으로 상호 변환하려면?

System.BitConverter의 메서드를 사용한다.

 

System.BitConverter.ToInt32(packet, 0);

 

4. 비동기 메서드 BeginXXX(), EndXXX()를 사용할 때 윈폼 컨트롤에 접근하는 코드는?

 비동기 메서드 BeginReceive, EndReceive 등을 사용할 때 EndReceive 에서는 AsyncCallback 개체를 사용하여 별도의 스레드에서 데이터를 수신하게 되는데, 이 스레드에서는 윈폼 컨트롤로 바로 출력할 수 없다. 이 때는 윈폼의 Invoke 메서드를 사용한다.

 

 Invoke의 첫 번째 인자는 Delegate이고 두 번째 인자는 관련된 변수이다. 아래는  EndReceive에서 byte[]형 데이터를 수신해서 ReceivedData 라는 사용자 이벤트를 발생했을 경우의 예이다.

        delegate void VerbosePrinter(string msg);

        void PrintText(string s)
        {
            txtOut.AppendText(s + "\r\n");
            txtOut.ScrollToCaret();
        }
        void p(string s)
        {
            this.Invoke(new VerbosePrinter(PrintText), s);
        }

        void cli_ReceivedData(object sender, byte[] bytes)
        {

               p(Encoding.Default.GetString(bytes);
        }