Ejemplo n.º 1
0
        /// <summary>
        /// 클라이언트가 보내온 데이터를 기다리고
        /// 정해진 약속에 따라 해석하고 처리하는 함수
        /// </summary>
        /// <param name="sockData">담당 소켓관련 객체</param>
        void ThreadRecv(object sockData)
        {
            SocketData clientData = sockData as SocketData;

            while (true)
            {
                try
                {
                    string data = clientData.sr.ReadLine(); // 클라이언트가 보내올 때까지 무한대기
                    //ProcessPacket(data, clientData);
                    SendAllData(data, clientData);          // 자신을 제외한 나머지 클라이언트에 모두 전송
                    //AddRecvListBox(String.Format("[{0}] {1}", clientData.ip, data));
                }
                catch (Exception ex)    // 거의 99%이상은 접속이 끊어졌을 때 발생한다
                {
                    AddRecvListBox("Exception: " + ex.Message);
                    DeleteClientFromList(clientData);
                    DeleteClientAddressFromListView(clientData);
                    break;
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 접속자를 관리하는 ListView에서 해당 클라이언트를 삭제
        /// </summary>
        /// <param name="client">삭제할 대상 클라이언트 정보</param>
        void DeleteClientAddressFromListView(SocketData client)
        {
            if (clientListView.InvokeRequired)
            {
                // 사용중일 때는 .NET에 등록하게 처리를 맡긴다
                Invoke(delClientAddressFromListView, new object[] { client });
            }
            else
            {
                foreach (ListViewItem lvi in clientListView.Items)
                {
                    string ip   = lvi.SubItems[0].Text;
                    string port = lvi.SubItems[1].Text;

                    if (ip == client.ip && port == client.port)
                    {
                        clientListView.Items.Remove(lvi);
                        break;
                    }
                }
            }
        }
Ejemplo n.º 3
0
 /// <summary>
 /// 데이터를 서버에 보낸 클라이언트를 제외한 나머지 클라이언트한테
 /// 데이터를 모두 전송하는 함수
 /// </summary>
 /// <param name="data">서버에 도착한 데이터</param>
 /// <param name="selfClient">데이터를 서버에 보낸 클라이언트
 ///       null일 경우는 클라이언트에서 수신한 데이터 없이
 ///       서버에서 모든 클라이언트한테 전송하는 경우
 /// </param>
 void SendAllData(string data, SocketData selfClient = null)
 {
     lock (this)
     {
         foreach (SocketData client in clientList)
         {
             if (client != selfClient)
             {
                 if (IsAnonymous)
                 {
                     client.sw.WriteLine(data);
                 }
                 else
                 {
                     string ipData = String.Format("[{0}] {1}", selfClient.ip, data);
                     client.sw.WriteLine(ipData);
                 }
                 client.sw.Flush();  // 즉시 전송해라
             }
         }
     }
 }
Ejemplo n.º 4
0
        /* 구분자 패킷 설계
         * 1) 크게 명령, 구분자, 데이터 3부분으로 나눈다
         * 2) 명령에 따라 데이터를 어떻게 해석할지 정한다
         * 3) 명령이 먼저 나온다
         * 4) 예시
         *    4-1) 명령의 종류 C : 채팅
         *                    S : 정해진 초 이후에 나를 해제
         *                    B : WinForm의 배경색
         *    4-2) 구분자 : |
         *    4-3) C|안녕하세요
         *         S|3
         *         B|Gold
         *         P|100|100
         */

        /// <summary>
        /// 정해진 약속에 따라 패킷을 처리하는 함수
        /// </summary>
        /// <param name="srcData">클라이언트가 보내온 전체 데이터</param>
        /// <param name="sendClient">데이터를 보낸 클라이언트</param>
        void ProcessPacket(string srcData, SocketData sendClient)
        {
            string[] datas = srcData.Split(new char[] { '|' });
            switch (datas[0])
            {
            case "C":
                AddRecvListBox(String.Format("[채팅] [{0}] {1}", sendClient.ip, srcData));
                SendAllData(srcData, sendClient);
                break;

            case "S":
            {
                AddRecvListBox(String.Format("[해제] [{0}] {1}", sendClient.ip, srcData));
                int sec = Int32.Parse(datas[1]);
                // 정해진 초 후에 처리할 스레드에 전달할 인자
                SocketCloseData scd = new SocketCloseData();
                scd.client = sendClient;
                scd.sec    = sec;
                Thread tClose =
                    new Thread(new ParameterizedThreadStart(ThreadClose));
                tClose.Start(scd);
            }
            break;

            case "B":
                AddRecvListBox(String.Format("[배경] [{0}] {1}", sendClient.ip, srcData));
                Color color = Color.FromName(datas[1]);
                this.BackColor = color;
                break;

            case "P":
                AddRecvListBox(String.Format("[좌표] [{0}] {1}", sendClient.ip, srcData));
                SendAllData(srcData, sendClient);
                break;
            }
        }