티스토리 뷰

반응형

다시 클라이언트로 넘어와서 이전에 만든 서버와 연결을 시도해 볼겁니다.

 

기존 프로젝트에서 클라이언트 소켓 클레스를 하나 생성해 줍니다.

 

 

ClientSocket.cs 코드

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

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


namespace AppTEST
{
	class ClientSocket
	{
		private ClientSocket()
		{

		}

		// 해당 클레스를 싱글톤으로 만듭니다.
		private static readonly Lazy<ClientSocket> _instance = new Lazy<ClientSocket>(() => new ClientSocket());

		public static ClientSocket Instance
		{
			get
			{
				return _instance.Value;
			}
		}

		// 소켓 관련 초기화 변수
		Socket mSocket;
		string host = "127.0.0.1";
		int port = 11561;

		// 연결 유무를 확인하기 위한 이벤트 콜백
		public delegate void eventCallback(int _evt);
		eventCallback callbackEvt;

		// 메시지 수신을 받기 위한 이벤트 콜백
		public delegate void receiveData(string _data);
		receiveData callbackMsg;

		// 데이터 수신를 위한 쓰레드
		Thread receiveThread;

		public void connect()
		{
			// 서버와 연결을 위해서 소켓을 생성합니다.
			mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			mSocket.NoDelay = true;

			IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse(host), port);

			try
			{
				mSocket.Connect(endpoint);
			}catch(Exception e)
			{
				callbackEvent((int)-1);
				return;
			}
			// 소켓이 연결 시 이벤트 전송.
			callbackEvent(0);

			// 수신 대기 쓰레드를 생성합니다.
			receiveThread = new Thread(new ThreadStart(receiveFunction));
			receiveThread.Start();
		}
		
		public void addCallBackEvt(eventCallback _evt)
		{
			// 이벤트를 등록합니다.
			callbackEvt = _evt;
		}

		public void callbackEvent(int _evt)
		{
			// 이벤트를 호출합니다.
			callbackEvt(_evt);
		}
		
		public void addCallBackMessage(receiveData _func)
		{
			// 메시지 콜백을 등록합니다.
			callbackMsg = _func;
		}

		public void callbackMessage(string _data)
		{
			// 메시지 콜백을 호출합니다.
			callbackMsg(_data);
		}

		public void sockSendMessage(string _msg)
		{
			// 메시지 전송
			try
			{
				mSocket.Send(Encoding.UTF8.GetBytes(_msg));
			}
			catch(Exception e)
			{
				;
			}
		}

		public void sendNewNick(string _newNick)
		{
			// 닉네임 정보를 전달합니다.
			string msg = "/nick " + _newNick;
			mSocket.Send(Encoding.UTF8.GetBytes(msg));
		}

		public void receiveFunction()
		{
			int res = 0;

			while (true)
			{
				try
				{
					byte[] bytes = new byte[1024];
					res = mSocket.Receive(bytes);
					if(res <= 0)
					{
						mSocket.Close();
					}
					callbackMessage(Encoding.UTF8.GetString(bytes, 0, res));
				}
				catch(Exception e)
				{
					break;
				}
			}
		}
	}
}

 

MainPage.xaml.cs 코드

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// 빈 페이지 항목 템플릿에 대한 설명은 https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x412에 나와 있습니다.

namespace AppTEST
{
    /// <summary>
    /// 자체적으로 사용하거나 프레임 내에서 탐색할 수 있는 빈 페이지입니다.
    /// </summary>
    public sealed partial class MainPage : Page
    {

        string nick;

        public MainPage()
        {
            this.InitializeComponent();
            initView();

        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            // 닉네임 변수가 문자열인지 그리고 비워져 있지는 않은지 확인한다.
            if (e.Parameter is string && !string.IsNullOrWhiteSpace((string)e.Parameter))
            {
                //list_attend.Text += e.Parameter.ToString() + "\r\n";
                nick = e.Parameter.ToString();
            }
            else
            {
                //list_attend.Text += "알수 없음\r\n";
                nick = "알 수 없음";
            }

            ClientSocket.Instance.addCallBackEvt(eventConnect);
            ClientSocket.Instance.addCallBackMessage(receiveCallback);
            ClientSocket.Instance.connect();
            base.OnNavigatedTo(e);
        }

        private void initView()
        {
            // 텍스트 박스 초기화
            chattingView.Text = "";

            // 텍스트박스에 세로 스크롤 바 적용
            ScrollViewer.SetVerticalScrollBarVisibility(chattingView, ScrollBarVisibility.Auto);

            //참여자 리스트 초기화
            list_attend.Text = "";

            // 텍스트박스에 세로 스크롤 바 적용
            ScrollViewer.SetVerticalScrollBarVisibility(list_attend, ScrollBarVisibility.Auto);

            input_text.Text = "";
        }

        private void btn_Change_Click(object sender, RoutedEventArgs e)
        {
            // 채팅 메시지에 적용
            //chattingView.Text += input_text.Text + "\r\n";

            ClientSocket.Instance.sockSendMessage(input_text.Text);
            // 입력된 값은 지워주자.
            input_text.Text = "";
        }

        public void eventConnect(int _evt)
        {
            if (_evt == 0)
            {
                chattingView.Text += "서버에 접속되었습니다.\r\n";
                ClientSocket.Instance.sendNewNick(nick);
            }
            else
            {
                chattingView.Text += "서버 접속에 실패하였습니다.ERROR:" + _evt + "\r\n";
            }
        }

        public void receiveCallback(string _msg)
        {
            int index = 0;

            if(_msg.Length == 0)
			{
                updateNewMssageAsync("서버와의 연결이 끊어졌습니다.\r\n");
                return;
            }

            updateNewMssageAsync(_msg);

            if (_msg.IndexOf(":") > -1)
            {
                ;
            }
            else
            {
                index = _msg.IndexOf("님이 입장 하였습니다.");
                if (index > -1)
                {
                    string newMember = _msg.Substring(0, index);
                    updateNewMemberAsync(newMember, index);
                }
            }
        }

        public async System.Threading.Tasks.Task updateNewMemberAsync(string _msg, int _index)
        {
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                //UI code here
                string newMember = _msg.Substring(0, _index);
                list_attend.Text += newMember + "\r\n";
            });
        }

        public async System.Threading.Tasks.Task updateNewMssageAsync(string _msg)
        {
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                //UI code here
                chattingView.Text += _msg + "\r\n";
            });
        }
    }
}

 

이제 실행해 봅니다.

 

 

 

앱 실행이 두개가 안되네요, 다른 TCP 프로그램을 사용해서 확인해 봅시다.

 

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함