레이블이 윈도우채팅소스인 게시물을 표시합니다. 모든 게시물 표시
레이블이 윈도우채팅소스인 게시물을 표시합니다. 모든 게시물 표시

2022년 2월 5일 토요일

(C#동영상)C# 윈도우 채팅, 채팅 서버, 멀티쓰레드, 델리게이트, Chatting Server, 자바학원, 닷넷학원, 시샵학원, WPF학원, 스프링학원, JAVA학원, C#학원

  (C#동영상)C# 윈도우 채팅, 채팅 서버, 멀티쓰레드, 델리게이트, Chatting Server, 자바학원, 닷넷학원, 시샵학원, WPF학원, 스프링학원, JAVA학원, C#학원


http://ojc.asia/bbs/board.php?bo_table=LecCsharp&wr_id=416 


(C#동영상)C# 윈도우 채팅, 채팅 서버, 멀티쓰레드, 델리게이트, Chatting Server

(C#동영상)C# 윈도우 채팅, 채팅 서버, 멀티쓰레드, 델리게이트, Chatting Server윈도우 기반 채팅채팅 서버 만들기윈폼 기반의 채팅 프로그램모든 부분이 콘솔 부분의 채팅 프로그램과 유사하다. 쓰

ojc.asia




윈도우 기반 채팅

채팅 서버 만들기










윈폼 기반의 채팅 프로그램


모든 부분이 콘솔 부분의 채팅 프로그램과 유사하다. 쓰레드 처리 부분과 스레드에서 텍스트 박스에 글을 쓰는 부분을 유심히 보도록 하자. 화면 UI는 다음과 같다.


[서버]

 


[클라이언트]


 

[채팅 서버]



1. 프로젝트명 : ChatServer


[Form1.Desigmer.cs]


namespace ChatServer

{

    partial class Form1

    {

        /// <summary>

        ///  Required designer variable.

        /// </summary>

        private System.ComponentModel.IContainer components = null;


        /// <summary>

        ///  Clean up any resources being used.

        /// </summary>

        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>

        protected override void Dispose(bool disposing)

        {

            if (disposing && (components != null))

            {

                components.Dispose();

            }

            base.Dispose(disposing);

        }


        #region Windows Form Designer generated code


        /// <summary>

        ///  Required method for Designer support - do not modify

        ///  the contents of this method with the code editor.

        /// </summary>

        private void InitializeComponent()

        {

            this.txtChatMsg = new System.Windows.Forms.TextBox();

            this.btnStart = new System.Windows.Forms.Button();

            this.lblMsg = new System.Windows.Forms.Label();

            this.SuspendLayout();

            // 

            // txtChatMsg

            // 

            this.txtChatMsg.Location = new System.Drawing.Point(27, 15);

            this.txtChatMsg.Multiline = true;

            this.txtChatMsg.Name = "txtChatMsg";

            this.txtChatMsg.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;

            this.txtChatMsg.Size = new System.Drawing.Size(528, 337);

            this.txtChatMsg.TabIndex = 0;

            // 

            // btnStart

            // 

            this.btnStart.Font = new System.Drawing.Font("맑은 고딕", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);

            this.btnStart.Location = new System.Drawing.Point(340, 367);

            this.btnStart.Name = "btnStart";

            this.btnStart.Size = new System.Drawing.Size(215, 86);

            this.btnStart.TabIndex = 1;

            this.btnStart.Tag = "Stop";

            this.btnStart.Text = "서버 시작";

            this.btnStart.UseVisualStyleBackColor = true;

            this.btnStart.Click += new System.EventHandler(this.btnStart_Click);

            // 

            // lblMsg

            // 

            this.lblMsg.AutoSize = true;

            this.lblMsg.Font = new System.Drawing.Font("맑은 고딕", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);

            this.lblMsg.Location = new System.Drawing.Point(45, 384);

            this.lblMsg.Name = "lblMsg";

            this.lblMsg.Size = new System.Drawing.Size(153, 30);

            this.lblMsg.TabIndex = 2;

            this.lblMsg.Tag = "Stop";

            this.lblMsg.Text = "Server 중지 됨";

            // 

            // Form1

            // 

            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);

            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;


            this.ClientSize = new System.Drawing.Size(596, 479);

            this.Controls.Add(this.lblMsg);

            this.Controls.Add(this.btnStart);

            this.Controls.Add(this.txtChatMsg);

            this.Name = "Form1";

            this.Text = "Form1";

this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form1_FormClosed);

            this.ResumeLayout(false);

            this.PerformLayout();


        }


        #endregion


        private TextBox txtChatMsg;

        private Button btnStart;

        private Label lblMsg;

    }

}




[Form1.cs]


using System.Collections;

using System.Net;

using System.Net.Sockets;

using System.Text;


namespace ChatServer

{

    //서버의 txtChatMsg 텍스트박스에 글을 쓰기위한 델리게이트

    //실제 글을 쓰는것은 Form1클래스의 UI쓰레드가 아닌 다른 스레드인 ClientHandler의 스레드 이기에        

    //ClientHandler의 스레드에서 이 델리게이트를 호출하여 텍스트 박스에 글을 쓴다.


    //(만약 컨트롤을 만든 윈폼의 UI쓰레드가 아닌 다른 스레드에서 텍스트박스에 글을 쓴다면 에러발생)

    delegate void SetTextDelegate(string s);


    public partial class Form1 : Form

    {

        TcpListener chatServer = new TcpListener(IPAddress.Parse("127.0.0.1"), 2022);

        public static ArrayList clientSocketArray = new ArrayList();


        public Form1()

        {

            InitializeComponent();

        }


        //서버 시작/종료 클릭

        private void btnStart_Click(object sender, EventArgs e)

        {

            try

            {

                // 현재 서버가 종료 상태인 경우

                if (lblMsg.Tag.ToString() == "Stop")

                {

                    //채팅서버 시작

                    chatServer.Start();


                    //계속 떠 있으면서 클라이언트의 연결을 기다리는 쓰레드 생성

                    //이 스레드가 실행하는 메소드에서 클라이언트 연결을 받고

                    //생성된 클라이언트 소켓을 clientSocketArray에 담고 새로운 쓰레드를 만들어

                    //접속된 클라이언트 전용으로 채팅을 한다.

                    Thread waitThread = new Thread(new ThreadStart(AcceptClient));

                    waitThread.Start();


                    lblMsg.Text = "Server 시작됨";

                    lblMsg.Tag = "Start";

                    btnStart.Text = "서버 종료";

                }

                else

                {

                    chatServer.Stop();

                    foreach (Socket soket in Form1.clientSocketArray)

                    {

                        soket.Close();

                    }

                    clientSocketArray.Clear();

                    lblMsg.Text = "Server 중지됨";

                    lblMsg.Tag = "Stop";

                    btnStart.Text = "서버 시작";

                }

            }

            catch (Exception ex)

            {

                MessageBox.Show("서버 시작 오류 :" + ex.Message);

            }

        }


        //윈도우 창을 닫을 때

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)

        {

            Application.Exit();

            chatServer.Stop();

        }


        //무한루프로 떠 있으면서 클라이언트 접속을 기다린다.

        private void AcceptClient()

        {

            Socket socketClient = null;

            while (true)

            {

                //Socket 생성 및 연결 대기

                try

                {

                    //연결을 기다리다가 클라이언트가 접속하면 AcceptSocket 메서드가 실행되어

                    //클라이언트와 상대할 소켓을 리턴 받는다.

                    socketClient = chatServer.AcceptSocket();


                    //Chatting을 실행하는 ClientHandler 인스턴스화시키고

                    //접속한 클라이언트 접속 소켓을 할당

                    ClientHandler clientHandler = new ClientHandler();

                    clientHandler.ClientHandler_Setup(this, socketClient, this.txtChatMsg);


                    //클라이언트를 상대하면서 채팅을 수행하는 스레드 생성 후 시작

                    Thread thd_ChatProcess = new Thread(new ThreadStart(clientHandler.Chat_Process));

                    thd_ChatProcess.Start();

                }

                catch (System.Exception)

                {

                    Form1.clientSocketArray.Remove(socketClient); break;

                }

            }

        }


        //텍스트박스에 대화내용을 쓰는 메소드 

        public void SetText(string text)

        {

            //t.InvokeRequired가 True를 반환하면 

            // Invoke 메소드 호출을 필요로 하는 상태고 즉 현재 스레드가 UI스레드가 아님

            //  이때 Invoke를 시키면 UI스레드가 델리게이트에 설정된 메소드를 실행해준다.

            //  False를 반환하면 UI스레드가 좁근하는 경우로 컨트롤에 직접 접근해도 문제가 없는 상태다.

            if (this.txtChatMsg.InvokeRequired)

            {

                SetTextDelegate d = new SetTextDelegate(SetText);  //델리게이트 선언

                this.Invoke(d, new object[] { text });                        //델리게이트를 통해 글을 쓴다.

                                                                              //이경우 UI스레드를 통해 SetText를 호출함

            }

            else

            {

                this.txtChatMsg.AppendText(text);  //텍스트박스에 글을 씀

            }

        }

    }


    public class ClientHandler

    {       

        private TextBox txtChatMsg;

        private Socket socketClient;

        private NetworkStream netStream;

        private StreamReader strReader;

        private Form1 form1;


        public void ClientHandler_Setup(Form1 form1, Socket socketClient, TextBox txtChatMsg)

        {

            this.txtChatMsg = txtChatMsg;   //채팅 메시지 출력을 위한 TextBox

            this.socketClient = socketClient; //클라이언트 접속소켓, 이를 통해 스트림을 만들어 채팅한다.

            this.netStream = new NetworkStream(socketClient);

            Form1.clientSocketArray.Add(socketClient); //클라이언트 접속소켓을 List에 담음

            this.strReader = new StreamReader(netStream);

            this.form1 = form1;

        }


        public void Chat_Process()

        {

            while (true)

            {

                try

                {

                    //문자열을 받음

                    string lstMessage = strReader.ReadLine();

                    if (lstMessage != null && lstMessage != "")

                    {

                        //Form1클래스의 SetText메소드를 호출

                        //SetText에서는 델리게이트를 통해 TextBox에 글을 쓴다.

                        //직접 다른 쓰레드의 TextBox에 값을 쓰면 오류 발생 : Cross-thread operation not valid

                        form1.SetText(lstMessage + "\r\n");


                        byte[] bytSand_Data = Encoding.Default.GetBytes(lstMessage + "\r\n");

                        lock (Form1.clientSocketArray)

                        { foreach (Socket soket in Form1.clientSocketArray) { 

                                NetworkStream stream = new NetworkStream(soket); 

                                stream.Write(bytSand_Data, 0, bytSand_Data.Length); } }

                    }

                }

                catch (Exception ex)

                {

                    MessageBox.Show("채팅 오류 : " + ex.ToString());

                    Form1.clientSocketArray.Remove(socketClient);

                    break;

                }

            }

        }

    }

}



#채팅소스, #채팅강좌, #윈도우채팅소스, #시샵채팅, #콘솔채팅, #자바채팅소스, #닷넷채팅, #닷넷채팅소스, #시샵교육, #닷넷교육, #시샵학원, #닷넷학원, 채팅소스, 채팅강좌, 윈도우채팅소스, 시샵채팅, 콘솔채팅, 자바채팅소스, 닷넷채팅, 닷넷채팅소스, 시샵교육, 닷넷교육, 시샵학원, 닷넷학원, 

(C#교육동영상)C# ADO.NET 실습 ODP.NET/ODAC 설치 오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원

  (C#교육동영상)C# ADO.NET 실습  ODP.NET/ODAC 설치  오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원 https://www.youtube.com/watch?v=qIPU85yAlzc&list=PLxU-i...