블로그 이미지
따시쿵

calendar

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

Notice

2014. 12. 23. 12:38 C# with TCP/IP

프로그램 설명


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();
        }


posted by 따시쿵