블로그 이미지
따시쿵

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

2015. 5. 25. 15:13 C# with TCP/IP

프로그램 설명


패킷을 이용한 데이타 전송 예제입니다. 로그인과 회원가입을 예로 들어 설명 합니다.

전송할 데이타를 바로 네트워크 스트림에 쓰지 않고 전송 패킷에 저장을 한 후, 일괄 전송하는 방법입니다.


1. 3개의 프로젝트를 먼저 만듭니다.


  MyLogin_Packet : 클래스 라이브러리 타입, dll class 파일, 패킷 정의용

  MyLoginClient1_WindowsForm : 윈도우즈 폼 타입. 클라이언트 폼. exe 파일

  MyLoginServer1_WindowsForm : 윈도우즈 폼 타입. 서버 폼. exe 파일



2. MyLogin_Packet : 클래스 라이브러리 타입, dll class 파일, 패킷 정의용

   

   기본 패킷 정의

namespace MyLogin_Packet
{
    public enum PacketType :int
    {
        Login = 0,
        Login_RESULT,
        Member_REGISTER,
        Member_REGISTER_RESULT
    }

    [Serializable]
    public class Packet
    {
        public int packet_Type;
        public int packet_Length;
        
        public Packet()
        {
            this.packet_Type = 0;
            this.packet_Length = 0;
        }

        public static byte[] Serialize(Object data)
        {
            try
            {
                MemoryStream ms = new MemoryStream(1024 * 4); // packet size will be maximum 4k
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(ms, data);
                return ms.ToArray();
            }
            catch
            {
                return null;
            }
        }

        public static Object Deserialize(byte[] data)
        {
            try
            {
                MemoryStream ms = new MemoryStream(1024 * 4);
                ms.Write(data, 0, data.Length);

                ms.Position = 0;
                BinaryFormatter bf = new BinaryFormatter();
                Object obj = bf.Deserialize(ms);
                ms.Close();
                return obj;
            }
            catch
            {
                return null;
            }
        }
    }
}

   

   파생된 패킷 정의(로그인, 회원가입)

namespace MyLogin_Packet
{
    [Serializable]
    public class Login : Packet
    {
        public string id_str { get; set; }
        public string pw_str { get; set; }

    }
}

namespace MyLogin_Packet
{
    [Serializable]
    public class MemberRegister : Packet
    {
        public string id_str { get; set; }
        public string pw_str { get; set; }
        public string nickname_str { get; set; }
    }
}

   


3. MyLoginClient1_WindowsForm : 윈도우즈 폼 타입. 클라이언트 폼. exe 파일

   

  로그인 버튼 클릭시 전송할 데이타 Login Packet class 로 Serialize 시킴. 받은 데이타는 LoginResult Packet class 로 Deserialize 시킴.

   

        private void btnSend_Click(object sender, EventArgs e)
        {
            try
            {
                byte[] buffer = new byte[1024 * 4];

                // 1. connect to server
                TcpClient client = new TcpClient("192.168.0.11", 7778);
                NetworkStream stream = client.GetStream();

                // 2. send the packet
                Login login = new Login();
                login.packet_Type = (int)PacketType.Login;
                login.id_str = textBox1.Text.Trim();
                login.pw_str = textBox2.Text.Trim();

                Packet.Serialize(login).CopyTo(buffer, 0);

                stream.Write(buffer, 0, buffer.Length);

                // 3. receive the packet
                Array.Clear(buffer, 0, buffer.Length);

                int bytesRead = stream.Read(buffer, 0, buffer.Length);
                LoginResult loginResult = (LoginResult)Packet.Deserialize(buffer);

                if (loginResult.result)
                {
                    MessageBox.Show(loginResult.reason, "클라이언트 확인", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                {
                    MessageBox.Show(loginResult.reason, "클라이언트 오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                // 4. close the socket
                stream.Close();
                client.Close();
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message, "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }


4. MyLoginServer1_WindowsForm : 윈도우즈 폼 타입. 서버 폼. exe 파일

  

   stream 으로 데이타를 받은 후, PacketType class 로 deserialize 시킴으로, 받은 패킷이 어떤 기능을 하는 패킷인지 구분하는 로직

  

            Packet packet = (Packet)Packet.Deserialize(buffer);

            if (packet == null)
                return;

            switch ((int)packet.packet_Type)
            {
                case (int)PacketType.Login:
                    {
                              // 로그인 로직 추가
                    }
                    break;
                case (int)PacketType.Member_REGISTER:
                    {
                              // 회원가입 로직 추가
                    }
                    break;
            }

   

   Login packet class 로 deserialize 시킴

  

                        // 받은 패킷을 Login class 로 deserialize 시킴
                        Login login = (Login)Packet.Deserialize(buffer);

                        setLog(string.Format("ID : {0}, PWD : {1}", login.id_str, login.pw_str)); // 화면에 display 시킴

   

   Loginresult packet class 로 serialize 시켜서 클라이언트에게 전송함

  

                        // 전송할 패킷을 LoginResult class 로 serialize 시킴
                        LoginResult loginResult = new LoginResult();
                        loginResult.packet_Type = (int)PacketType.Login_RESULT;
                        if (random.Next(1, 100) % 2 == 0)    // 짝수라면.... 로그인 성공 
                        {
                            loginResult.result = true;
                            loginResult.reason = "정상적으로 로그인이 되었습니다.";
                        }
                        else                                // 홀수라면.... 로그인 실패
                        {
                            loginResult.result = false;
                            loginResult.reason = "아이디와 비밀번호를 확인 하시기 바랍니다.";
                        }

                        Array.Clear(buffer, 0, buffer.Length);
                        Packet.Serialize(loginResult).CopyTo(buffer, 0);
                        stream.Write(buffer, 0, buffer.Length);


실행 화면


소스 파일 :


MyLogin_Packet.zip

MyLoginClient1_WindowsForm.zip  MyLoginServer1_WindowsForm.zip

posted by 따시쿵
2015. 5. 20. 11:50 C# with TCP/IP

프로그램 설명


서버에서 연결되어 있는 클라이언트의 유효성을 체크하는 예제입니다.


1. 윈도우폼의 [도구상자]에서 [Timer] 클래스를 끌어다 폼에 추가 


2. 윈도우폼에 체크 박스를 두어서 체크시 클라이언트 connection 체크를 주기적으로 실행.


   메시지 전송시 헤드만 전송하고 바디 전송은 하지 않습니다. 왜냐하면 유효한지만 

   체크하는 것이므로 연결이 정상적인지, 비정상적인지만 체크하면 됩니다.


   client.SendMessage(BitConverter.GetBytes((int)0));


        #region checkBox1_CheckedChanged
        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
            {
                //
                timer1.Tick += new EventHandler(TimerEventProcessor);

                // Sets the timer interval to 10 seconds.
                timer1.Interval = 10000;
                timer1.Start();
            }
            else
                timer1.Stop();
        }
        #endregion

        #region TimerEventProcessor
        // This is the method to run when the timer is raised.
        private void TimerEventProcessor(Object myObject, EventArgs myEventArgs)
        {
            Trace.WriteLine("Event raise the TimerEventProcessor");

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

                    if (client.sck.Connected)
                        client.SendMessage(BitConverter.GetBytes((int)0));  
                    else
                    {
                        this.client_Disconnected(client);
                        DisconnectedClientList(client.sck);
                    }
                }
            });
        }
        #endregion




실행 후


소스 파일 : 

 MyKeepAliveClient1_WindowsForm.zip MyKeepAliveServer1_WindowsForm.zip


posted by 따시쿵
2015. 3. 26. 13:45 C# with TCP/IP

프로그램 설명


바이트 배열을 이용한 파일 전송을 구현한 예시입니다.

이미지 파일 전송시 데이타 구조와 일반 텍스트 데이타 구조가 다르므로 아래에 그림으로 표시했습니다.

실행 후




이미지 파일 전송 후



메시지 전송 후




프로그램 작성


1. 데이타 버퍼 클래스 (StateObject.cs)


    class StateObject
    {
        // Client socket
        public Socket workSocket = null;

        public const int BufferSize = 4096;

        // Receive buffer
        public byte[] buffer = new byte[BufferSize];
    }


2. 서버 프로그램


    public partial class MainForm : Form
    {
        bool initialFlag = true;
        string receivedPath = string.Empty;
        enum DataPacketType { TEXT = 1, IMAGE };
        int dataType = 0;
        string textData = string.Empty;

        public MainForm()
        {
            InitializeComponent();

            Thread t_handler = new Thread(StartListening);
            t_handler.IsBackground = true;
            t_handler.Start();
        }

        public static ManualResetEvent allDone = new ManualResetEvent(false);
        private void StartListening()
        {
            IPEndPoint localEP = new IPEndPoint(IPAddress.Any, 9050);
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                listener.Bind(localEP);
                listener.Listen(10);

                while(true)
                {
                    allDone.Reset();
                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                    allDone.WaitOne();
                }
            }
            catch(SocketException se)
            {
                Trace.WriteLine(string.Format("SocketException :{0}", se.Message));
            }
            catch(Exception ex)
            {
                Trace.WriteLine(string.Format("Exception :{0}", ex.Message));
            }
        }

        private void AcceptCallback(IAsyncResult ar)
        {
            allDone.Set();

            Socket listener = ar.AsyncState as Socket;
            Socket handler = listener.EndAccept(ar);

            StateObject state = new StateObject();
            state.workSocket = handler;
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
            initialFlag = true;
        }

        private void ReadCallback(IAsyncResult ar)
        {
            int fileNameLen = 0;
            string content = string.Empty;
            StateObject state = ar.AsyncState as StateObject;
            Socket handler = state.workSocket;
            int bytesRead = handler.EndReceive(ar);
            
            if(bytesRead > 0)
            {                
                if (initialFlag)
                {
                    dataType = BitConverter.ToInt32(state.buffer, 0);
                    if (dataType == (int)DataPacketType.IMAGE)
                    { 
                        fileNameLen = BitConverter.ToInt32(state.buffer, 4);
                        string fileName = Encoding.UTF8.GetString(state.buffer, 8, fileNameLen);

                        string pathUser = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
                        string pathDownload = Path.Combine(pathUser, "Downloads");

                        receivedPath = Path.Combine(pathDownload, fileName);

                        if (File.Exists(receivedPath))
                            File.Delete(receivedPath);
                    }
                    else if (dataType == (int)DataPacketType.TEXT)
                    {
                        textData = Encoding.UTF8.GetString(state.buffer, 4, bytesRead - 4);
                        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
                    }
                }

                if (dataType == (int)DataPacketType.IMAGE)
                {
                    BinaryWriter bw = new BinaryWriter(File.Open(receivedPath, FileMode.Append));
                    if (initialFlag)
                        bw.Write(state.buffer, 8 + fileNameLen, bytesRead - (8 + fileNameLen));
                    else
                        bw.Write(state.buffer, 0, bytesRead);

                    initialFlag = false;
                    bw.Close();
                    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
                }
            }
            else
            {
                if (dataType == (int)DataPacketType.IMAGE)
                {
                    pictureBox1.ImageLocation = receivedPath;
                    Invoke((MethodInvoker)delegate
                    {
                        lblMessage.Text = "Data has been received";
                    });
                }
                else if (dataType == (int)DataPacketType.TEXT)
                    Invoke((MethodInvoker)delegate
                    {
                        textBox1.AppendText(textData + Environment.NewLine);
                    });
            }
        }
    }


3. 클라이언트 프로그램


    public partial class MainForm : Form
    {
        string m_splitter = "'\\'";
        string m_fName = string.Empty;
        string[] m_split = null;
        byte[] m_clientData = null;
        enum DataPacketType { TEXT = 1, IMAGE };

        public MainForm()
        {
            InitializeComponent();
            
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            char[] delimeter = m_splitter.ToCharArray();

            openFileDialog1.Filter = "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png";
            openFileDialog1.ShowDialog();

            textBox1.Text = openFileDialog1.FileName;
            pictureBox1.ImageLocation = openFileDialog1.FileName;

            m_split = textBox1.Text.Split(delimeter);
            int limit = m_split.Length;

            m_fName = m_split[limit - 1].ToString();

            if (textBox1.Text != null)
                btnSend.Enabled = true;
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            Thread t_handler = new Thread(SendData);
            t_handler.IsBackground = true;
            t_handler.Start();
        }

        private void SendData()
        {
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            byte[] fileName = Encoding.UTF8.GetBytes(m_fName);
            byte[] fileData = File.ReadAllBytes(textBox1.Text);
            byte[] fileNameLen = BitConverter.GetBytes(fileName.Length);
            byte[] fileType = BitConverter.GetBytes((int)DataPacketType.IMAGE);
            // IMAGE(4 byte) + 파일이름(4 byte) + 파일이름길이(4 byte) + 데이타 길이
            m_clientData = new byte[fileType.Length + 4 + fileName.Length + fileData.Length];

            fileType.CopyTo(m_clientData, 0);
            fileNameLen.CopyTo(m_clientData, 4);
            fileName.CopyTo(m_clientData, 8);
            fileData.CopyTo(m_clientData, 8 + fileName.Length);
            
            clientSocket.Connect(IPAddress.Parse("192.168.0.11"), 9050);
            clientSocket.Send(m_clientData);
            clientSocket.Close();
        }

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

            byte[] textData = Encoding.UTF8.GetBytes(textBox2.Text);
            byte[] fileType = BitConverter.GetBytes((int)DataPacketType.TEXT);
            // TEXT(4 byte) + 데이타 길이
            m_clientData = new byte[fileType.Length + textData.Length];

            fileType.CopyTo(m_clientData, 0);
            textData.CopyTo(m_clientData, 4);

            clientSocket.Connect(IPAddress.Parse("192.168.0.11"), 9050);
            clientSocket.Send(m_clientData);
            clientSocket.Close();
        }
    }

posted by 따시쿵
2015. 3. 20. 18:00 C# with TCP/IP

프로그램 설명


SslStream 클래스를 이용한 통신 방법으로 구현 되었습니다.


보안이 없는 일반 tcp 서버/클라이언트와 비교해서 다른 점은 데이타를 주고 받기 전에 반드시 SSL 핸드세이크의 단계를 거친다는 점입니다.


아래는 msdn 에서 발취한 내용입니다.

https://msdn.microsoft.com/ko-kr/library/system.net.security.sslstream(v=vs.110).aspx

SSL 핸드셰이크라고도 하는 인증 프로세스가 성공하면 서버와 클라이언트(선택적)의 ID가 설정되고 클라이언트와 서버는 SslStream을 사용하여 메시지를 주고받을 수 있습니다. 정보를 보내거나 받기 전에 클라이언트와 서버에서는 SslStream에 제공되는 보안 서비스 및 수준을 확인하여, 선택한 프로토콜, 알고리즘 및 강도가 무결성 및 기밀성 요구 사항을 충족하는지 확인해야 합니다.


작업을 하기 전에 인증서를 만드는 방법을 알고 개발에 사용할 인증서를 만들어야 합니다.


1.

Makecert.exe (Certificate Creation Tool) 사이트에서 다음의 예제와 같이 도스 창에서 명령어를 실행해서 작성합니다.


makecert -r -pe -n "CN=XYZ Company" -b 01/01/2005 -e 01/01/2010 -sky exchange -ss my


makecert 파일은 Windows 8.1 을 기준으로 아래의 경로에 있습니다.


 


2.

Visual Studio 를 이용해서 인증서를 테스트 할 수 있는 환경, 즉 사용할 수 있는 인증서로 만듭니다.








여기에 보여지는 소스는 msdn 사이트에 나오는 소스이며 원본 사이트는 아래와 같습니다.

https://msdn.microsoft.com/ko-kr/library/system.net.security.sslstream(v=vs.110).aspx



실행 후




메시지 전송 후




프로그램 작성 방법


1. 서버 프로그램


using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Diagnostics;

    public sealed class SslTcpServer
    {
        static X509Certificate serverCertificate = null;

        public static void RunServer(string certificate, string password)
        {
            try
            {
                serverCertificate = new X509Certificate(certificate, password);
                
                TcpListener listener = new TcpListener(IPAddress.Any, 8080);
                listener.Start();

                while(true)
                {
                    Console.WriteLine("Waiting for a client to connect...");
                    Console.WriteLine();

                    TcpClient client = listener.AcceptTcpClient();
                    ProcessClient(client);
                }
            }
            catch(Exception ex)
            {
                Trace.WriteLine(string.Format("Error : {0}", ex.Message));
            }
        }

        static void ProcessClient(TcpClient client)
        {
            SslStream sslStream = new SslStream(client.GetStream(), false);

            try
            {
                sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls, true);
                
                // Set timeouts for the read and write to 5 seconds.
                //sslStream.ReadTimeout = 5000;
                //sslStream.WriteTimeout = 5000;

                // Read a message from the client.
                Console.WriteLine("Waiting for client message...");
                string messageData = ReadMessage(sslStream);
                Console.WriteLine("Received : {0}", messageData.Substring(0, messageData.IndexOf("$")));

                // Write a message to the client
                messageData = "[reply] " + messageData;
                byte[] message = Encoding.UTF8.GetBytes(messageData);
                sslStream.Write(message);
                Console.WriteLine("Sending hello message");
                Console.WriteLine();
            }
            catch (AuthenticationException e)
            {
                Console.WriteLine("Exception: {0}", e.Message);
                if (e.InnerException != null)
                {
                    Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                }
                Console.WriteLine("Authentication failed - closing the connection.");
                sslStream.Close();
                client.Close();
                return;
            }
            finally
            {
                // The client stream will be closed with the sslStream
                // because we specified this behavior when creating
                // the sslStream.
                sslStream.Close();
                client.Close();
            }
        }

        static string ReadMessage(SslStream sslStream)
        {
            // Read the  message sent by the client.
            // The client signals the end of the message using the
            // "$" marker.
            byte[] buffer = new byte[2048];
            StringBuilder messageData = new StringBuilder();
            int bytes = -1;
            do
            {
                // Read the client's test message.
                bytes = sslStream.Read(buffer, 0, buffer.Length);

                // Use Decoder class to convert from bytes to UTF8
                // in case a character spans two buffers.
                Decoder decoder = Encoding.UTF8.GetDecoder();
                char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
                decoder.GetChars(buffer, 0, bytes, chars, 0);
                messageData.Append(chars);
                // Check for EOF or an empty message.
                if (messageData.ToString().IndexOf("$") != -1)
                {
                    break;
                }
            } while (bytes != 0);

            return messageData.ToString();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            SslTcpServer.RunServer("XYZ_Company_ver2.pfx", "agrafood01");

            Console.WriteLine("Press the any key to continue...");
            Console.ReadLine();
        }
    }


2. 클라이언트 프로그램


using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Diagnostics;
using System.Collections;

    public class SslTcpClient
    {
        private static Hashtable certtificateError = new Hashtable();

        // The following method is invoked by the RemoteCertificateValidationDelegate.
        public static bool ValidateServerCertificate(
              object sender,
              X509Certificate certificate,
              X509Chain chain,
              SslPolicyErrors sslPolicyErrors)
        {
            if (sslPolicyErrors == SslPolicyErrors.None)
                return true;

            Console.WriteLine("Certificate error: {0}", sslPolicyErrors);

            // Do not allow this client to communicate with unauthenticated servers.
            return false;
        }

        public static void RunClient(string machineName, string serverName, string inputMessage)
        {
            // Create a TCP/IP client socket.
            // machineName is the host running the server application.
            TcpClient client = new TcpClient(machineName, 8080);
            Console.WriteLine("Client connected.");
            // Create an SSL stream that will close the client's stream.
            SslStream sslStream = new SslStream(
                client.GetStream(),
                false,
                new RemoteCertificateValidationCallback(ValidateServerCertificate),
                null
                );
            // The server name must match the name on the server certificate.
            try
            {
                sslStream.AuthenticateAsClient(serverName);
            }
            catch (AuthenticationException e)
            {
                Console.WriteLine("Exception: {0}", e.Message);
                if (e.InnerException != null)
                {
                    Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                }
                Console.WriteLine("Authentication failed - closing the connection.");
                client.Close();
                return;
            }

            // Encode a test message into a byte array.
            // Signal the end of the message using the "$".
            byte[] messsage = Encoding.UTF8.GetBytes(inputMessage + "$");
            // Send hello message to the server. 
            sslStream.Write(messsage);
            sslStream.Flush();

            // Read message from the server.
            string serverMessage = ReadMessage(sslStream);
            Console.WriteLine("Server says: {0}", serverMessage.Substring(0, serverMessage.IndexOf("$")));


            // Close the client connection.
            client.Close();
            Console.WriteLine("Client closed.");
            Console.WriteLine();
        }

        private static string ReadMessage(SslStream sslStream)
        {
            // Read the message sent by the server.
            // The end of the message is signaled using the "$" marker
            byte[] buffer = new byte[2048];
            StringBuilder messageData = new StringBuilder();
            int bytes = -1;

            do
            {
                bytes = sslStream.Read(buffer, 0, buffer.Length);

                Decoder decoder = Encoding.UTF8.GetDecoder();
                char[] chars = new char[decoder.GetCharCount(buffer,0,bytes)];
                decoder.GetChars(buffer, 0, bytes, chars, 0);
                messageData.Append(chars);

                if (messageData.ToString().IndexOf("$") != -1)
                {
                    break;
                }
            } while (bytes != 0);

            return messageData.ToString();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {            
            string inputMessage = string.Empty;

            do
            {
                Console.Write("Clients says: ");
                inputMessage = Console.ReadLine();
                SslTcpClient.RunClient("192.168.0.12", "XYZ Company", inputMessage);
            } while (inputMessage.ToLower() != "exit");
            
            Console.WriteLine("Press any key to continue...");
            Console.ReadLine();
        }
    }


posted by 따시쿵
2015. 3. 17. 15:41 C# with TCP/IP

프로그램 설명




실행 후




Connect 버튼 클릭 후




메시지 전송 후




프로그램 작성


1. handleClient.cs (서버에서 사용하는 클래스)


    class handleClient
    {
        TcpClient clientSocket = null;
        public Dictionary<Tcpclient, string> clientList = null;

        public void startClient(TcpClient clientSocket, Dictionary<Tcpclient, string> clientList)
        {
            this.clientSocket = clientSocket;
            this.clientList = clientList;

            Thread t_hanlder = new Thread(doChat);
            t_hanlder.IsBackground = true;
            t_hanlder.Start();
        }

        public delegate void MessageDisplayHandler(string message, string user_name);
        public event MessageDisplayHandler OnReceived;

        public delegate void DisconnectedHandler(TcpClient clientSocket);
        public event DisconnectedHandler OnDisconnected;

        private void doChat()
        {
            NetworkStream stream = null;
            try
            {
                byte[] buffer = new byte[1024];
                string msg = string.Empty;
                int bytes = 0;
                int MessageCount = 0;

                while (true)
                {
                    MessageCount++;
                    stream = clientSocket.GetStream();
                    bytes = stream.Read(buffer, 0, buffer.Length);
                    msg = Encoding.Unicode.GetString(buffer, 0, bytes);
                    msg = msg.Substring(0, msg.IndexOf("$"));

                    if (OnReceived != null)
                        OnReceived(msg, clientList[clientSocket].ToString());
                }
            }
            catch (SocketException se)
            {
                Trace.WriteLine(string.Format("doChat - SocketException : {0}", se.Message));

                if (clientSocket != null)
                {
                    if (OnDisconnected != null)
                        OnDisconnected(clientSocket);

                    clientSocket.Close();
                    stream.Close();
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(string.Format("doChat - Exception : {0}", ex.Message));

                if (clientSocket != null)
                {
                    if (OnDisconnected != null)
                        OnDisconnected(clientSocket);

                    clientSocket.Close();
                    stream.Close();
                }
            }
        }

    }


2. 서버 프로그램


    public partial class MainForm : Form
    {
        TcpListener server = null;
        TcpClient clientSocket = null;
        static int counter = 0;

        public Dictionary<Tcpclient, string> clientList = new Dictionary<Tcpclient,string>();
 
        public MainForm()
        {
            InitializeComponent();

            // socket start
            Thread t = new Thread(InitSocket);
            t.IsBackground = true;
            t.Start();
        }

        private void InitSocket()
        {
            server = new TcpListener(IPAddress.Any, 9999);
            clientSocket = default(TcpClient);
            server.Start();
            DisplayText(">> Server Started");

            while(true)
            {
                try
                {
                    counter++;
                    clientSocket = server.AcceptTcpClient();
                    DisplayText(">> Accept connection from client");

                    NetworkStream stream = clientSocket.GetStream();
                    byte[] buffer = new byte[1024];
                    int bytes = stream.Read(buffer, 0, buffer.Length);
                    string user_name = Encoding.Unicode.GetString(buffer, 0, bytes);
                    user_name = user_name.Substring(0, user_name.IndexOf("$"));

                    clientList.Add(clientSocket, user_name);

                    // send message all user
                    SendMessageAll(user_name + " Joined ", "",  false);

                    handleClient h_client = new handleClient();
                    h_client.OnReceived += new handleClient.MessageDisplayHandler(OnReceived);
                    h_client.OnDisconnected += new handleClient.DisconnectedHandler(h_client_OnDisconnected);                    
                    h_client.startClient(clientSocket, clientList);
                }
                catch (SocketException se)
                {
                    Trace.WriteLine(string.Format("InitSocket - SocketException : {0}", se.Message));
                    break;
                }
                catch (Exception ex)
                {
                    Trace.WriteLine(string.Format("InitSocket - Exception : {0}", ex.Message));
                    break;
                }
            }

            clientSocket.Close();
            server.Stop();
        }

        void h_client_OnDisconnected(TcpClient clientSocket)
        {
            if (clientList.ContainsKey(clientSocket))
                clientList.Remove(clientSocket);
        }

        private void OnReceived(string message, string user_name)
        {
            string displayMessage = "From client : " + user_name + " : " + message;
            DisplayText(displayMessage);
            SendMessageAll(message, user_name, true);
        }

        public void SendMessageAll(string message, string user_name, bool flag)
        {
            foreach(var pair in clientList)
            {
                Trace.WriteLine(string.Format("tcpclient : {0} user_name : {1}", pair.Key, pair.Value));

                TcpClient client = pair.Key as TcpClient;
                NetworkStream stream = client.GetStream();
                byte[] buffer = null;

                if(flag)
                {
                    buffer = Encoding.Unicode.GetBytes(user_name + " says : " + message);
                }
                else
                {
                    buffer = Encoding.Unicode.GetBytes(message);
                }
                
                stream.Write(buffer, 0, buffer.Length);
                stream.Flush();
            }
        }

        private void DisplayText(string text)
        {
            if (richTextBox1.InvokeRequired)
            {
                richTextBox1.BeginInvoke(new MethodInvoker(delegate
                {
                    richTextBox1.AppendText(text + Environment.NewLine);
                }));
            }
            else
                richTextBox1.AppendText(text + Environment.NewLine);
        }
    }


3. 클라이언트 프로그램


    public partial class MainForm : Form
    {
        TcpClient clientSocket = new TcpClient();
        NetworkStream stream = default(NetworkStream);
        string message = string.Empty;

        public MainForm()
        {
            InitializeComponent();
        }

        private void btnSendText_Click(object sender, EventArgs e)
        {
            byte[] buffer = Encoding.Unicode.GetBytes(this.textBoxMessage.Text + "$");
            stream.Write(buffer, 0, buffer.Length);
            stream.Flush();
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            clientSocket.Connect("192.168.0.12", 9999);
            stream = clientSocket.GetStream();

            message = "Connected to Chat Server";
            DisplayText(message);

            byte[] buffer = Encoding.Unicode.GetBytes(this.textBoxNickName.Text + "$");
            stream.Write(buffer, 0, buffer.Length);
            stream.Flush();

            Thread t_handler = new Thread(GetMessage);
            t_handler.IsBackground = true;
            t_handler.Start();
        }

        private void GetMessage()
        {
            while(true)
            {
                stream = clientSocket.GetStream();
                int BUFFERSIZE = clientSocket.ReceiveBufferSize;
                byte[] buffer = new byte[BUFFERSIZE];
                int bytes = stream.Read(buffer, 0, buffer.Length);

                string message = Encoding.Unicode.GetString(buffer, 0, bytes);
                DisplayText(message);
            }
        }

        private void DisplayText(string text)
        {
            if (richTextBox1.InvokeRequired)
            {
                richTextBox1.BeginInvoke(new MethodInvoker(delegate
                {
                    richTextBox1.AppendText(text + Environment.NewLine);
                }));
            }
            else
                richTextBox1.AppendText(text + Environment.NewLine);
        }
    }


posted by 따시쿵
2015. 3. 14. 17:30 C# with TCP/IP

프로그램 설명


1:1 통신에 이어서 1:N 통신을 다루는 프로그램입니다.

각 클라이언트 소켓마다 쓰레드를 만들어서 통신하는 방법입니다.





실행 후




메신지 전송 후




프로그램 작성 순서


1. 서버 사이드 소켓 핸들 (handleClient.cs)


    class handleClient
    {
        TcpClient clientSocket;
        int clientNo;

        public void startClient(TcpClient ClientSocket, int clientNo)
        {
            this.clientSocket = ClientSocket;
            this.clientNo = clientNo;

            Thread t_hanlder = new Thread(doChat);
            t_hanlder.IsBackground = true;
            t_hanlder.Start();
        }

        public delegate void MessageDisplayHandler(string text);
        public event MessageDisplayHandler OnReceived;

        public delegate void CalculateClientCounter();
        public event CalculateClientCounter OnCalculated;

        private void doChat()
        {
            NetworkStream stream = null;
            try
            { 
                byte[] buffer = new byte[1024];
                string msg = string.Empty;
                int bytes = 0;
                int MessageCount = 0;                

                while(true)
                {
                    MessageCount++;
                    stream = clientSocket.GetStream();
                    bytes = stream.Read(buffer, 0, buffer.Length);
                    msg = Encoding.Unicode.GetString(buffer, 0, bytes);
                    msg = msg.Substring(0, msg.IndexOf("$"));
                    msg = "Data Received : " + msg;

                    if (OnReceived != null)
                        OnReceived(msg);

                    msg = "Server to client(" + clientNo.ToString() + ") " + MessageCount.ToString();
                    if (OnReceived != null)
                        OnReceived(msg);

                    byte[] sbuffer = Encoding.Unicode.GetBytes(msg);
                    stream.Write(sbuffer, 0, sbuffer.Length);
                    stream.Flush();

                    msg = " >> " + msg;
                    if (OnReceived != null) { 
                        OnReceived(msg);
                        OnReceived("");
                    }
                }
            }
            catch(SocketException se)
            {
                Trace.WriteLine(string.Format("doChat - SocketException : {0}", se.Message));

                if (clientSocket != null)
                {
                    clientSocket.Close();
                    stream.Close();
                }

                if (OnCalculated != null)
                    OnCalculated();
            }
            catch (Exception ex)
            {
                Trace.WriteLine(string.Format("doChat - Exception : {0}", ex.Message));

                if (clientSocket != null)
                {
                    clientSocket.Close();
                    stream.Close();
                }

                if (OnCalculated != null)
                    OnCalculated();
            }
        }
    }


2. 서버 프로그램


    public partial class MainForm : Form
    {
        TcpListener server = null;
        TcpClient client = null;
        static int counter = 0;

        public MainForm()
        {
            InitializeComponent();

            // socket start
            Thread t = new Thread(InitSocket);
            t.IsBackground = true;
            t.Start();
        }
        
        private void InitSocket()
        {
            server = new TcpListener(IPAddress.Any, 9999);
            client = default(TcpClient);
            server.Start();
            DisplayText(">> Server Started");

            while(true)
            {
                try
                { 
                    counter++;
                    client = server.AcceptTcpClient();
                    DisplayText(">> Accept connection from client");

                    handleClient h_client = new handleClient();
                    h_client.OnReceived += new handleClient.MessageDisplayHandler(DisplayText);
                    h_client.OnCalculated += new handleClient.CalculateClientCounter(CalculateCounter);
                    h_client.startClient(client, counter);
                }
                catch (SocketException se)
                {
                    Trace.WriteLine(string.Format("InitSocket - SocketException : {0}", se.Message));
                }
                catch (Exception ex)
                {
                    Trace.WriteLine(string.Format("InitSocket - Exception : {0}", ex.Message));
                }
            }        
        }

        private void CalculateCounter()
        {
            counter--;
        }

        private void DisplayText(string text)
        {
            if (richTextBox1.InvokeRequired)
            {
                richTextBox1.BeginInvoke(new MethodInvoker(delegate
                {
                    richTextBox1.AppendText(text + Environment.NewLine);
                }));
            }
            else
                richTextBox1.AppendText(text + Environment.NewLine); 
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (client != null)
            {
                client.Close();
                client = null;
            }

            if (server != null)
            {
                server.Stop();
                server = null;
            }
        }
    }


3. 클라이언트 프로그램


    public partial class MainForm : Form
    {
        TcpClient clientSocket = new TcpClient();

        public MainForm()
        {
            InitializeComponent();

            new Thread(delegate()
                {
                    InitSocket();
                }).Start();            
        }

        private void InitSocket()
        {
            try
            {
                clientSocket.Connect("192.168.0.12", 9999);
                DisplayText("Client Started");
                labelStatus.Text = "Client Socket Program - Server Connected ...";
            }
            catch (SocketException se)
            {
                MessageBox.Show(se.Message, "Error");                
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error");
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            NetworkStream stream = clientSocket.GetStream();
            byte[] sbuffer = Encoding.Unicode.GetBytes(richTextBox2.Text + "$");
            stream.Write(sbuffer, 0, sbuffer.Length);
            stream.Flush();

            byte[] rbuffer = new byte[1024];
            stream.Read(rbuffer, 0, rbuffer.Length);
            string msg = Encoding.Unicode.GetString(rbuffer);
            msg = "Data from Server : " + msg;
            DisplayText(msg);

            richTextBox2.Text = "";
            richTextBox2.Focus();
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (clientSocket != null)
                clientSocket.Close();
        }

        private void DisplayText(string text)
        {
            if (richTextBox1.InvokeRequired)
            {
                richTextBox1.BeginInvoke(new MethodInvoker(delegate
                {
                    richTextBox1.AppendText(Environment.NewLine + " >> " + text);
                }));
            }
            else
                richTextBox1.AppendText(Environment.NewLine + " >> " + text);
        }
    }


posted by 따시쿵
2015. 3. 12. 16:41 C# with TCP/IP

프로그램 설명


한 프로그램에서 여러개의 포트를 열어서 작업이 필요한 경우입니다.

포트별로 쓰레드를 만들어서 작업하는 방식입니다. 예제에서는 8080, 8081 포트를 엽니다.




실행 후



프로그램 작성 순서


1. ListenPorts.cs


    class ListenPorts
    {
        Socket[] socket;
        IPEndPoint[] ipEndPoint;

        internal ListenPorts(IPEndPoint[] ipEndPoint)
        {
            this.ipEndPoint = ipEndPoint;
            socket = new Socket[ipEndPoint.Length];
        }

        public void beginListen()
        {
            for(int i = 0; i < ipEndPoint.Length; i++)
            {
                socket[i] = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket[i].Bind(ipEndPoint[i]);

                Thread t_handler = new Thread(threadListen);
                t_handler.IsBackground = true;
                t_handler.Start(socket[i]);
            }
        }

        private void threadListen(object sender)
        {
            Socket m_client = sender as Socket;
            byte[] data = new byte[1024];
            
            try
            {
                m_client.Listen(100);
                Socket newSocket = m_client.Accept();
                int bytes = newSocket.Receive(data);

                IPEndPoint remoteIP = newSocket.RemoteEndPoint as IPEndPoint;
                IPEndPoint localIP = newSocket.LocalEndPoint as IPEndPoint;

                Console.WriteLine("server ip : {0} remote ip : {1} ", localIP.ToString(), remoteIP.ToString());
                Console.WriteLine("Received data : {0}", Encoding.Unicode.GetString(data, 0, bytes));
                
                string msg = "Welcome to multiple server";
                byte[] buffer = Encoding.Unicode.GetBytes(msg);
                newSocket.Send(buffer, buffer.Length, SocketFlags.None);
                Console.WriteLine("Send data : {0}", msg);
                Console.WriteLine();
            }
            catch(SocketException se)
            {
                Console.WriteLine(se.Message);
            }
            
        }
    }


2. 서버 프로그램


    class Program
    {
        static void Main(string[] args)
        {
            IPEndPoint ipEndPoint1 = new IPEndPoint(IPAddress.Any, 8080);
            IPEndPoint ipEndPoint2 = new IPEndPoint(IPAddress.Any, 8081);

            IPEndPoint[] ipEndPoint = new IPEndPoint[2] { ipEndPoint1, ipEndPoint2 };
            //IPEndPoint[] ipEndPoint = new IPEndPoint[1] { ipEndPoint1 };

            ListenPorts listenport = new ListenPorts(ipEndPoint);
            listenport.beginListen();
            Console.WriteLine("Begin Listen");
            Console.WriteLine();
            
            Console.ReadKey();
        }
    }


3. 클라이언트 프로그램


    class Program
    {
        static void Main(string[] args)
        {
            byte[] data = new byte[1024];

            //TCP Client

            Console.WriteLine("This is a Client, host name is {0}", Dns.GetHostName());
            Console.WriteLine();

            //Set the IP address of the server, and its port.
            IPEndPoint ipep1 = new IPEndPoint(IPAddress.Parse("192.168.0.12"), 8080);
            IPEndPoint ipep2 = new IPEndPoint(IPAddress.Parse("192.168.0.12"), 8081);
            string welcome = "Hello, Multiple server ! ";

            // port 8080 으로 전송
            try
            {
                // 소켓 생성
                Socket server1 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                // 메시지 전송
                data = Encoding.Unicode.GetBytes(welcome);
                server1.Connect(ipep1);
                server1.Send(data);
                Console.WriteLine("Send by the port : {0}", server1.LocalEndPoint.ToString());
                Console.WriteLine("Send data : {0}", welcome);

                // 메시지 받음
                byte[] msg = new byte[1024];
                int bytes = server1.Receive(msg);
                Console.WriteLine("Received data : {0}", Encoding.Unicode.GetString(msg, 0, bytes));
                Console.WriteLine();
                // 소켓 닫기
                server1.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            // port 8081 으로 전송
            try
            {
                // 소켓 생성
                Socket server2 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                // 메시지 전송
                data = Encoding.Unicode.GetBytes(welcome);
                server2.Connect(ipep2);
                server2.Send(data);
                Console.WriteLine("Send by the port : {0}", server2.LocalEndPoint.ToString());
                Console.WriteLine("Send data : {0}", welcome);

                // 메시지 받음
                byte[] msg = new byte[1024];
                int bytes = server2.Receive(msg);
                Console.WriteLine("Received data : {0}", Encoding.Unicode.GetString(msg, 0, bytes));
                Console.WriteLine();
                // 소켓 닫기
                server2.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.ReadKey();
        }
    }


posted by 따시쿵
2015. 2. 25. 15:11 C# with TCP/IP
프로그램 설명


codeproject 의 소켓 라이브러리를 이용한 예제를 만들었습니다.


라이브러리에 대한 자세한 설명은 http://www.codeproject.com/Articles/563627/A-full-library-for-a-Socket-Client-Server-system 를 참고하시면 되고, 기본 라이브러리에서 몇가지 수정한 부분이 있습니다.



서버의 기능 


1. 접속자 리스트 관리 - 각 개인별로 메시지를 전송할 수 있음 

   ==> 사용자 이름에 마우스 오른쪽 버튼을 클릭하면 [메시지 전송하기] contextmenu 가 있으며, 

         이것을 이용해서 개별적으로 메시지를 전송할 수 있음


2. [모두에게] 기능을 추가 해서 전체 참석자에게 일괄적으로 메시지를 전송할 수 있음.


3. log4net 라이브러리를 이용해서 폴더에 날짜별로 로그를 쌓을 수 있음


3. log 탭과 message 탭을 따로 두어서, 서버의 작동 상태나 클라이언트의 연결/비연결 상태는 log 탭에

  실시간으로 보여주고, 클라이언트와의 메시지 확인은 message 탭에서 확인이 가능함



클라이언트 기능


1. [Launch clients...] 기능을 두어서 multiple 접속이 가능하게 구현해 두었으며, 서버의 상태를 확인

   가능함


2. 일반 메시지와 비밀글 기능을 두었음



실행 후






메시지 전송 후






프로그램 작성


codeproject 에서 다운을 받으면 실제적인 라이브러리 프로젝트는 AsyncClientServerLib, BaseClientServerLib, SocketServerLib 3개 입니다.


나머지는 테스트용도 입니다.


여기에 올린 프로그램은 Custom_ClientSock, Custom_ServerSocket 두 개입니다.

테스트 용도라면 아이피 부분만 각자의 환경에 맞게 수정하시면 됩니다.





SocketServer_V4.zip





posted by 따시쿵
2015. 2. 12. 15:57 C# with UDP/IP

udp multicast 는 sender가 receiver 에게 데이타를 단방향 통신으로 전달하는 기술 기법입니다.


multicast 구현시 고려할 사항


▷ IP multicast 에서 사용할 아이피를 적당하게 잘 선택해야 합니다. 

   선택한 아이피로 멀티캐스트그룹을 만들어야 하므로 다른 시스템에서 사용하지 않는 아이피를 사용

   합니다.

   

   사용할 아이피는 IANA 정보에 따라서 239.0.0.0 와 239.255.255.255 사이의 아이피를 선택합니다.

   MComms TV 에도 정보가 나와 있으니 참조하면 됩니다.


▷ 시스템에서 사용하지 않는 포트를 선택합니다.

   Windows Vista, 7, 2008 는 포트 번호 49152 와 65535, 예전 윈도즈는 1025 와 5000 그리고 Linux

   는 32768 와 61000 번호를 선택합니다.

   

   자세한 정보는 여기에 나와 있습니다. MComms TV 



프로그램 설명


sender 가 특정 아이피로 멀티캐스트그룹을 만들고, 그룹에 참가하는 receiver 에게 루프를 돌면서 메시지를 전송한 것입니다.



실행 후


메시지 전송 후


프로그램 작성 순서


1. 공통 라이브러리


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


2. Sender 프로그램


        static void Main(string[] args)
        {
            UdpClient udpclient = new UdpClient();

            IPAddress multicastaddress = IPAddress.Parse("239.0.0.222");
            udpclient.JoinMulticastGroup(multicastaddress);
            IPEndPoint remoteEP = new IPEndPoint(multicastaddress, 2222);

            byte[] buffer = null;

            Console.WriteLine("Press ENTER to start sending message");
            Console.ReadLine();

            for (int i = 0; i <= 8000; i++)
            {
                buffer = Encoding.Unicode.GetBytes(i.ToString());
                udpclient.Send(buffer, buffer.Length, remoteEP);
                Console.WriteLine("Sent : {0}", i.ToString());
            }

            buffer = Encoding.Unicode.GetBytes("quit");
            udpclient.Send(buffer, buffer.Length, remoteEP);

            udpclient.Close();

            Console.WriteLine("All Done! Press ENTER to quit.");
            Console.ReadLine();
        }


3. Receiver 프로그램


        static void Main(string[] args)
        {
            UdpClient client = new UdpClient();

            client.ExclusiveAddressUse = false;
            IPEndPoint localEp = new IPEndPoint(IPAddress.Any, 2222);

            client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            client.ExclusiveAddressUse = false;

            client.Client.Bind(localEp);

            IPAddress multicastaddress = IPAddress.Parse("239.0.0.222");
            client.JoinMulticastGroup(multicastaddress);

            Console.WriteLine("Listening this will quit");

            while(true)
            {
                byte[] data = client.Receive(ref localEp);
                string strData = Encoding.Unicode.GetString(data);
                Console.WriteLine("received data : {0}", strData);

                if (strData == "quit")
                    break;
            }

            Console.WriteLine("quit the program to ENTER");
            Console.ReadLine();
        }
posted by 따시쿵
2015. 2. 9. 12:10 C# with TCP/IP

프로그램 설명


이번 예제는 연결된 클라이언트, 모두에게 메시지를 전송하는 코드입니다.

서버는 접속 커넥션을 기달렸다가 클라이언트가 접속을 하게 되면 각 접속은 새로운 쓰레드가 담당을 관리합니다.


서버는 모든 연결된 클라이언트를 array list 로 관리를 합니다.


클라이언트가 메시지를 서버에게 전달을 하게 되면, 쓰레드가 본인 클라이언트만 제외하고 모든 접속 된 클라이언트에게 메시지를 전달합니다.



실행 후




메시진 전송 후





프로그램 작성 순서


1. 공통 라이브러리


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


2. 서버 프로그램


    class Program
    {
        private static TcpListener server;
        private static List<tcpclient> clientList = new List<tcpclient>();

        static void Main(string[] args)
        {
            server = new TcpListener(IPAddress.Any, 12340);
            server.Start();

            Console.WriteLine("server started\n");
            Console.WriteLine("waiting for a client");

            while(true)
            {                
                TcpClient client = server.AcceptTcpClient();
                clientList.Add(client);

                Thread t_handler = new Thread(new ParameterizedThreadStart(ClientListener));
                t_handler.Start(client);

                // 디버깅 용
                Debug.WriteLine("Thread count = {0}", Process.GetCurrentProcess().Threads.Count);
            }            
        }

        static void ClientListener(object sender)
        {
            TcpClient client = null;
            StreamReader sr = null;

            try
            {
                client = sender as TcpClient;
                sr = new StreamReader(client.GetStream());

                Console.WriteLine("New Client connected\n");

                while (true)
                {
                    string message = sr.ReadLine();
                    if (!string.IsNullOrEmpty(message))
                    { 
                        BroadCast(message, client);
                        Console.WriteLine("received data : {0}\n", message);
                    }
                }
            }
            catch (SocketException se)
            {
                Console.WriteLine("SocketException : {0}\n", se.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception : {0}\n", ex.Message);
            }
            finally
            {
                Console.WriteLine("client disconnected\n");
                clientList.Remove(client);

                sr.Close();
                client.Close();

                Thread.CurrentThread.Abort();
            }
        }

        static void BroadCast(string message, TcpClient excludeClient)
        {
            foreach(TcpClient client in clientList)
            {
                if (client != excludeClient)
                { 
                    StreamWriter sw = new StreamWriter(client.GetStream());
                    sw.WriteLine(message);
                    sw.Flush();
                }
            }
        }
    }


3. 클라이언트 프로그램


        static void Main(string[] args)
        {
            TcpClient client = null;
            StreamWriter sw = null;

            try
            { 
                client = new TcpClient("192.168.0.12", 12340);
                Console.WriteLine("Connected to server.\n");

                Thread c_thread = new Thread(new ParameterizedThreadStart(Client_Read));
                c_thread.Start(client);

                sw = new StreamWriter(client.GetStream());

                while(true)
                {
                    if (client.Connected)
                    {
                        Console.Write("send data : ");
                        string input = Console.ReadLine();
                        sw.WriteLine(input);
                        sw.Flush();
                    }
                    else
                        break;
                }
            }
            catch (SocketException se)
            {
                Console.WriteLine("SocketException : {0}", se.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception : {0}", ex.Message);
            }
            finally
            {
                sw.Close();
                client.Close();
            }

            Console.WriteLine("Press the ENTER key to continue...");
            Console.ReadLine();
        }

        static void Client_Read(object sender)
        {
            TcpClient client = sender as TcpClient;
            StreamReader sr = new StreamReader(client.GetStream());

            try
            {
                while(true)
                {
                    string message = sr.ReadLine();
                    if (!string.IsNullOrEmpty(message))
                        Console.WriteLine("\nreceived data : {0}\n", message);
                }
            }
            catch(SocketException se)
            {
                Console.WriteLine("SocketException : {0}\n", se.Message);
            }
            catch(Exception ex)
            {
                Console.WriteLine("Exception : {0}\n", ex.Message);
            }
            finally
            {
                sr.Close();
                client.Close();
            }
        }


posted by 따시쿵
prev 1 2 3 4 next