블로그 이미지
따시쿵

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 31

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 따시쿵
2014. 12. 23. 11:52 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), 클라이언트가 서버로 전송하는 메시지를 콘솔에서 입력 받아서 서버로 전송하는 부분입니다.


클라이언트에서 서버로 전송하는 문자열의 마지막에 <EOF>을 문자열을 추가해서 전송합니다.


데모로 나와 있는 소스는 클라이언트가 메시지를 한 번 전송하고, 에코 메시지를 받는 것이 전부입니다. 계속 메시지를 전송할 수 있는 것이 아닙니다.


예제에서는 클라이언트 3개를 띄워서 테스트를 해 봤습니다.


실행 후




메시지 전송 후




프로그램 작성 순서


1. 소켓/쓰레드과 관련한 네임스페이스를 서버/클라이언트 모두에 포함 시킵니다.

using System.Net;
using System.Net.Sockets;
using System.Threading;


2. 서버 프로그램

        // Incoming data from the client
        public static string data = null;

        public static string TruncateLeft(string value, int maxLength)
        {
            if (string.IsNullOrEmpty(value)) return value;
            return value.Length <= maxLength ? value : value.Substring(0, maxLength);
        }

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

        public static void StartListening()
        {
            Socket listener = null;
            Socket handler = null;

            // 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, 11000);

            // Create a TCP/IP Socket
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            // Bind the socket to the local endpoint and
            // listen for incoming connections.
            try{
                listener.Bind(localEndPoint);
                listener.Listen(10);

                // Start listening for connections.
                while(true)
                {
                    Console.WriteLine("Waiting for connections.....");

                    // Program is suspended while waiting for an incoming connection.
                    handler = listener.Accept();
                    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
                    Console.WriteLine("Text received : {0}", data);

                    // Echo the data back to the client
                    data = "[Server Echo 메시지]" + data;
                    byte[] msg = Encoding.UTF8.GetBytes(data);

                    handler.Send(msg);
                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();
                }
            }
            catch (SocketException se)
            {
                Console.WriteLine("Socket 에러 : {0}", se.ToString());
                switch(se.SocketErrorCode)
                {
                    case SocketError.ConnectionAborted:
                    case SocketError.ConnectionReset:
                        handler.Close();
                        break;
                }
            }
            catch(Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        static void Main(string[] args)
        {
            StartListening();
            Console.ReadLine();
        }


2. 클라이언트 프로그램

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

        private static void StartClient()
        {
            // Data buffer fr incomming data
            byte[] bytes = new byte[1024];

            // Connect to a remote device
            try
            {
                // Establish the remote endpoint for the socket.
                // This example uses port 11000 on the local computer.
                IPAddress remoteIPAddress = IPAddress.Parse(LocalIPAddress());
                IPEndPoint remoteEndPoint = new IPEndPoint(remoteIPAddress, 11000);

                // Create a TCP/IP Socket
                Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                // Connect the socket to the remote endpoint Catch any errors.
                try
                {
                    sender.Connect(remoteEndPoint);

                    Console.WriteLine("Socket connected to {0}", sender.RemoteEndPoint.ToString());

                    // Encoding the data string into a byte array.
                    Console.Write("Client 메시지 :");
                    byte[] msg = Encoding.UTF8.GetBytes(Console.ReadLine());
                    
                    // Send the data through the socket.
                    int bytesSent = sender.Send(msg);

                    // Receive the response from the remote device
                    int bytesRec = sender.Receive(bytes);
                    Console.WriteLine("Echoed test = {0}", Encoding.UTF8.GetString(bytes, 0, bytesRec));

                    // Release the socket.
                    sender.Shutdown(SocketShutdown.Both);
                    sender.Close();
                }
                catch(ArgumentNullException ane)
                {
                    Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
                }
                catch(SocketException se)
                {
                    Console.WriteLine("SocketException : {0}", se.ToString());
                }
                catch(Exception e)
                {
                    Console.WriteLine("Unexpected exception : {0}", e.ToString());
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        static void Main(string[] args)
        {
            StartClient();
            Console.ReadLine();
        }


posted by 따시쿵
2014. 12. 23. 11:52 C# with TCP/IP

프로그램 설명


클라이언트가 보낸 데이타의 양이 많아서 한 번에 받을 수가 없는 경우가 있습니다. 보낸 데이타를 손실없이 모두 다 받는 방법을 설명합니다.


프로그램 구조의 핵심은 클라이언트가 데이타를 보낼때에 전송 데이타 사이즈를 미리 전송하고, 두 번째로 실제 데이타를 존송합니다.


서버에서는 전송된 데이타 사이즈를 미리 받아서 받을 버퍼 사이즈 크기를 결정하고, 받을 데이타가 모두 전송 될 때까지 루프를 돌면서 메모리 스트림에 기록을 한 후에, 화면에 보여줄 때에 한꺼번에 가져와서 화면에 보여 줍니다.


accept 소켓의 ReceiveBufferSize 속성 값이 65536 (int) 이니 일반적인 텍스트를 주고 받는 데에는 별무리가 없을 것으로 보이고, 단지 파일를 전송할때에는 영향을 받을 것으로 보입니다.


예제는 상당히 긴 텍스트를 전송하기는 것을 시나리오로 작성했습니다.


실행 후





메시지 전송 후







프로그램 작성 순서


1. 소켓/쓰레드과 관련한 네임스페이스를 서버/클라이언트 모두에 포함 시킵니다.

using System.Net;
using System.Net.Sockets;
using System.Threading;


2. 서버 프로그램

        Socket sck;
        Socket acc;

        public MainForm()
        {
            InitializeComponent();
        }

        private void btnListen_Click(object sender, EventArgs e)
        {
            sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            sck.Bind(new IPEndPoint(0, 8));
            sck.Listen(0);

            acc = sck.Accept();

            sck.Close();

            new Thread(() =>
            {
                while(true)
                {
                    try
                    {
                        byte[] sizeBuf = new byte[4];

                        acc.Receive(sizeBuf, 0, sizeBuf.Length, 0);

                        int size = BitConverter.ToInt32(sizeBuf, 0);
                        MemoryStream ms = new MemoryStream();

                        while (size > 0)
                        {
                            byte[] buffer;
                            if (size < acc.ReceiveBufferSize)
                                buffer = new byte[size];
                            else
                                buffer = new byte[acc.ReceiveBufferSize];

                            int rec = acc.Receive(buffer, 0, buffer.Length, 0);

                            size -= rec;

                            ms.Write(buffer, 0, buffer.Length);
                        }

                        ms.Close();

                        byte[] data = ms.ToArray();

                        ms.Dispose();

                        Invoke((MethodInvoker)delegate
                        {
                            richTextBox1.Text = Encoding.UTF8.GetString(data);
                        });
                    }
                    catch
                    {
                        MessageBox.Show("서버: DISCONNECTION!");
                        acc.Close();
                        acc.Dispose();
                        break;
                    }
                }
                Application.Exit();
            }).Start();
        }
    }


3. 클라이언트 프로그램

        Socket sck;
        public MainForm()
        {
            InitializeComponent();
            FormClosing += new FormClosingEventHandler(MainForm_FormClosing);
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (sck.Connected)
                sck.Close();
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                sck.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8));
            }
            catch
            {
                MessageBox.Show("Unable to connect!");
            }
        }

        private void btnSendText_Click(object sender, EventArgs e)
        {
            byte[] data = Encoding.UTF8.GetBytes(richTextBox1.Text);

            sck.Send(BitConverter.GetBytes(data.Length), 0, 4, 0);
            sck.Send(data);
        }

posted by 따시쿵