프로그램 설명
msdn 사이트에 있는 콘솔 버전을 윈도우 버전으로 수정했습니다.
원본 소스는 아래와 같습니다.
동기 서버 예제 : http://msdn.microsoft.com/ko-kr/library/6y0e13d3(v=vs.110).aspx
동기 클라이언트 예제 : http://msdn.microsoft.com/ko-kr/library/kb5kfec7(v=vs.110).aspx
수정한 부분은 로컬 아이피를 가져오는 method 추가와 문자열 자르기 method(TruncateLeft), 클라이언트가 서버로 전송하는 메시지를 윈도우(textbox)에서 입력 받아서 서버로 전송하는 부분입니다.
클라이언트에서 서버로 전송하는 문자열의 마지막에 <EOF>을 문자열을 추가해서 전송합니다.
예제에서는 클라이언트 3개를 띄워서 테스트를 해 봤습니다.
실행 후
메시지 전송 후
프로그램 작성 순서
1. 소켓/쓰레드과 관련한 네임스페이스를 서버/클라이언트 모두에 포함 시킵니다.
using System.Net; using System.Net.Sockets; using System.Threading;
2. 서버 프로그램
// Incoming data from the client public static string data = null; // Socket listen, accept private Socket listener = null; private Socket handler = null; public MainForm() { InitializeComponent(); FormClosing += new FormClosingEventHandler(MainForm_FormClosing); } public void MainForm_FormClosing(object sender, FormClosingEventArgs e) { if (handler != null) { handler.Close(); handler.Dispose(); } if (listener != null) { listener.Close(); listener.Dispose(); } Application.Exit(); } public static string TruncateLeft(string value, int maxLength) { if (string.IsNullOrEmpty(value)) return value; return value.Length <= maxLength ? value : value.Substring(0, maxLength); } // Get local IP public static string LocalIPAddress() { IPHostEntry host; string localIP = ""; host = Dns.GetHostEntry(Dns.GetHostName()); foreach (IPAddress ip in host.AddressList) { if (ip.AddressFamily == AddressFamily.InterNetwork) { localIP = ip.ToString(); return localIP; } } return "127.0.0.1"; } private void btnListen_Click(object sender, EventArgs e) { // Data buffer from incoming data byte[] bytes = new byte[1024]; // Establish the local endpoint for the socket // Dns.GetHostName returns the name of the // host running the application IPAddress localIPAddress = IPAddress.Parse(LocalIPAddress()); IPEndPoint localEndPoint = new IPEndPoint(localIPAddress, 12000); // Create a TCP/IP Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); // Bind the socket to the local endpoint and // listen for incoming connections. try { listener.Bind(localEndPoint); listener.Listen(10); new Thread(delegate() { // Start listening for connections. while (true) { Invoke((MethodInvoker)delegate { listBox1.Items.Add("Waiting for connections....."); }); // Program is suspended while waiting for an incoming connection. handler = listener.Accept(); Invoke((MethodInvoker)delegate { listBox1.Items.Add("클라이언트 연결.....OK"); }); try { data = null; // An incoming connection needs to be processed. while (true) { bytes = new byte[1024]; int bytesRec = handler.Receive(bytes); data += Encoding.UTF8.GetString(bytes, 0, bytesRec); if (data.IndexOf("<eof>") > -1) break; } // Truncate the <eof> data = TruncateLeft(data, data.Length - 5); // Show the data on the console Invoke((MethodInvoker)delegate { listBox1.Items.Add(string.Format("Text received : {0}", data)); }); // Echo the data back to the client data = "[Server Echo 메시지]" + data; byte[] msg = Encoding.UTF8.GetBytes(data); handler.Send(msg); } catch { MessageBox.Show("서버: DISCONNECTION!"); handler.Close(); handler.Dispose(); break; } } }).Start(); } catch (SocketException se) { MessageBox.Show("SocketException 에러 : " + se.ToString()); switch (se.SocketErrorCode) { case SocketError.ConnectionAborted: case SocketError.ConnectionReset: handler.Shutdown(SocketShutdown.Both); handler.Close(); break; } } catch (Exception ex) { MessageBox.Show("Exception 에러 : " + ex.ToString()); } } private void button1_Click(object sender, EventArgs e) { listBox1.Items.Clear(); }
3. 클라이언트 프로그램
// Client socket private Socket sock = null; // Data buffer from incomming data byte[] bytes = new byte[1024]; public MainForm() { InitializeComponent(); } private void btnSendText_Click(object sender, EventArgs e) { new Thread(() => { try { // Create a TCP/IP Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // Connect to the server sock.Connect(new IPEndPoint(IPAddress.Parse(textBox1.Text), 12000)); // Send the data through the socket. byte[] msg = Encoding.UTF8.GetBytes(textBox2.Text + "<eof>"); int bytesSent = sock.Send(msg); //bytes = null; int bytesRec = sock.Receive(bytes); if (bytesSent <= 0) { throw new SocketException(); } Invoke((MethodInvoker)delegate { listBox1.Items.Add(Encoding.UTF8.GetString(bytes, 0, bytes.Length)); }); } catch (SocketException se) { MessageBox.Show("SocketException = " + se.Message.ToString()); sock.Close(); sock.Dispose(); } }).Start(); } private void btnDisconnect_Click(object sender, EventArgs e) { sock.Shutdown(SocketShutdown.Both); sock.Close(); }
'C# with TCP/IP' 카테고리의 다른 글
[Program C#]비동기 서버/클라이언트 msdn 예제 - 윈도우 버전 (3) | 2015.01.02 |
---|---|
[Program C#]비동기 서버/클라이언트 msdn 예제 - 콘솔 버전 (0) | 2014.12.26 |
[Program C#]동기 서버/클라이언트 msdn 예제 - 콘솔 버전 (0) | 2014.12.23 |
[Program C#]Socket 통신 - 버퍼 사이즈보다 많은 양의 데이타를 받을 시 (0) | 2014.12.23 |
[Program C#]Socket 통신 - Handling Disconnection (0) | 2014.12.23 |