블로그 이미지
따시쿵

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

2015. 1. 17. 16:24 C# with TCP/IP

닷넷 환경에서 구조체를 이용한 소켓 통신을 지원하기 위한 방법은 크게 두 가지로 나뉩니다.


★ 마샬링(Marshaling)을 이용한 구조체 사용.

★ 바이너리 포매터(Binary Formatter)의 사용.


이번에는 마샬링 기법을 이용한 구조체를 통신하기 위한 방법을 소개합니다.


프로그램 설명


클라이언트가 학생의 4가지 데이타(이름, 과목, 점수, 메모)를 서버로 전송한다고 가정하고 필요한 클래스는 아래와 같습니다.

    class DataPacket
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
        public string Name;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
        public string Subject;

        [MarshalAs(UnmanagedType.I4)]
        public int Grade;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
        public string Memo;
    }


실행 후



메시지 전송 후



프로그램 작성 순서


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

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


2. 서버 프로그램


    class Program
    {
        static void Main(string[] args)
        {
            TcpListener server = null;

            try
            {
                server = new TcpListener(IPAddress.Parse("192.168.0.12"), 13000);
                server.Start();

                byte[] buffer = new byte[8092];
                
                while(true)
                {
                    Console.WriteLine("Waiting for a connection.....");

                    TcpClient client = server.AcceptTcpClient();
                    Console.WriteLine("\nConnected!!");

                    NetworkStream stream = client.GetStream();

                    DataPacket packet = new DataPacket();
                    //buffer = null;

                    while(stream.Read(buffer, 0, Marshal.SizeOf(packet)) != 0)
                    {
                        unsafe
                        {
                            fixed(byte* fixed_buffer = buffer)
                            {
                                Marshal.PtrToStructure((IntPtr)fixed_buffer, packet);
                            }
                        }

                        string Name = packet.Name;
                        string Subject = packet.Subject;
                        Int32 Grade = packet.Grade;
                        string Memo = packet.Memo;

                        
                        Console.WriteLine("이 름 : {0}", Name);
                        Console.WriteLine("과 목 : {0}", Subject);
                        Console.WriteLine("점 수 : {0}", Grade);
                        Console.WriteLine("메 모 : {0}", Memo);
                        Console.WriteLine("");
                        Console.WriteLine("===========================================");
                        Console.WriteLine("");
                    }

                    stream.Close();
                    client.Close();
                }
            }
            catch(SocketException se)
            {
                Console.WriteLine(se.Message.ToString());
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
            }

            Console.ReadLine();
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    class DataPacket
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
        public string Name;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
        public string Subject;

        [MarshalAs(UnmanagedType.I4)]
        public int Grade;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
        public string Memo;
    }


3. 클라이언트 프로그램


    class Program
    {
        static void Main(string[] args)
        {
            try 
            {
                string Name = string.Empty;
                string Subject = string.Empty;
                Int32 Grade = 0;
                string Memo = string.Empty;

                do
                {
                    Console.Write("이름 : ");
                    Name = Console.ReadLine();

                    Console.Write("과목 : ");
                    Subject = Console.ReadLine();

                    Console.Write("점수 : ");
                    string tmpGrage = Console.ReadLine();
                    if (tmpGrage != "")
                        Grade = Convert.ToInt32(tmpGrage);
                    else
                        Grade = 0;

                    Console.Write("메모 : ");
                    Memo = Console.ReadLine();

                    if (string.IsNullOrEmpty(Name) || string.IsNullOrEmpty(Subject))
                        break;

                    // 전송할 데이타 가공하기
                    DataPacket packet = new DataPacket();

                    packet.Name = Name;
                    packet.Subject = Subject;
                    packet.Grade = Grade;
                    packet.Memo = Memo;

                    byte[] buffer = new byte[Marshal.SizeOf(packet)];

                    unsafe
                    {
                        fixed (byte* fixed_buffer = buffer)
                        {
                            Marshal.StructureToPtr(packet, (IntPtr)fixed_buffer, false);
                        }
                    }

                    // 데이타 전송하기
                    TcpClient client = new TcpClient();
                    client.Connect("192.168.0.12", 13000);
                    Console.WriteLine("Connected...");

                    NetworkStream stream = client.GetStream();

                    stream.Write(buffer, 0, Marshal.SizeOf(packet));
                    Console.WriteLine("{0} data sent\n", Marshal.SizeOf(packet));

                    stream.Close();
                    client.Close();
                } while (Name != "" && Subject != "");
            }
            catch (SocketException se)
            {
                Console.WriteLine(se.Message.ToString());
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
            }
            Console.WriteLine("\nPress enter key to continue....");
            Console.ReadLine();
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    class DataPacket
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
        public string Name;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
        public string Subject;

        [MarshalAs(UnmanagedType.I4)]
        public int Grade;
      
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
        public string Memo;
    }


posted by 따시쿵
2015. 1. 15. 16:29 C# with TCP/IP

프로그램 설명


서버와 클라이언트를 각각 쓰레드를 이용한 멀티프로그램으로 예제를 만들어 보았습니다.


실행 후



메시지 전송 후



프로그램 작성 순서


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

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

2. 서버 프로그램

        private void btnStart_Click(object sender, EventArgs e)
        {
            Thread tcpServerRunThread = new Thread(new ThreadStart(TcpServerRun));
            tcpServerRunThread.IsBackground = true;
            tcpServerRunThread.Start();
        }

        private void TcpServerRun()
        {
            TcpListener tcpListener = new TcpListener(IPAddress.Any, 5004);
            tcpListener.Start();
            updateUI("Listening");
            updateUI("===========================================");

            while(true)
            {
                TcpClient client = tcpListener.AcceptTcpClient();
                updateUI("Connected");
                Thread tcpHandlerThread = new Thread(new ParameterizedThreadStart(tcpHandler));
                tcpHandlerThread.Start(client);
            }
        }

        private void tcpHandler(object client)
        {
            TcpClient mClient = client as TcpClient;
            NetworkStream stream = mClient.GetStream();
            byte[] message = new byte[1024];
            int byteRead = stream.Read(message, 0, message.Length);
            updateUI("New Message = " + Encoding.UTF8.GetString(message, 0, byteRead));
            updateUI("");

            stream.Close();
            mClient.Close();
        }

        private void updateUI(string s)
        {
            Action del = delegate()
            {
                textBox1.AppendText(s + System.Environment.NewLine);
            };
            Invoke(del);
        }

3. 클라이언트 프로그램

        private void btnSend_Click(object sender, EventArgs e)
        {
            Thread mThread = new Thread(new ThreadStart(SendAsClient));
            mThread.Start();
        }

        private void SendAsClient()
        {
            TcpClient client = new TcpClient();
            client.Connect(IPAddress.Parse(textServerIP.Text), Convert.ToInt32(textServerPort.Text));
            updateUI("Connected");

            NetworkStream stream = client.GetStream();

            string sendData = textMessage.Text;
            byte[] msg = new byte[256];
            msg = Encoding.UTF8.GetBytes(sendData);

            stream.Write(msg, 0, msg.Length);
            updateUI(string.Format("send data : {0}", sendData));
            updateUI(string.Format("{0} bytes sent", msg.Length ));

            stream.Close();
            client.Close();
        }

        private void updateUI(string s)
        {
            Func<int> del = delegate()
            {
                textBox1.AppendText(s + System.Environment.NewLine);
                return 0;
            };
            Invoke(del);
        }


posted by 따시쿵
2015. 1. 13. 16:16 C# with TCP/IP

프로그램 설명


msdn 에 있는 예제를 가지고 만든 버전입니다.


TcpListener 클래스 

http://msdn.microsoft.com/ko-kr/library/system.net.sockets.tcplistener(v=vs.110).aspx


TcpClient 클래스

http://msdn.microsoft.com/ko-kr/library/system.net.sockets.tcpclient(v=vs.110).aspx


클라이언트 버전은 사용자 입력을 반복적으로 입력받을 수 있게 수정했습니다.


클라이언트의 메시지를 서버가 받아서 대문자로 변경해 주는 작업만 처리합니다.



실행 후



메시지 전송 후




프로그램 작성 순서


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

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


2. 서버 프로그램

        TcpListener server = null;
 
        public MainForm()
        {
            InitializeComponent();
            FormClosing += new FormClosingEventHandler(Form_Closing);
        }

        private void Form_Closing(object sender, FormClosingEventArgs e)
        {
            if (server != null)
                server = null;

            Application.Exit();
        }
        
        private void btnListen_Click(object sender, EventArgs e)
        {
            new Thread(delegate()
                {
                    try
                    {
                        // Set the TcpListener on port 14000.
                        Int32 port = 14000;
                        IPAddress localAddr = IPAddress.Parse("127.0.0.1");

                        // TcpListener server = new TcpListener(port);
                        server = new TcpListener(localAddr, port);
                        server.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

                        // Start listening for client requests.
                        server.Start();

                        // Buffer for reading data
                        Byte[] bytes = new Byte[256];
                        String data = null;
                        
                        // Enter the listening loop.
                        while (true)
                        {
                            Invoke((MethodInvoker)delegate
                            {
                                listBox1.Items.Add("Waiting for a connection... ");
                            });

                            // Perform a blocking call to accept requests.
                            // You could also user server.AcceptSocket() here.
                            TcpClient client = server.AcceptTcpClient();
                            Invoke((MethodInvoker)delegate
                            {
                                listBox1.Items.Add("Connected!");
                            });

                            data = null;

                            // Get a stream object for reading and writing
                            NetworkStream stream = client.GetStream();

                            int i;

                            // Loop to receive all the data sent by the client.
                            while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
                            {
                                // Translate data bytes to a ASCII string.
                                data = System.Text.Encoding.UTF8.GetString(bytes, 0, i);
                                Invoke((MethodInvoker)delegate
                                {
                                    listBox1.Items.Add(string.Format("Received: {0}", data));
                                });

                                // Process the data sent by the client.
                                data = data.ToUpper();

                                byte[] msg = System.Text.Encoding.UTF8.GetBytes(data);

                                // Send back a response.
                                stream.Write(msg, 0, msg.Length);
                                Invoke((MethodInvoker)delegate
                                {
                                    listBox1.Items.Add(string.Format("Sent: {0}", data));
                                    listBox1.Items.Add("");
                                });
                            }

                            // Shutdown and end connection
                            client.Close();
                        }  // end of outer while                    
                    }
                    catch (SocketException se)
                    {
                        MessageBox.Show(string.Format("SocketException: {0}", se.Message.ToString()));
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(string.Format("Exception: {0}", ex.Message.ToString()));
                    }
                    finally
                    {
                        // Stop listening for new clients.
                        server.Stop();
                    }
            }).Start();
        }

2. 클라이언트 프로그램


        private void btnSend_Click(object sender, EventArgs e)
        {
            string serverIP = textServerIP.Text;
            string sendData = textMessage.Text;

            SendMessage(serverIP, sendData);
        }

        private void SendMessage(string server, string message)
        {
            try
            {
                // Create a TcpClient.
                // Note, for this client to work you need to have a TcpServer 
                // connected to the same address as specified by the server, port
                // combination.
                Int32 port = 14000;
                TcpClient client = new TcpClient(server, port);

                // Translate the passed message into ASCII and store it as a Byte array.
                Byte[] data = System.Text.Encoding.UTF8.GetBytes(message);

                // Get a client stream for reading and writing.
                //  Stream stream = client.GetStream();

                NetworkStream stream = client.GetStream();

                // Send the message to the connected TcpServer. 
                stream.Write(data, 0, data.Length);

                Invoke((MethodInvoker)delegate
                {
                    listBox1.Items.Add(string.Format("Sent: {0}", message));
                });

                // Receive the TcpServer.response.

                // Buffer to store the response bytes.
                data = new Byte[256];

                // String to store the response ASCII representation.
                String responseData = String.Empty;

                // Read the first batch of the TcpServer response bytes.
                Int32 bytes = stream.Read(data, 0, data.Length);
                responseData = System.Text.Encoding.UTF8.GetString(data, 0, bytes);
                Invoke((MethodInvoker)delegate
                {
                    listBox1.Items.Add(string.Format("Received: {0}", responseData));
                    listBox1.Items.Add("");
                });

                // Close everything.
                stream.Close();
                client.Close();
            }
            catch (ArgumentNullException e)
            {
                MessageBox.Show(string.Format("ArgumentNullException: {0}", e.Message.ToString()));
            }
            catch (SocketException e)
            {
                MessageBox.Show(string.Format("SocketException: {0}", e.Message.ToString()));
            }
        }
posted by 따시쿵
2015. 1. 9. 07:51 C# with TCP/IP

프로그램 설명


msdn 에 있는 예제를 가지고 만든 버전입니다.


TcpListener 클래스 

http://msdn.microsoft.com/ko-kr/library/system.net.sockets.tcplistener(v=vs.110).aspx


TcpClient 클래스

http://msdn.microsoft.com/ko-kr/library/system.net.sockets.tcpclient(v=vs.110).aspx


클라이언트 버전은 사용자 입력을 반복적으로 입력받을 수 있게 수정했습니다.


클라이언트의 메시지를 서버가 받아서 대문자로 변경해 주는 작업만 처리합니다.


실행 후



메시지 전송 후




프로그램 작성 순서


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

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


2. 서버 프로그램


        static void Main(string[] args)
        {
            TcpListener server = null;

            try
            {
                // Set the TcpListener on port 13000
                Int32 port = 14000;
                IPAddress localAddr = IPAddress.Parse("127.0.0.1");

                // TcpListener server = new TcpListener(port);
                server = new TcpListener(localAddr, port);

                // Starting listening for client requests.
                server.Start();

                // Buffer for reading data
                byte[] bytes = new byte[256];
                string data = string.Empty;

                // Enter the listening loop
                while(true)
                {
                    Console.WriteLine("Waiting for a connection...");

                    // Perform a blocking call to accept requests.
                    // You could also user server.AcceptSocket() here
                    TcpClient client = server.AcceptTcpClient();
                    Console.WriteLine("Connected!");

                    data = string.Empty;

                    // Get a stream object for reading and writing
                    NetworkStream stream = client.GetStream();

                    int bytesRead = 0;
                    // Loop to receive all the data sent by the client
                    while( (bytesRead=stream.Read(bytes, 0, bytes.Length)) != 0)
                    {
                        // Translate data bytes to a UTF8.
                        data = Encoding.UTF8.GetString(bytes, 0, bytesRead);
                        Console.WriteLine("Received: {0}", data);

                        // Process tha data sent by the client
                        data = data.ToUpper();

                        byte[] msg = Encoding.UTF8.GetBytes(data);

                        // Send back a response
                        stream.Write(msg, 0, msg.Length);
                        Console.WriteLine("Sent: {0}\n", data);
                    }

                    // Shutdown and end connection
                    client.Close();
                }
            }
            catch(SocketException se)
            {
                Console.WriteLine("SocketException : {0}", se.Message.ToString());
            }
            finally
            {
                // Stop listening for new clients
                server.Stop();
            }

            Console.WriteLine("\nHit enter to continue...");
            Console.Read(); 
        }

3. 클라이언트 프로그램


        static void Main(string[] args)
        {
            string sendData = string.Empty;
            do
            {
                Console.Write("\n전송할 데이타를 입력해 주세요 : ");
                sendData = Console.ReadLine();

                if (!string.IsNullOrEmpty(sendData))
                    Connect("127.0.0.1", sendData);
            } while (sendData != "");
            
            Console.WriteLine("\nPress Enter to continue...");
            Console.Read();
        }

        static void Connect(string server, string message)
        {
            try
            {
                // Create a TcpClient
                // Note, for this client to work you need to have a TcpServer
                // connected to the same address as specified by the server, port
                // combination
                Int32 port = 14000;
                TcpClient client = new TcpClient(server, port);

                // Get a client stream for reading and writing
                // Stream stream = client.GetStream() : System.IO needs..
                NetworkStream stream = client.GetStream();

                // Translate the passed message into UTF8 and store it as Byte array.
                byte[] data = Encoding.UTF8.GetBytes(message);

                // Send the message to the connected TcpServer
                stream.Write(data, 0, data.Length);

                Console.WriteLine("Sent: {0}", message);

                // Receive the TcpServer response

                // Buffer to store the response bytes.
                data = new byte[256];

                // string to store the response ASCII representation.
                string responseData = string.Empty;

                Int32 bytesRead = stream.Read(data, 0, data.Length);
                responseData = Encoding.UTF8.GetString(data, 0, bytesRead);
                Console.WriteLine("Received: {0}", responseData);

                // Close everything
                stream.Close();
                client.Close();
            }
            catch(ArgumentNullException e)
            {
                Console.WriteLine("ArgumentNullException: {0}", e.Message.ToString());
            }
            catch(SocketException e)
            {
                Console.WriteLine("SocketException: {0}", e.Message.ToString());
            }
        }



posted by 따시쿵
2015. 1. 6. 15:43 C# with TCP/IP

프로그램 설명


다중 접속과 데이타 전송 및 클라이언트에서 소켓 해제시 서버에서 인지를 하고 접속한 클라이언트 소켓을 해제하는 예제입니다.


구조는 서버에서 listen socket 을 생성하고, 각각의 클라이언트 접속시 client class 를 만들어서 리스트뷰에서 현재 상태의 소켓 상태와 메시지를 보여 주는 구조입니다. 


서버 구현시 사용한 listen class, client class 파일 올립니다.

Client.cs  Listener.cs

클라이언트에서는 소켓을 해제하는 단계를 거칩니다.



실행 후



메시지 전송 후



클라이언트 접속 해제 후



프로그램 설명


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

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


2. 서버 프로그램


        Listener listener;

        public Main()
        {
            InitializeComponent();

            int port = Convert.ToInt32(Properties.Settings.Default.Port);
            listener = new Listener(port);
            listener.SocketAccepted += new Listener.SocketAcceptedHandler(listener_SocketAccepted);
            Load += new EventHandler(Main_Load);
        }

        void Main_Load(object sender, EventArgs e)
        {
            string tcpServerIP = Properties.Settings.Default.ServerIP;
            listener.Start(tcpServerIP);
        }

        void listener_SocketAccepted(System.Net.Sockets.Socket e)
        {
            Client client = new Client(e);
            client.Received += new Client.ClientReceivedHandler(client_Received);
            client.Disconnected += new Client.ClientDisconnectedHandler(client_Disconnected);

            Invoke((MethodInvoker)delegate
            {
                ListViewItem i = new ListViewItem();
                i.Text = client.EndPoint.ToString();
                i.SubItems.Add(client.ID);
                i.SubItems.Add("XX");
                i.SubItems.Add("YY");
                i.Tag = client;
                lstClient.Items.Add(i);
            });
        }

        void client_Disconnected(Client sender)
        {
            Invoke((MethodInvoker)delegate
            {                
                for (int i = 0; i < lstClient.Items.Count; i++)
                {
                    Client client = lstClient.Items[i].Tag as Client;

                    if (client.ID == sender.ID)
                    {
                        lstClient.Items.RemoveAt(i);
                        break;
                    }
                }
            });
        }

        void client_Received(Client sender, byte[] data)
        {
            Invoke((MethodInvoker)delegate
            {
                for (int i = 0; i < lstClient.Items.Count; i++)
                {
                    Client client = lstClient.Items[i].Tag as Client;

                    if (client.ID == sender.ID)
                    {
                        lstClient.Items[i].SubItems[2].Text = Encoding.UTF8.GetString(data);
                        lstClient.Items[i].SubItems[3].Text = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
                        break;
                    }
                }
            });
        }


3. 클라이언트 프로그램


        Socket sck;
        public Main()
        {
            InitializeComponent();
            sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            string ServerIP = Properties.Settings.Default.ServerIP;
            string Port = Properties.Settings.Default.Port;

            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ServerIP), Convert.ToInt32(Port));
            sck.Connect(remoteEP);
            lblInfo.Text = "Connected";
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            int s = sck.Send(Encoding.UTF8.GetBytes(textBox1.Text));
            if (s > 0)
            {
                lblInfo.Text = string.Format("{0} bytes data sent", s.ToString());
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            lblInfo.Text = "Not Connected....";
            sck.Close();
            sck.Dispose();
            Close();
        }


posted by 따시쿵
2015. 1. 3. 09:34 C# with TCP/IP

프로그램 설명


이번 프로그램에서는 클라이언트가 다중으로 접속하는 것을 다루되도록 하겠습니다.


클라이언트는 서버에 접속을 하고 접속을 끊어 버리는 단순한 작업을 합니다. 서버는 연결이 들어오는 것을 어떻게 저장하고 관리하는지를 보여 줍니다.


서버 프로그램에서 사용하는 Listener class 파일을 첨부 파일과 환경 파일에 아이피와 포트를 저장하고 사용합니다. 두가지 모두 올립니다.


Listener.cs   Settings.cs


실행 후



연결 요청 후


프로그램 작성 순서


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

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


2. 서버 프로그램


        static Listener l;
        static List<socket> sockets;

        static void Main(string[] args)
        {
            System.Diagnostics.Debug.WriteLine("{0} : {1}", Properties.Settings.Default.ServerIP, Properties.Settings.Default.Port);
            string serverIP = Properties.Settings.Default.ServerIP;
            string port = Properties.Settings.Default.Port;

            l = new Listener(Convert.ToInt32(port));
            sockets = new List<socket>();

            l.SocketAccepted += new Listener.SocketAcceptedHandler(l_SocketAccepted);
            l.Start(serverIP);

            Console.ReadLine();
        }

        static void l_SocketAccepted(System.Net.Sockets.Socket e)
        {
            Console.WriteLine("New Connection: {0}\n{1}\n=========================", 
                                e.RemoteEndPoint.ToString(), DateTime.Now.ToString());

            if (e != null)
                sockets.Add(e);

            int index = 1;
            Console.WriteLine("Connected socket list\n=========================");
            foreach(Socket s in sockets)
            {
                Console.WriteLine("{0} : {1} : socket handle {2}", index, s.RemoteEndPoint.ToString(), s.Handle.ToString());
                index++;
            }

            Console.WriteLine("");
        }


3. 클라이언트 프로그램


            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            string serverIP = Properties.Settings.Default.ServerIP;
            string port = Properties.Settings.Default.Port;

            s.Connect(IPAddress.Parse(serverIP), Convert.ToInt32(port));
            s.Close();
            s.Dispose();



posted by 따시쿵
2015. 1. 2. 16:39 C# with TCP/IP

프로그램 설명


msdn 사이트에 있는 예제를 조금 수정해서 작성했습니다.

원본 소스는 아래와 같습니다.


비동기 서버 예제 : http://msdn.microsoft.com/ko-kr/library/bew39x2a(v=vs.110).aspx

비동기 클라이언트 예제 : http://msdn.microsoft.com/ko-kr/library/fx6588te(v=vs.110).aspx


윈도우 버전으로 변경하는 중에 서버 소스는 변경할 부분이 별로 없지만 클라이언트 소스는 문제가 여러가지 발생하여 기본 골격을 변경했습니다.


클라이언트 소스에 나오는 부분을 client class 를 만들어 따로 저장 했으며, 화면 부분은 delegate 를 이용해서 진행 상황의 데이타를 보여 주는 구조를 가지고 있습니다. 


client.cs 는 첨부 파일로 올려 놓습니다.

 

Client.cs



실행 후



메시지 전송 후




프로그램 작성 순서


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

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


2. 서버 프로그램

    public partial class MainForm : Form
    {
       // Thread signal.
        public static ManualResetEvent allDone = new ManualResetEvent(false);
        // Golobal Sockeet define for listener 
        public Socket g_listener = null;

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

        public void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (g_listener != null)
            {
                g_listener.Close();
                g_listener.Dispose();
            }

            Application.Exit();
        }

        private void btnListen_Click(object sender, EventArgs e)
        {
            // button disabled.
            btnListen.Enabled = false;

            // Data buffer for incoming data
            byte[] bytes = new byte[10240];

            // Establish the local endpoint for the socket
            // The ip address of the computer
            // running the listener is "192.168.0.12" 예제로...
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(LocalIPAddress()), 11000);

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

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

                new Thread(delegate()
                    {
                        while (true)
                        {
                            // Set the event to nonsignaled state
                            allDone.Reset();

                            // Start an asynchronous socket to listen for connections.
                            Invoke((MethodInvoker)delegate
                            {
                                listBox1.Items.Add("Waiting for a connection...");
                            });
                            g_listener.BeginAccept(new AsyncCallback(AcceptCallback), g_listener);

                            // Waiting until a connection is made before continuing.
                            allDone.WaitOne();
                        }
                    }).Start();
            }
            catch (SocketException se)
            {
                MessageBox.Show(string.Format("StartListening [SocketException] Error : {0} ", se.Message.ToString()));
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("StartListening [Exception] Error : {0} ", ex.Message.ToString()));
            }
        }

        public void AcceptCallback(IAsyncResult ar)
        {
            // Signal the main thread to continue
            allDone.Set();

            // Get the socket that handles the client request.
            Socket listener = ar.AsyncState as Socket;
            Socket handler = listener.EndAccept(ar);

            // Create the state object
            StateObject state = new StateObject();
            state.workSocket = handler;
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None, new AsyncCallback(ReadCallback), state);
        }

        public void ReadCallback(IAsyncResult ar)
        {
            string content = string.Empty;

            // Retrieve the state object and the handler socjet
            // from the asynchronous state object
            StateObject state = ar.AsyncState as StateObject;
            Socket handler = state.workSocket;

            // Read data from the client socket
            int bytesRead = handler.EndReceive(ar);

            if (bytesRead > 0)
            {
                // There might be more data, so store the data received so far
                state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead));

                // Check for end-of-flag tag. If it is no 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.
                    Invoke((MethodInvoker)delegate
                    {
                        content = TruncateLeft(content, content.Length - 5);
                        listBox1.Items.Add(string.Format("Read {0} bytes from socket. 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, SocketFlags.None, new AsyncCallback(ReadCallback), state);
                }
            }
        }

        public void Send(Socket handler, string data)
        {
            // Convert the string data byte data using UTF8 encoding.
            byte[] byteData = Encoding.UTF8.GetBytes(data);

            // Begin sending the data to the remote device.
            handler.BeginSend(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(SendCallback), handler);
        }

        public void SendCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object
                Socket handler = ar.AsyncState as Socket;

                // Complete sending the data to remote device
                int bytesSent = handler.EndSend(ar);
                Invoke((MethodInvoker)delegate
                {
                    listBox1.Items.Add(string.Format("Sent {0} bytes to client", bytesSent));
                    listBox1.Items.Add("");
                });
                
                handler.Shutdown(SocketShutdown.Both);
                handler.Close();
            }
            catch (SocketException se)
            {
                MessageBox.Show(string.Format("SendCallback [SocketException] Error : {0} ", se.Message.ToString()));
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("SendCallback [Exception] Error : {0} ", ex.Message.ToString()));
            }
        }

        public 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 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 btnDataClear_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
        }
    }

    // State object for reading client data asynchronously
    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();
    }


3. 클라이언트 프로그램

        private Client client;
        public MainForm()
        {
            InitializeComponent();
            FormClosing += new FormClosingEventHandler(MainForm_FormClosing);
        }

        private void client_OnDisconnect(Client sender)
        {
            UpdateUIListBoxInfo("Disconnected");
        }

        private void client_OnReceive(string receiveData)
        {
            string content = string.Format("receiveData : {0}", receiveData);
            UpdateUIListBoxInfo(content);
            UpdateUIListBoxInfo("");
        }

        private void client_OnSend(Client sender, int bytesSent)
        {
            string content = string.Format("Sent {0} bytes to server.", bytesSent);
            UpdateUIListBoxInfo(content);    
        }

        private void client_OnConnect(Client sender, bool connected)
        {
            if (connected)
            {
                UpdateUIListBoxInfo("Connection Accepted.....");
            }
        }
        
        public void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (client.Connected)
                client.Close();

            Application.Exit();
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            client = new Client(txtServerIP.Text);
            client.OnConnect += new Client.OnConnectEventHandler(client_OnConnect);
            client.OnSend += new Client.OnSendEventHandler(client_OnSend);
            client.OnReceive += new Client.OnReceiveEventHandler(client_OnReceive);
            client.OnDisconnect += new Client.OnDisconnectEventHandler(client_OnDisconnect);

            string sendData = txtContent.Text;
            client.StartClient(sendData);
        }

        private void UpdateUIListBoxInfo(string content)
        {
            if (listBox1.InvokeRequired)
            {
                listBox1.BeginInvoke(new MethodInvoker(delegate
                {
                    listBox1.Items.Add(content);
                }));
            }
            else
                listBox1.Items.Add(content);
        }


posted by 따시쿵
2014. 12. 26. 16:47 C# with TCP/IP

프로그램 설명


msdn 사이트에 있는 예제를 조금 수정해서 작성했습니다.

원본 소스는 아래와 같습니다.


비동기 서버 예제 : http://msdn.microsoft.com/ko-kr/library/bew39x2a(v=vs.110).aspx

비동기 클라이언트 예제 : http://msdn.microsoft.com/ko-kr/library/fx6588te(v=vs.110).aspx


비동기로 소켓을 실행하기 위해 ManualResetEvent 클래스를 사용해서 thread 간 통신을 하며, StateObject class 를 만들어서 받을 데이타를 정의하는 부분이 추가 되었으며, 비동기 호출 method 들(beginAccept, beginReceive, beginSend)을 호출합니다.  


다른 부분들은 동기 서버/클라이언트의 추가 함수들을 같이 사용했습니다.(문자열 자르기, 로컬 아이피 가져오기)


초기에 실행하면 다른점이 보이는데 이 부분이 실제로 비동기 호출을 담당하는 부분이며 소켓을 통해서 데이타를 주고 받는 부분이 비동기로 구현되어 있습니다.


실행 후



메시지 전송 후



프로그램 작성 순서


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

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


2. 서버 프로그램


    // State object for reading client data asynchronously
    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();
    }

    class Program
    {
        // Thread signal
        public static ManualResetEvent allDone = new ManualResetEvent(false);

        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 static void StartListening()
        {
            // Data buffer for incoming data
            byte[] bytes = new byte[1024];

            // Establish the local endpoint for the socket
            // running the listener is "192.168.0.12" 테스트 아이치
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(LocalIPAddress()), 11000);


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

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

                while(true)
                {
                    // Set the event to nonsignaled state
                    allDone.Reset();

                    // Start an asynchronous socket to listen for connections.
                    Console.WriteLine("\nWaiting for a connections...");
                    listener.BeginAccept(new AsyncCallback(AcceptCallback) , listener);

                    // Wait until a connection is made before running
                    allDone.WaitOne();

                }
            }
            catch (SocketException se)
            {
                Console.WriteLine("StartListening[SocketException] Error : {0} ", se.Message.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine("StartListening[Exception] Error : {0} ", ex.Message.ToString());
            }

            Console.WriteLine("\nPress ENTER to continue.....\n");
            Console.ReadLine();
        }

        public static void AcceptCallback(IAsyncResult ar)
        {
            // Signal the main thread to continue.
            allDone.Set();

            // Get the socket that handles the client socket
            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);

            // Create the socket object
            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;

            // Retrieve the state object and the handler socket
            // from the asynchronous state object
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;

            // Read data from the client socket
            int bytesRead = handler.EndReceive(ar);

            if (bytesRead > 0)
            {
                // There might be more data, so store the data received so far
                state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead));

                // Check for end-of-file tag. If it it 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.
                    content = TruncateLeft(content, content.Length - 5);
                    Console.WriteLine("Read {0} bytes from socket \nData : {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)
        {
            // Convert the string data to bytes data using UTF8 encoding
            byte[] byteData = Encoding.UTF8.GetBytes(data);

            // Being sending the data to the remote device
            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 = ar.AsyncState as Socket;

                // 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 (SocketException se)
            {
                Console.WriteLine("SendCallback[SocketException] Error : {0} ", se.Message.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine("SendCallback[Exception] Error : {0} ", ex.Message.ToString());
            }
        }

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


3. 클라이언트 프로그램

    #region State object define
    // State object for receiving data from reomte device
    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();
    }
    #endregion

    class Program
    {
        // The port number for the remote device
        private const int port = 11000;

        // ManaulResetEvent instances signal completion
        private static ManualResetEvent connectDone = new ManualResetEvent(false);
        private static ManualResetEvent sendDone = new ManualResetEvent(false);
        private static ManualResetEvent receiveDone = new ManualResetEvent(false);

        // The response from the remote device
        private static String response = String.Empty;

        private static void StartClient()
        {
            // Connect to a remote device
            try
            {
                // Establish the remote endpoint for the socket
                // The name of
                // remote device 아이피 "192.168.0.12" : 테스트 목적
                IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("192.168.0.12"), 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 user input data to the remote device
                Console.Write("전송할 메시지를 입력해 주세요 : ");
                string sendData = Console.ReadLine() + "<eof>";
                Send(client, sendData);
                sendDone.WaitOne();

                // Receive the response from the remote device.
                Receive(client);
                receiveDone.WaitOne();

                // Write the response to the console
                Console.WriteLine("Response received : {0}", response);

                // Release the socket
                client.Shutdown(SocketShutdown.Both);
                client.Close();
            }
            catch (SocketException se)
            {
                Console.WriteLine("StartClient SocketException Error : {0} ", se.Message.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine("StartClient Exception Error : {0} ", ex.Message.ToString());
            }
        }

        private static void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object
                Socket client = (Socket)ar.AsyncState;

                // Complete the connection
                client.EndConnect(ar);

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

                // Signal that the connection has been made
                connectDone.Set();
            }
            catch (SocketException se)
            {
                Console.WriteLine("ConnectCallback SocketException Error : {0} ", se.Message.ToString());
            }
            catch(Exception ex)
            {
                Console.WriteLine("ConnectCallback Exception Error : {0} ", ex.Message.ToString());
            }
        }

        private static void Receive(Socket client)
        {
            try
            {
                // Create the state object
                StateObject state = new StateObject();
                state.workSocket = client;

                // Begin receiving the data from the remote device
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
            }
            catch (SocketException se)
            {
                Console.WriteLine("Receive SocketException Error : {0} ", se.Message.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine("Receive Exception Error : {0} ", ex.Message.ToString());
            }
        }

        private static void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the state object and the client socket
                // from the asynchronous state object
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;

                // Read data from the remote device
                int bytesRead = client.EndReceive(ar);

                if (bytesRead > 0)
                {
                    // There might be more data, so store the data received so far
                    state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead));

                    // Get the rest of the data
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
                }
                else
                {
                    // All the data has arrived; put it in response
                    if (state.sb.Length > 1)
                        response = state.sb.ToString();

                    // Signal that all bytes have been received.
                    receiveDone.Set();
                }

            }
            catch (SocketException se)
            {
                Console.WriteLine("ReceiveCallback SocketException Error : {0} ", se.Message.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine("ReceiveCallback Exception Error : {0} ", ex.Message.ToString());
            }
        }

        private static void Send(Socket client, string data)
        {
            // Convert the string data to byte data using UTF8 encoding
            byte[] byteData = Encoding.UTF8.GetBytes(data);

            // Being sending the data to the remote device
            client.BeginSend(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(SendCallback), client);
        }

        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object
                Socket client = ar.AsyncState as Socket;

                // Complete sending the data to the remote device
                int bytesSent = client.EndSend(ar);
                Console.WriteLine("Sent {0} bytes to server", bytesSent);

                // Signal that all bytes have been sent
                sendDone.Set();
            }
            catch (SocketException se)
            {
                Console.WriteLine("SendCallback SocketException Error : {0} ", se.Message.ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine("SendCallback Exception Error : {0} ", ex.Message.ToString());
            }
        }
        static void Main(string[] args)
        {
            StartClient();
            Console.ReadLine();
        }
    }


posted by 따시쿵
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 따시쿵
prev 1 2 3 4 5 6 next