README

소켓 프로그램, 특별 비동기 방식에 대한 MSDN 라이브러리의 예제 코드를 보여줍니다.


비동기 서버 소켓 Ex

http://msdn.microsoft.com/en-us/library/fx6588te.aspx


비동기 클라 소켓 Ex

http://msdn.microsoft.com/en-us/library/bew39x2a.aspx


비동기 서버 소켓을 사용하여

http://msdn.microsoft.com/en-us/library/5w7b7x5f.aspx



Client.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// Asynchronous Client Socket Example
// http://msdn.microsoft.com/en-us/library/bew39x2a.aspx
 
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
 
// 원격 장치로부터 데이터를 수신하는 상태 객체.
public class StateObject 
{
    // Client socket.
    public Socket workSocket = null;
    // Size of receive buffer.
    public const int BufferSize = 256;
    // Receive buffer.
    public byte[] buffer = new byte[BufferSize];
    // Received data string.
    public StringBuilder sb = new StringBuilder();
}
 
public class AsynchronousClient 
{
    // 원격 장치의 포트 번호.
    private const int port = 11000;
 
    // ManualResetEvent 인스턴스가 완료되었음을 알립니다.
    private static ManualResetEvent connectDone = 
        new ManualResetEvent(false);
    private static ManualResetEvent sendDone = 
        new ManualResetEvent(false);
    private static ManualResetEvent receiveDone = 
        new ManualResetEvent(false);
 
    // 원격 장치에서 응답.
    private static String response = String.Empty;
 
    private static void StartClient() 
    {
        // 원격 장치에 연결합니다.
        try {
            // 소켓의 원격 끝점을 설정합니다.
            // 원격 장치는 "host.contoso.com"입니다.
            IPHostEntry ipHostInfo = Dns.Resolve("host.contoso.com");
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
 
            // Create a TCP/IP socket.
            Socket client = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);
 
            // Connect to the remote endpoint.
            client.BeginConnect( remoteEP, 
                new AsyncCallback(ConnectCallback), client);
            connectDone.WaitOne();
 
            // 원격 장치에 대한 테스트 데이터를 전송합니다.
            Send(client,"This is a test<EOF>");
            sendDone.WaitOne();
 
            // 원격 장치로부터 응답을 수신합니다.
            Receive(client);
            receiveDone.WaitOne();
 
            // 콘솔에 대한 응답을 작성합니다.
            Console.WriteLine("Response received : {0}", response);
 
            // Release the socket.
            client.Shutdown(SocketShutdown.Both);
            client.Close();
            
        } catch (Exception e) {
            Console.WriteLine(e.ToString());
        }
    }
 
    private static void ConnectCallback(IAsyncResult ar) 
    {
        try 
        {
            // 상태 개체에서 소켓을 검색합니다.
            Socket client = (Socket) ar.AsyncState;
 
            // 연결을 완료합니다.
            client.EndConnect(ar);
 
            Console.WriteLine("Socket connected to {0}",
                client.RemoteEndPoint.ToString());
 
            // 연결이 된 것을 알려줍니다.
            connectDone.Set();
        } 
        catch (Exception e) 
        {
            Console.WriteLine(e.ToString());
        }
    }
 
    private static void Receive(Socket client) 
    {
        try 
        {
            // Create the state object.
            StateObject state = new StateObject();
            state.workSocket = client;
 
            // 원격 장치로부터 데이터를 수신하기 시작한다.
            client.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReceiveCallback), state);
        } 
        catch (Exception e) 
        {
            Console.WriteLine(e.ToString());
        }
    }
 
    private static void ReceiveCallback( IAsyncResult ar ) 
    {
        try 
        {
            // 상태 개체와 클라이언트 소켓을 취득합니다
            // 비동기 상태 개체에서.
            StateObject state = (StateObject) ar.AsyncState;
            Socket client = state.workSocket;
 
            // 원격 장치에서 데이터를 읽습니다.
            int bytesRead = client.EndReceive(ar);
 
            if (bytesRead > 0
            {
                // There might be more data, so store the data received so far.
                // 더 많은 데이터가 될 수 있으므로, 지금까지 수신 된 데이터를 저장할 수도있다.
            state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));
 
                // 나머지 데이터를 가져옵니다.
                client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,
                    new AsyncCallback(ReceiveCallback), state);
            } 
            else 
            {
                // 모든 데이터가 도착했습니다. 응답 그것을 놓습니다.
                if (state.sb.Length > 1
                {
                    response = state.sb.ToString();
                }
                // 모든 바이트가 수신 된 신호.
                receiveDone.Set();
            }
        } 
        catch (Exception e) 
        {
            Console.WriteLine(e.ToString());
        }
    }
 
    private static void Send(Socket client, String data) 
    {
        // ASCII 인코딩을 사용하여 바이트의 데이터를 문자열 데이터를 변환합니다.
        byte[] byteData = Encoding.ASCII.GetBytes(data);
 
        // 원격 장치에 데이터를 보내기 시작.
        client.BeginSend(byteData, 0, byteData.Length, 0,
            new AsyncCallback(SendCallback), client);
    }
 
    private static void SendCallback(IAsyncResult ar) 
    {
        try 
        {
            // 상태 개체에서 소켓을 검색합니다.
            Socket client = (Socket) ar.AsyncState;
 
            // 원격 장치에 데이터를 송신 완료.
            int bytesSent = client.EndSend(ar);
            Console.WriteLine("Sent {0} bytes to server.", bytesSent);
 
            // 모든 바이트가 전송 된 것을 신호.
            sendDone.Set();
        } 
        catch (Exception e) 
        {
            Console.WriteLine(e.ToString());
        }
    }
    
    public static int Main(String[] args) 
    {
        StartClient();
        return 0;
    }
}
cs



Server.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// Asynchronous Server Socket Example
// http://msdn.microsoft.com/en-us/library/fx6588te.aspx
 
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
 
// 비동기 클라이언트 데이터를 읽을 수있는 상태 개체
public class StateObject 
{
    // Client  socket.
    public Socket workSocket = null;
    // Size of receive buffer.
    public const int BufferSize = 1024;
    // Receive buffer.
    public byte[] buffer = new byte[BufferSize];
    // Received data string.
    public StringBuilder sb = new StringBuilder();  
}
 
public class AsynchronousSocketListener 
{
    // 스레드 신호.
    public static ManualResetEvent allDone = new ManualResetEvent(false);
 
    public AsynchronousSocketListener() {
    }
 
    public static void StartListening() 
{
        // 들어오는 데이터에 대한 데이터 버퍼입니다.
        byte[] bytes = new Byte[1024];
 
        // 소켓의 로컬 엔드 포인트를 설정합니다.
        // 컴퓨터의 DNS 이름
        // 리스너를 실행하는 "host.contoso.com"입니다.
        IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
        IPAddress ipAddress = ipHostInfo.AddressList[0];
        IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
 
        // Create a TCP/IP socket.
        Socket listener = new Socket(AddressFamily.InterNetwork,
            SocketType.Stream, ProtocolType.Tcp );
 
        // 로컬 끝점에 소켓을 바인드하고 들어오는 연결을 기다리고 있습니다.
        try 
        {
            listener.Bind(localEndPoint);
            listener.Listen(100);
 
            while (true
            {
                // Set the event to nonsignaled state.
                allDone.Reset();
 
                // 연결을 수신 할 수있는 비동기 소켓을 시작합니다.
                Console.WriteLine("Waiting for a connection...");
                listener.BeginAccept( 
                    new AsyncCallback(AcceptCallback),
                    listener );
 
                // 연결은 계속하기 전에 때까지 기다립니다.
                allDone.WaitOne();
            }
 
        } 
        catch (Exception e) 
        {
            Console.WriteLine(e.ToString());
        }
 
        Console.WriteLine("\nPress ENTER to continue...");
        Console.Read();
        
    }
 
    public static void AcceptCallback(IAsyncResult ar) 
    {
        // 메인 스레드가 계속해서 신호를 출력합니다.
        allDone.Set();
 
        // 클라이언트 요청을 처리하는 소켓을 가져옵니다.
        Socket listener = (Socket) ar.AsyncState;
        Socket handler = listener.EndAccept(ar);
 
        // 상태 개체를 만듭니다.
        StateObject state = new StateObject();
        state.workSocket = handler;
        handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
            new AsyncCallback(ReadCallback), state);
    }
 
    public static void ReadCallback(IAsyncResult ar) 
    {
        String content = String.Empty;
 
        // 비동기 상태 개체에서.
        // 상태 개체 처리기 소켓을 가져옵니다
        StateObject state = (StateObject) ar.AsyncState;
        Socket handler = state.workSocket;
 
        // 클라이언트 소켓에서 데이터를 읽습니다.
        int bytesRead = handler.EndReceive(ar);
 
        if (bytesRead > 0
        {
            // There  might be more data, so store the data received so far.
            state.sb.Append(Encoding.ASCII.GetString(
                state.buffer,0,bytesRead));
 
            // Check for end-of-file tag. If it is not there, read 
            // more data.
            content = state.sb.ToString();
            if (content.IndexOf("<EOF>"> -1
            {
                // All the data has been read from the 
                // client. Display it on the console.
                Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
                    content.Length, content );
                // Echo the data back to the client.
                Send(handler, content);
            } 
            else 
            {
                // Not all data received. Get more.
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);
            }
        }
    }
    
    private static void Send(Socket handler, String data) 
    {
        // ASCII 인코딩을 사용하여 바이트 문자열 데이터를 변환합니다.
        byte[] byteData = Encoding.ASCII.GetBytes(data);
 
        // 원격 장치에 데이터 전송을 시작합니다.
        handler.BeginSend(byteData, 0, byteData.Length, 0,
            new AsyncCallback(SendCallback), handler);
    }
 
    private static void SendCallback(IAsyncResult ar) 
    {
        try 
        {
            // Retrieve the socket from the state object.
            Socket handler = (Socket) ar.AsyncState;
 
            // Complete sending the data to the remote device.
            int bytesSent = handler.EndSend(ar);
            Console.WriteLine("Sent {0} bytes to client.", bytesSent);
 
            handler.Shutdown(SocketShutdown.Both);
            handler.Close();
 
        } 
        catch (Exception e) 
        {
            Console.WriteLine(e.ToString());
        }
    }
 
 
    public static int Main(String[] args) 
    {
        StartListening();
        return 0;
    }
}
cs


  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기