블로그 이미지
따시쿵

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. 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. 21. 07:43 C#

log4net 을 이용한 로그파일 쓰는 예제입니다. 라이브러리 다운로드와 자세한 설명은 다음의 사이트를 이용하시면 됩니다. http://logging.apache.org/log4net/index.html


파일 이름이 날짜로 되어서 구분하는 예제를 만들었습니다.


app.config App.config


<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  
<!--log4net 설정하는 부분 시작-->    
  <log4net>    
    <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
      <file value="logs\" />
      <datePattern value="yyyy-MM-dd'.log'" />
      <staticLogFileName value="false" />
      <appendToFile value="true" />
      <rollingStyle value="Date" />
      <maxSizeRollBackups value="10" />
      <maximumFileSize value="50MB" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
      </layout>
    </appender>
  
    
    <root>
      <!--LogLevel: OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL -->
      <level value="ALL" />
      <appender-ref ref="LogFileAppender" />
    </root>
  </log4net>
<!--log4net 설정하는 부분 종료--> 
  

    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
</configuration>


사용예제


            new Thread(delegate()
                {
                    for (int i = 0; i <= 100; i++)
                    {
                        Logger.WriteLog(LogLevel4N.INFO, i.ToString());
                    }
                }).Start();

            new Thread(delegate()
            {
                for (int i = 0; i <= 100; i++)
                {
                    Logger.WriteLog(LogLevel4N.DEBUG, i.ToString());
                }
            }).Start();

            new Thread(delegate()
            {
                for (int i = 0; i <= 100; i++)
                {
                    Logger.WriteLog(LogLevel4N.ERROR, i.ToString());
                }
            }).Start();

            new Thread(delegate()
            {
                for (int i = 0; i <= 100; i++)
                {
                    Logger.WriteLog(LogLevel4N.WARN, i.ToString());
                }
            }).Start();      


posted by 따시쿵
2015. 2. 21. 07:21 C#

Trace class를 이용해서 파일에 로그 파일을 쓰는 경우가 있습니다. 이런 경우에도 설정 파일(app.config)을 이용해서 파일에 쓰는 경우를 보여 줍니다.


Trace.WriteLine 을 이용한 경우입니다.

System.IO.StreamWriter class 와 로그 파일에 lock mode 를 걸지 않는 경우입니다.


app.config


  <!--Trace.WriteLine 을 설정하는 부분 시작 -->
  <system.diagnostics>
    <trace autoflush="true" indentsize="4">
      <listeners>
        <add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializedata="TextWriterOutput.log" />
        <remove name="Default" />
      </remove>
    </trace>
  </system.diagnostics>
 <!--Trace.WriteLine 을 설정하는 부분 종료 -->


LoggerSystem.cs


    #region LoggerSystem class
    public static class LoggerSystem
    {
        public static void Error(string message, string module)
        {
            WriteEntry(message, "error", module);
        }

        public static void Error(Exception ex, string module)
        {
            WriteEntry(ex.Message, "error", module);
        }

        public static void Warning(string message, string module)
        {
            WriteEntry(message, "warning", module);
        }

        public static void Info(string message, string module)
        {
            WriteEntry(message, "info", module);
        }

        private static void WriteEntry(string message, string type, string module)
        {
            Trace.WriteLine(
                    string.Format("[{0}],{1},{2},{3}",
                                  DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                                  type,
                                  module,
                                  message));
        }
    }
    #endregion


사용예제


            new Thread(delegate()
                {
                    for (int i = 0; i <= 1000; i++)
                    {
                        LoggerSystem.Error("button1_Click = " + i.ToString(), "myapp");
                    }
                }).Start();

            new Thread(delegate()
            {
                for (int i = 0; i <= 1000; i++)
                {
                    LoggerSystem.Info("button2_Click = " + i.ToString(), "myapp");
                }
            }).Start();  


'C#' 카테고리의 다른 글

BackgroundWorker class  (0) 2015.03.02
텍스트 로그 파일 라이브러리 - 3  (0) 2015.02.21
멀티플(multiple) 윈도우 - 1  (0) 2015.01.24
멀티스레드 환경에서 UI 에 데이타 표시할 경우  (0) 2015.01.15
Task 클래스  (0) 2015.01.10
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 따시쿵
2015. 2. 2. 16:48 C# with UDP/IP

프로그램 설명


udp 클라이언트/서버 예제입니다.


UdpClient 클래스는 전송 및 동기 블록 모드 비 연결 UDP 데이터 그램 을 수신하기위한 간단한 방법을 제공합니다. UDP 는 비 연결 전송 프로토콜 이기 때문에, 전송 및 데이터를 수신 하기 전에 원격 호스트 연결을 설정할 필요가 없습니다. 


다음의 두 가지 방법 중 하나를기본 원격 호스트를 확립 하는 옵션 을 가질 것 :


1. 원격 호스트 이름 및 매개 변수로 포트 번호를 사용하여 UdpClient 클래스의 인스턴스를 만듭니다.

2. UdpClient 클래스의 인스턴스를 생성 한 다음 연결 메소드를 호출합니다.


ReceiveFrom method 의 IPEndPoint 을 이용해서 전송하는 호스트의 정보를 알 수 있습니다.


실행 후


메시지 전송 후





프로그램 작성 순서


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


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


2. 서버 프로그램


        static void Main(string[] args)
        {
            int recv = 0;
            byte[] data = new byte[1024];

            IPEndPoint ep = new IPEndPoint(IPAddress.Any, 9050);
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            server.Bind(ep);

            Console.WriteLine("Waiting for a client...");

            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
            EndPoint remoteEP = (EndPoint)sender;

            recv = server.ReceiveFrom(data, ref remoteEP);
            
            Console.WriteLine("[first] Message received from {0}", remoteEP.ToString());
            Console.WriteLine("[first] received data : {0}", Encoding.UTF8.GetString(data, 0, recv));

            string welcome = "Welcome to udp server";
            data = Encoding.UTF8.GetBytes(welcome);
            server.SendTo(data, remoteEP);

            while(true)
            {
                data = new byte[1024];
                recv = server.ReceiveFrom(data, ref remoteEP);
                string recvData = Encoding.UTF8.GetString(data, 0, recv);
                Console.WriteLine("received data : {0}", recvData);

                server.SendTo(Encoding.UTF8.GetBytes(recvData), remoteEP);
                Console.WriteLine("send data : {0}", Encoding.UTF8.GetString(data, 0, recv));
                Console.WriteLine("");
            }

            server.Close();
        }


3. 클라이언트 프로그램


        static void Main(string[] args)
        {
            int recv = 0;
            byte[] data = new byte[1024];
            string input, stringData;

            IPEndPoint serverEP = new IPEndPoint(IPAddress.Parse("192.168.0.12"), 9050);

            Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
            EndPoint remoteEP = (EndPoint)sender;

            string welcome = "hello, udp server?";
            data = Encoding.UTF8.GetBytes(welcome);
            client.SendTo(data, data.Length, SocketFlags.None, serverEP);

            data = new byte[1024];
            recv = client.ReceiveFrom(data, ref remoteEP);

            Console.WriteLine("[first] Message received from {0}", remoteEP.ToString());
            stringData = Encoding.UTF8.GetString(data, 0, recv);
            Console.WriteLine(stringData);

            while (true)
            {
                Console.Write("send data : ");
                input = Console.ReadLine();
                if (input == "exit")
                    break;

                data = Encoding.UTF8.GetBytes(input);
                client.SendTo(data, data.Length, SocketFlags.None, serverEP);

                recv = client.ReceiveFrom(data, ref remoteEP);
                stringData = Encoding.UTF8.GetString(data);
                Console.WriteLine("received data : {0}", stringData);
            }

            Console.WriteLine("Stopping client");
            client.Close();
        }


'C# with UDP/IP' 카테고리의 다른 글

[Program C#]Broadcast  (0) 2015.02.25
[Program C#]UDP Multicast  (0) 2015.02.12
[Program C#]UDP 통신 - 기본(UdpClient) - 콘솔 버전  (0) 2015.02.02
TCP & UDP 비교  (0) 2015.02.02
posted by 따시쿵
2015. 2. 2. 09:12 C# with UDP/IP

프로그램 설명


udp 클라이언트/서버 예제입니다.


UdpClient 클래스는 전송 및 동기 블록 모드 비 연결 UDP 데이터 그램 을 수신하기위한 간단한 방법을 제공합니다. UDP 는 비 연결 전송 프로토콜 이기 때문에, 전송 및 데이터를 수신 하기 전에 원격 호스트 연결을 설정할 필요가 없습니다. 


다음의 두 가지 방법 중 하나를기본 원격 호스트를 확립 하는 옵션 을 가질 것 :


1. 원격 호스트 이름 및 매개 변수로 포트 번호를 사용하여 UdpClient 클래스의 인스턴스를 만듭니다.

2. UdpClient 클래스의 인스턴스를 생성 한 다음 연결 메소드를 호출합니다.


Receive method 의 IPEndPoint 을 이용해서 전송하는 호스트의 정보를 알 수 있습니다.


실행 후


메시지 전송 후



프로그램 작성 순서


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


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


2. 서버 프로그램


            byte[] data = new byte[1024];
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
            UdpClient server = new UdpClient(ipep);

            Console.WriteLine("Waiting for a client....");

            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);

            data = server.Receive(ref sender);

            Console.WriteLine("Message received from {0}", sender.ToString());
            Console.WriteLine("received data : {0}", Encoding.UTF8.GetString(data, 0, data.Length));

            string welcome = "Welcome to my udp server";
            data = Encoding.UTF8.GetBytes(welcome);
            server.Send(data, data.Length, sender);

            while(true)
            {
                data = server.Receive(ref sender);
                Console.WriteLine("received data : {0}", Encoding.UTF8.GetString(data, 0, data.Length));

                server.Send(data, data.Length, sender);
                Console.WriteLine("send data : {0}", Encoding.UTF8.GetString(data, 0, data.Length));
            }

            server.Close();


3. 클라이언트 프로그램


            byte[] data = new byte[1024];
            string input, stringData;
            UdpClient client = new UdpClient("192.168.0.12", 9050);

            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);

            string welcome = "hello, udp server?";
            data = Encoding.UTF8.GetBytes(welcome);
            client.Send(data, data.Length);

            data = client.Receive(ref sender);

            Console.WriteLine("Message received from {0}", sender.ToString());
            stringData = Encoding.UTF8.GetString(data, 0, data.Length);
            Console.WriteLine(stringData);

            while(true)
            {
                Console.Write("send data : ");
                input = Console.ReadLine();
                if (input == "exit")
                    break;

                data = Encoding.UTF8.GetBytes(input);
                client.Send(data, data.Length);
                data = client.Receive(ref sender);
                stringData = Encoding.UTF8.GetString(data);
                Console.WriteLine("received data : {0}", stringData);
            }

            client.Close();
            Console.WriteLine("Stopping clinet");
            


'C# with UDP/IP' 카테고리의 다른 글

[Program C#]Broadcast  (0) 2015.02.25
[Program C#]UDP Multicast  (0) 2015.02.12
[Program C#]UDP 통신 - 기본(Socket) - 콘솔 버전  (1) 2015.02.02
TCP & UDP 비교  (0) 2015.02.02
posted by 따시쿵
2015. 2. 2. 09:11 C# with UDP/IP






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

프로그램 설명


이번 예제는 Binary Serialization / Deserialization 을 이용한 통신 방법을 설명합니다.


클래스에 property 로 5개 필드(Name, Subject, Grade, Memo, SendTime)를 정의 합니다. SendTime 필드는 전송하는 클라이언트의 전송 시각을 기입하고, 서버에서 메시지를 받아서 네트워크 지연 시간을 확인 해 보기 위한 용도로 추가 했습니다. 또한 탭컨트롤을 추가해서 [Log], [Message] 화면을 구분했습니다.


3개의 프로젝트가 필요합니다.


1. 공통 라이브러리 

   ==> 클라이언트와 서버에서 사용할 클래스

   ==> 클래스 이름 위에 [Serializable] 특성을 기입하는 게 중요함.

   ==> DataPacket.cs



2. 클라이언트 프로그램


3. 서버 프로그램



실행 후


메시지 전송 후



프로그램 작성 순서


1. 공통 라이브러리 (Common Libray) 

클라이언트와 서버에서 사용할 어셈블리 코드


    [Serializable]
    public class DataPacket
    {
        public string Name { get; set; }
        public string Subject { get; set; }
        public Int32 Grade { get; set; }
        public string Memo { get; set; }
        public DateTime SendTime { get; set; }
    }

 


2. 서버 프로그램


    public partial class MainForm : Form
    {
        TcpListener server = null;
        public MainForm()
        {
            InitializeComponent();
            FormClosing += new FormClosingEventHandler(WindowsFormClosing);
            InitStart();

            // 탭 페이지 [message] 탭 활성화
            tabControl1.SelectTab("tabPage2");
        }

        private void WindowsFormClosing(object sender, FormClosingEventArgs s)
        {
            if (server != null)
                server = null;

            Application.Exit();
        }
        private void InitStart()
        {
            Thread socketworker = new Thread(new ThreadStart(socketThread));
            socketworker.IsBackground = true;
            socketworker.Start();
        }

        private void socketThread()
        {
            try
            {
                server = new TcpListener(IPAddress.Parse("192.168.0.12"), 13000);
                server.Start();
                updateStatusInfo(string.Format("[{0}] server start", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));

                while (true)
                {
                    TcpClient client = server.AcceptTcpClient();
                    updateStatusInfo(string.Format("[{0}] new connected", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));
                    Thread clientworker = new Thread(new ParameterizedThreadStart(clientThread));
                    clientworker.IsBackground = true;
                    clientworker.Start(client);
                }
            }
            catch (SocketException se)
            {
                Debug.WriteLine("SocketException : {0}", se.Message);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Exception : {0}", ex.Message);
            }
        }

        private void clientThread(object sender)
        {
            string Name = string.Empty;
            string Subject = string.Empty;
            Int32 Grade = 0;
            string Memo = string.Empty;
            DateTime SendTime;
            TimeSpan time = TimeSpan.Zero;

            // 1. 데이타 받기
            TcpClient client = sender as TcpClient;
            NetworkStream stream = client.GetStream();

            byte[] buffer = new byte[8092];
  
            if (client.GetStream().CanRead)
            {                
                IFormatter formatter = new BinaryFormatter();

                DataPacket packet = new DataPacket();
                packet = (DataPacket)formatter.Deserialize(stream);

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

                time = DateTime.Now - SendTime;

                updateStatusInfo(string.Format("[{0}] data received", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));
            }
            

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

            updateStatusInfo(string.Format("[{0}] disconnted", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));

            // 2. 데이타 표시하기
            Invoke((MethodInvoker)delegate
            {
                int count = listView1.Items.Count;
                count++;

                ListViewItem i = new ListViewItem();
                i.Text = count.ToString();
                i.SubItems.Add(Name);
                i.SubItems.Add(Subject);
                i.SubItems.Add(Grade.ToString());
                i.SubItems.Add(Memo);
                i.SubItems.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                i.SubItems.Add(string.Format("{0}.{1} seconds", time.Seconds.ToString(), time.Milliseconds.ToString()));
                listView1.Items.Add(i);

                listView1.Items[this.listView1.Items.Count - 1].EnsureVisible();
            });

            Debug.WriteLine("{0} : {1} : {2} : {3} : {4} : {5}", Name, Subject, Grade, Memo, time.Seconds.ToString(), time.Milliseconds.ToString());
            
        }

        private void updateStatusInfo(string content)
        {
            Action del = delegate()
            {
                listBox1.Items.Add(content);
            };
            Invoke(del);
        }

        private void btnDataClear_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("데이타를 모두 삭제 하시겠습니까?", "질문", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.OK)
            {
                listBox1.Items.Clear();
                listView1.Items.Clear();
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            updateStatusInfo(string.Format("[{0}] server stop", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));
            Application.Exit();
        }
    }


2. 클라이언트 프로그램


        public MainForm()
        {
            InitializeComponent();

            // 마우스 in / out 이벤트 추가
            btnSend.MouseEnter += new EventHandler(btnSend_MouseEnter);
            btnSend.MouseLeave += new EventHandler(btnSend_MouseLeave);

            // 탭 페이지 [message] 탭 활성화
            tabControl1.SelectTab("tabPage2");
        }

        void btnSend_MouseEnter(object sender, EventArgs e)
        {
            btnSend.UseVisualStyleBackColor = false;
            btnSend.BackColor = Color.FromArgb(255, 255, 165, 00);  // 배경색을 오렌지 색으로 변경함...
            btnSend.ForeColor = Color.White;                        // 글자색을 흰색으로 변경함
        }

        void btnSend_MouseLeave(object sender, EventArgs e)
        {
            btnSend.UseVisualStyleBackColor = true;
            btnSend.BackColor = SystemColors.Control;               // 배경색을 시스템 기본색으로 변경함...
            btnSend.ForeColor = SystemColors.ControlText;           // 글자색을 시스템 기본색으로 변경함...
        }

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

        private void socketThread()
        {
            // 1. 데이타패킷 조합
            Debug.WriteLine("{0} : {1} : {2} : {3}", txtName.Text, txtSubject.Text, txtGrade.Text, txtMemo.Text);

            DataPacket packet = new DataPacket();

            packet.Name = txtName.Text;
            packet.Subject = txtSubject.Text;

            Int32 outNum;
            if (Int32.TryParse(txtGrade.Text, out outNum))
            {
                packet.Grade = Convert.ToInt32(txtGrade.Text);
            }
            else
            {
                packet.Grade = 0;
            }

            packet.Memo = txtMemo.Text;

            if (string.IsNullOrEmpty(packet.Name))
            {
                MessageBox.Show("[이 름]을 입력하시기 바랍니다", "경고", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Invoke((MethodInvoker)delegate
                {
                    txtName.Focus();

                });
                return;
            }

            if (string.IsNullOrEmpty(packet.Subject))
            {
                MessageBox.Show("[과 목]을 입력하시기 바랍니다", "경고", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Invoke((MethodInvoker)delegate
                {
                    txtSubject.Focus();

                });
                return;
            }

            if (packet.Grade == 0)
            {
                MessageBox.Show("[점 수]을 입력하시기 바랍니다", "경고", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Invoke((MethodInvoker)delegate
                {
                    txtGrade.Focus();

                });
                return;
            }

            if (string.IsNullOrEmpty(packet.Memo))
            {
                packet.Memo = " ";
            }

            packet.SendTime = DateTime.Now;

            Debug.WriteLine("{0} : {1} : {2} : {3} : {4}",
                                        packet.Name, packet.Subject, packet.Grade, packet.Memo, packet.SendTime.ToString("yyyy-MM-dd HH:mm:ss.fff"));

            // 2. TcpClient 생성 및 설정
            TcpClient client = new TcpClient(txtServerIP.Text, Convert.ToInt32(txtServerPort.Text));
            NetworkStream stream = client.GetStream();
            updateStatusInfo(string.Format("[{0}] Connected", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));

            // 3. 전송하기
            IFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, packet);

            updateStatusInfo(string.Format("[{0}] {1} bytes data sent", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), SizeOf(packet)));

            // 4. 스트림과 소켓 닫기
            stream.Close();
            client.Close();

            updateStatusInfo(string.Format("[{0}] Disconnected", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));

            // 5. listview 에 추가하기
            Invoke((MethodInvoker)delegate
            {
                int count = listView1.Items.Count;
                count++;

                ListViewItem i = new ListViewItem();
                i.Text = count.ToString();
                i.SubItems.Add(txtName.Text);
                i.SubItems.Add(txtSubject.Text);
                i.SubItems.Add(txtGrade.Text);
                i.SubItems.Add(txtMemo.Text);
                i.SubItems.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                listView1.Items.Add(i);

                listView1.Items[this.listView1.Items.Count - 1].EnsureVisible();
            });
        }

        private void updateStatusInfo(string content)
        {
            Action del = delegate()
            {
                listBox1.Items.Add(content);
            };
            Invoke(del);
        }

        public static long SizeOf(object obj)
        {
            long size = 0;

            try
            {
                System.IO.MemoryStream stream = new System.IO.MemoryStream();
                BinaryFormatter objFormatter = new BinaryFormatter();
                objFormatter.Serialize(stream, obj);
                size = stream.Length;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception : {0}", ex.Message);
            }

            return size;
        }


posted by 따시쿵
2015. 1. 28. 17:05 C# with TCP/IP

프로그램 설명


이번 예제는 Binary Serialization / Deserialization 을 이용한 통신 방법을 설명합니다.


클래스에 property 로 5개 필드(Name, Subject, Grade, Memo, SendTime)를 정의 합니다. SendTime 필드는 전송하는 클라이언트의 전송 시각을 기입하고, 서버에서 메시지를 받아서 네트워크 지연 시간을 확인 해 보기 위한 용도로 추가 했습니다.


3개의 프로젝트가 필요합니다.


1. 공통 라이브러리 

   ==> 클라이언트와 서버에서 사용할 클래스

   ==> 클래스 이름 위에 [Serializable] 특성을 기입하는 게 중요함.

   ==> DataPacket.cs


2. 클라이언트 프로그램


3. 서버 프로그램



실행 후

메시지 전송 후



프로그램 작성 순서


1. 공통 라이브러리 (Common Libray) 

클라이언트와 서버에서 사용할 어셈블리 코드


    [Serializable]
    public class DataPacket
    {
        public string Name { get; set; }
        public string Subject { get; set; }
        public Int32 Grade { get; set; }
        public string Memo { get; set; }
        public DateTime SendTime { get; set; }
    }

 


2. 서버 프로그램


        static void Main(string[] args)
        {
            TcpListener server = null;
            try 
            { 
                server = new TcpListener(IPAddress.Parse("192.168.0.12"), 13000);
                server.Start();

                while (true)
                {
                    Console.WriteLine("Waiting for a connection.....");

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

                    if (client.GetStream().CanRead)
                    {
                        NetworkStream stream = client.GetStream();
                        IFormatter formatter = new BinaryFormatter();

                        DataPacket packet = new DataPacket();
                        packet = (DataPacket)formatter.Deserialize(stream);

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

                        TimeSpan time = DateTime.Now - SendTime;
   
                        Console.WriteLine("이 름 : {0}", Name);
                        Console.WriteLine("과 목 : {0}", Subject);
                        Console.WriteLine("점 수 : {0}", Grade);
                        Console.WriteLine("메 모 : {0}", Memo);
                        Console.WriteLine("지연된 시간 : {0}.{1} seconds", time.Seconds.ToString(), time.Milliseconds.ToString());
                        Console.WriteLine("");
                        Console.WriteLine("===========================================");
                        Console.WriteLine("");
                        
                        stream.Close();
                        client.Close();
                    }
                }
            }
            catch (SocketException se)
            {
                Console.WriteLine("SocketException : {0}", se.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception : {0}", ex.Message);
            }
            finally
            {
                server.Stop();
            }
        }

 


3. 클라이언트 프로그램


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

                do
                {
                    // 1. 데이타 입력
                    Console.Write("이름 : ");
                    Name = Console.ReadLine();

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

                    Console.Write("점수 : ");
                    string tmpGrage = Console.ReadLine();
                    if (tmpGrage != "")
                    {
                        int outGrade = 0;
                        if (Int32.TryParse(tmpGrage, out outGrade))
                            Grade = Convert.ToInt32(tmpGrage);
                        else
                            Grade = 0;
                    }
                    else
                        Grade = 0;

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

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

                    // 2. 구조체 데이타를 바이트 배열로 변환
                    DataPacket packet = new DataPacket();
                    packet.Name = Name;
                    packet.Subject = Subject;
                    packet.Grade = Grade;
                    packet.Memo = Memo;
                    packet.SendTime = DateTime.Now;
                    Debug.WriteLine("{0} : {1} : {2} : {3} : {4}",
                                        packet.Name, packet.Subject, packet.Grade, packet.Memo, packet.SendTime.ToString("yyyy-MM-dd HH:mm:ss.fff"));

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

                    NetworkStream stream = client.GetStream();

                    IFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(stream, packet);

                    Console.WriteLine("{0} bytes data sent\n", SizeOf(packet));

                    // 4. 스트림과 소켓 닫기
                    stream.Close();
                    client.Close();
                } while (Name != "" && Subject != "");

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

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

        public static long SizeOf(object obj)
        {
            long size = 0;

            try
            {
                System.IO.MemoryStream stream = new System.IO.MemoryStream();
                BinaryFormatter objFormatter = new BinaryFormatter();
                objFormatter.Serialize(stream, obj);
                size = stream.Length;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception : {0}", ex.Message);
            }

            return size;
        }

 


posted by 따시쿵