윈도우 폰 7에서 PC와의 TCP 소켓 통신

윈도우 폰 7에서 PC와 TCP 소켓 통신을 구현하는 방법을 설명합니다. 윈도우 폰 7 에뮬레이터와 PC의 간단한 TCP 서비스 간 통신을 설정하는 방법에 대해 다룹니다.

TCP 클라이언트는 주로 소켓 연결 설정, 데이터 송수신 및 기존 소켓 종료 기능을 구현합니다.

  1 using System;  
  2 using System.Net;  
  3 using System.Windows;  
  4 using System.Windows.Controls;  
  5 using System.Windows.Documents;  
  6 using System.Windows.Ink;  
  7 using System.Windows.Input;  
  8 using System.Windows.Media;  
  9 using System.Windows.Media.Animation;  
 10 using System.Windows.Shapes;  
 11   
 12 // 수동 추가된 네임스페이스  
 13 using System.Net.Sockets;  
 14 using System.Threading;  
 15 using System.Text;  
 16   
 17 namespace NetworkCommunication  
 18 {  
 19     public class TcpConnector  
 20     {  
 21         private NetworkChannel communicationSocket = null;  
 22   
 23         // 비동기 작업 완료 시 알림을 위한 이벤트 객체  
 24         static ManualResetEvent operationCompleted = new ManualResetEvent(false);  
 25   
 26         // 비동기 작업 시간 초한 정의. 이 시간 내에 응답을 받지 못하면 작업 중단.  
 27         const int OPERATION_TIMEOUT = 5000;  
 28   
 29         // 최대 수신 버퍼 크기  
 30         const int MAX_RECEIVE_BUFFER = 2048;  
 31   
 32         // 지정된 포트의 서버에 소켓 연결  
 33         // serverAddress 서버 주소  
 34         // portNumber 연결 포트  
 35         // 반환값: 연결 결과 문자열  
 36         public string EstablishConnection(string serverAddress, int portNumber)  
 37         {  
 38             string connectionResult = string.Empty;  
 39   
 40             // DnsEndPoint 생성. 서버 포트가 이 메서드에 전달됨  
 41             DnsEndPoint serverEndpoint = new DnsEndPoint(serverAddress, portNumber);  
 42   
 43             communicationSocket = new NetworkChannel(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  
 44   
 45             // 연결 요청을 위한 SocketAsyncEventArgs 객체 생성  
 46             SocketAsyncEventArgs eventArgs = new SocketAsyncEventArgs();  
 47             eventArgs.RemoteEndPoint = serverEndpoint;  
 48   
 49             // Completed 이벤트를 위한 인라인 이벤트 핸들러  
 50             // 참고: 이 이벤트 핸들러는 이 메서드를 자체적으로 포함시키기 위해 인라인으로 구현되었습니다.  
 51             eventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object sender, SocketAsyncEventArgs e)  
 52                     {  
 53                         connectionResult = e.SocketError.ToString();  
 54                         // 요청이 완료되었음을 표시, UI 스레드 차단 안 함  
 55                         operationCompleted.Set();  
 56                     }  
 57                 );  
 58   
 59             operationCompleted.Reset();  
 60             communicationSocket.ConnectAsync(eventArgs);  
 61             operationCompleted.WaitOne(OPERATION_TIMEOUT);  
 62   
 63             return connectionResult;  
 64         }  
 65   
 66         public string TransmitData(string data)  
 67         {  
 68             string response = "Operation Timeout";  
 69   
 70             if (communicationSocket != null)  
 71             {  
 72                 // SocketAsyncEventArgs 객체 생성 및 속성 설정  
 73                 SocketAsyncEventArgs eventArgs = new SocketAsyncEventArgs();  
 74                 eventArgs.RemoteEndPoint = communicationSocket.RemoteEndPoint;  
 75                 eventArgs.UserToken = null;  
 76   
 77                 eventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object sender, SocketAsyncEventArgs e)  
 78                         {  
 79                             response = e.SocketError.ToString();  
 80                             operationCompleted.Set();  
 81                         }  
 82                     );  
 83   
 84                 // 전송할 데이터를 전송 버퍼로 설정  
 85                 byte[] dataBuffer = Encoding.UTF8.GetBytes(data);  
 86                 eventArgs.SetBuffer(dataBuffer, 0, dataBuffer.Length);  
 87   
 88                 operationCompleted.Reset();  
 89                 communicationSocket.SendAsync(eventArgs);  
 90                 operationCompleted.WaitOne(OPERATION_TIMEOUT);  
 91             }  
 92             else  
 93             {  
 94                 response = "Socket is not initialized";  
 95             }  
 96   
 97             return response;  
 98         }  
 99   
100         public string ReceiveData()  
101         {  
102             string response = "Operation Timeout";  
103   
104             if (communicationSocket != null)  
105             {  
106                 SocketAsyncEventArgs eventArgs = new SocketAsyncEventArgs();  
107                 eventArgs.RemoteEndPoint = communicationSocket.RemoteEndPoint;  
108                 eventArgs.SetBuffer(new Byte[MAX_RECEIVE_BUFFER], 0, MAX_RECEIVE_BUFFER);  
109   
110                 eventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object sender, SocketAsyncEventArgs e)  
111                         {  
112                             if (e.SocketError == SocketError.Success)  
113                             {  
114                                 // 수신 버퍼에서 데이터 가져오기  
115                                 response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);  
116                                 response = response.Trim('\0');  
117                             }  
118                             else  
119                             {  
120                                 response = e.SocketError.ToString();  
121                             }  
122   
123                             operationCompleted.Set();  
124                         }  
125                     );  
126   
127                 operationCompleted.Reset();  
128                 communicationSocket.ReceiveAsync(eventArgs);  
129                 operationCompleted.WaitOne(OPERATION_TIMEOUT);  
130             }  
131             else  
132             {  
133                 response = "Socket is not initialized";  
134             }  
135   
136             return response;  
137         }  
138   
139         /// <summary>  
140         /// 소켓 연결을 닫고 관련 모든 리소스를 해제합니다  
141         /// </summary>  
142         public void TerminateConnection()  
143         {  
144             if (communicationSocket != null)  
145             {  
146                 communicationSocket.Close();  
147             }  
148         }  
149     }  
150 }  

TCP 클라이언트 사용 방법은 다음과 같습니다:

  1 using System;  
  2 using System.Collections.Generic;  
  3 using System.Linq;  
  4 using System.Net;  
  5 using System.Windows;  
  6 using System.Windows.Controls;  
  7 using System.Windows.Documents;  
  8 using System.Windows.Input;  
  9 using System.Windows.Media;  
 10 using System.Windows.Media.Animation;  
 11 using System.Windows.Shapes;  
 12 using Microsoft.Phone.Controls;  
 13   
 14 /* 
 15  * 윈도우 폰 7 에뮬레이터에서 실행하여 PC와 소켓 통신을 수행할 수 있습니다. Simple TCP 서비스에서 적절한 응답을 받습니다. 
 16 */  
 17   
 18 namespace NetworkCommunication  
 19 {  
 20     public partial class CommunicationPage : PhoneApplicationPage  
 21     {  
 22         const int ECHO_PORT = 7;  // 에코 포트: PC 시스템의 Simple TCP 서비스와 함께 사용, 수신한 문자열을 에코합니다  
 23         const int QOTD_PORT = 17; // 오늘의 명언 포트: PC 시스템의 Simple TCP 서비스와 함께 사용합니다  
 24   
 25         // 생성자  
 26         public CommunicationPage()  
 27         {  
 28             InitializeComponent();  
 29   
 30             txtServerAddress.Text = "yonghang-pc";       // 컴퓨터 이름: 바탕화면 -> 컴퓨터 속성에서 확인 가능  
 31             txtMessage.Text = "테스트 메시지";       // 전송할 문자열  
 32         }  
 33   
 34         private void btnEcho_Click(object sender, RoutedEventArgs e)  
 35         {  
 36             // 로그 초기화   
 37             ClearLog();  
 38   
 39             // 입력 유효성 확인  
 40             if (ValidateServerInput() && ValidateMessageInput())  
 41             {  
 42                 // TcpConnector 인스턴스 초기화  
 43                 TcpConnector connector = new TcpConnector();  
 44   
 45                 // Echo 서버에 연결 시작  
 46                 Log(String.Format("서버 '{0}'의 {1} 포트로 연결 중 (echo) ...", txtServerAddress.Text, ECHO_PORT), true);  
 47                 string result = connector.EstablishConnection(txtServerAddress.Text, ECHO_PORT);  
 48                 Log(result, false);  
 49   
 50                 // Echo 서버에 문자열 전송  
 51                 Log(String.Format("서버로 '{0}' 전송 중 ...", txtMessage.Text), true);  
 52                 result = connector.TransmitData(txtMessage.Text);  
 53                 Log(result, false);  
 54   
 55                 // Echo 서버로부터 응답 수신  
 56                 Log("수신 요청 중 ...", true);  
 57                 result = connector.ReceiveData();  
 58                 Log(result, false);  
 59   
 60                 // 소켓 연결 종료  
 61                 connector.TerminateConnection();  
 62             }  
 63   
 64         }  
 65   
 66         // 오늘의 명언 가져오기  
 67         private void btnGetQuote_Click(object sender, RoutedEventArgs e)  
 68         {  
 69             ClearLog();  
 70   
 71             if (ValidateServerInput())  
 72             {  
 73                 TcpConnector connector = new TcpConnector();  
 74   
 75                 Log(String.Format("서버 '{0}'의 {1} 포트로 연결 중 (오늘의 명언) ...", txtServerAddress.Text, QOTD_PORT), true);  
 76                 string result = connector.EstablishConnection(txtServerAddress.Text, QOTD_PORT);  
 77                 Log(result, false);  
 78   
 79                 Log("수신 요청 중 ...", true);  
 80                 result = connector.ReceiveData();  
 81                 Log(result, false);  
 82   
 83                 connector.TerminateConnection();  
 84             }  
 85         }  
 86   
 87         // 입력 확인  
 88         private bool ValidateMessageInput()  
 89         {  
 90             if (String.IsNullOrWhiteSpace(txtMessage.Text))  
 91             {  
 92                 MessageBox.Show("전송할 문자열을 입력하세요.");  
 93                 return false;  
 94             }  
 95   
 96             return true;  
 97         }  
 98   
 99         // 서버 입력 확인  
100         private bool ValidateServerInput()  
101         {  
102             if (String.IsNullOrWhiteSpace(txtServerAddress.Text))  
103             {  
104                 MessageBox.Show("서버 주소를 입력하세요!");  
105                 return false;  
106             }  
107   
108             return true;  
109         }  
110   
111        // TextBox에 테스트 정보 출력  
112         private void Log(string message, bool isOutgoing)  
113         {  
114             string direction = (isOutgoing) ? ">> " : "<< ";  
115             txtOutput.Text += Environment.NewLine + direction + message;  
116         }  
117   
118         // 테스트 정보 초기화  
119         private void ClearLog()  
120         {  
121             txtOutput.Text = String.Empty;  
122         }  
123     }  
124 }  

태그: 윈도우 폰 7 TCP 소켓 비동기 프로그래밍 네트워크 통신 C#

5월 27일 15:28에 게시됨