지난번에 1:1 소켓프로그래밍으로 채팅 프로그램을 만들어보았습니다.


참고 : http://yeolco.tistory.com/31


이번 시간에는 1:n 비동기 방식 채팅프로그램을 만들어보겠습니다.


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






실행화면


3명의 사용자가 동시에 사용했을때




잘 작동하는 화면입니다.





사용자 1명이 나가고 새로운 사용자가 서버에 접속하는 화면입니다.




◎ Server쪽 소스코드입니다.


using System;

using System.Collections.Generic;

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Threading;

using System.Windows.Forms;


namespace SIMT_CHATTING_SERVER

{

    public partial class Form1 : Form

    {

        TcpListener server = null; // 서버

        TcpClient clientSocket = null; // 소켓

        static int counter = 0; // 사용자 수

        string date; // 날짜 

        // 각 클라이언트 마다 리스트에 추가

        public Dictionary<TcpClient, string> clientList = new Dictionary<TcpClient, string>();


        public Form1()

        {

            InitializeComponent();

            // 쓰레드 생성

            Thread t = new Thread(InitSocket);

            t.IsBackground = true;

            t.Start();

        }


        private void InitSocket()

        {

            server = new TcpListener(IPAddress.Any, 9999); // 서버 접속 IP, 포트

            clientSocket = default(TcpClient); // 소켓 설정

            server.Start(); // 서버 시작

            DisplayText(">> Server Started");


            while (true)

            {

                try

                {

                    counter++; // Client 수 증가

                    clientSocket = server.AcceptTcpClient(); // client 소켓 접속 허용

                    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("$")); // client 사용자 명


                    clientList.Add(clientSocket, user_name); // cleint 리스트에 추가


                    SendMessageAll(user_name + " 님이 입장하셨습니다.", "", false); // 모든 client에게 메세지 전송


                    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) { break; }

                catch (Exception ex) { break; }

            }


            clientSocket.Close(); // client 소켓 닫기

            server.Stop(); // 서버 종료

        }


        void h_client_OnDisconnected(TcpClient clientSocket) // cleint 접속 해제 핸들러

        {

            if (clientList.ContainsKey(clientSocket))

                clientList.Remove(clientSocket);

        }


        private void OnReceived(string message, string user_name) // cleint로 부터 받은 데이터

        {

            if(message.Equals("leaveChat")) {

                string displayMessage = "leave user : " + user_name;

                DisplayText(displayMessage);

                SendMessageAll("leaveChat", user_name, true);

            }

            else {

                string displayMessage = "From client : " + user_name + " : " + message;

                DisplayText(displayMessage); // Server단에 출력

                SendMessageAll(message, user_name, true); // 모든 Client에게 전송

            }

        }


        public void SendMessageAll(string message, string user_name, bool flag)

        {

            foreach (var pair in clientList)

            {

                date = DateTime.Now.ToString("yyyy.MM.dd. HH:mm:ss"); // 현재 날짜 받기


                TcpClient client = pair.Key as TcpClient;

                NetworkStream stream = client.GetStream();

                byte[] buffer = null;


                if (flag)

                {

                    if(message.Equals("leaveChat"))

                        buffer = Encoding.Unicode.GetBytes(user_name + " 님이 대화방을 나갔습니다.");

                    else

                        buffer = Encoding.Unicode.GetBytes("[ " + date + " ] " + user_name + " : " + message);

                }

                else

                {

                    buffer = Encoding.Unicode.GetBytes(message);

                }


                stream.Write(buffer, 0, buffer.Length); // 버퍼 쓰기

                stream.Flush();

            }

        }


        private void DisplayText(string text) // Server 화면에 출력

        {

            if (textBox1.InvokeRequired)

            {

                textBox1.BeginInvoke(new MethodInvoker(delegate

                {

                    textBox1.AppendText(text + Environment.NewLine);

                }));

            }

            else

                textBox1.AppendText(text + Environment.NewLine);

        }

    }

}




◎ Client쪽 소스코드입니다.


using System;

using System.Net.Sockets;

using System.Text;

using System.Threading;

using System.Windows.Forms;


namespace Chatting

{

    public partial class Form2 : Form

    {

        TcpClient clientSocket = new TcpClient(); // 소켓

        NetworkStream stream = default(NetworkStream); 

        string message = string.Empty;


        public Form2()

        {

            InitializeComponent();

        }


        private void Form2_Load(object sender, EventArgs e)

        {

            try

            {

                clientSocket.Connect("192.168.0.31", 9999); // 접속 IP 및 포트

                stream = clientSocket.GetStream();

            }

            catch (Exception e2)

            {

                MessageBox.Show("서버가 실행중이 아닙니다.", "연결 실패!");

                Application.Exit();

            }


            message = "채팅 서버에 연결 되었습니다.";

            DisplayText(message);


            byte[] buffer = Encoding.Unicode.GetBytes(Form1.nickname + "$");

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

            stream.Flush();


            Thread t_handler = new Thread(GetMessage);

            t_handler.IsBackground = true;

            t_handler.Start();

        }


        private void button1_Click(object sender, EventArgs e) // 메세지 보내기

        {

            textBox2.Focus();

            byte[] buffer = Encoding.Unicode.GetBytes(textBox2.Text + "$");

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

            stream.Flush();

            textBox2.Text = "";

        }


        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) // Server에 메세지 출력

        {

            if (textBox1.InvokeRequired)

            {

                textBox1.BeginInvoke(new MethodInvoker(delegate

                {

                    textBox1.AppendText(text + Environment.NewLine);

                }));

            }

            else

                textBox1.AppendText(text + Environment.NewLine);

        }


        private void textBox2_KeyUp(object sender, KeyEventArgs e)

        {

            if (e.KeyCode == Keys.Enter) // 엔터키 눌렀을 때

                button1_Click(this, e);

        }


        private void Form2_FormClosing(object sender, FormClosingEventArgs e) // 폼 닫을 때 실행

        {

            byte[] buffer = Encoding.Unicode.GetBytes("leaveChat" + "$");

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

            stream.Flush();

            Application.ExitThread();

            Environment.Exit(0);

        }

    }

}





정보가 유익하셨다면 아래 공감버튼 눌러주시면 감사하겠습니다.

질문사항은 댓글로 달아주시면 성의껏 답변해드리겠습니다.


C# DB연동



C#에서 MySQL DataBase 연동하는 방법입니다.


먼저 C# 프로그램에서 MySQL과 연동하기 위해서는 Connector가 필요합니다.


아래 링크로 들어가 다운받아 줍니다.


https://dev.mysql.com/downloads/connector/net/8.0.html


설치가 완료되었으면 Visual Studio를 실행하고


C# - Windows Forms 앱을 만들어 줍니다. (저는 프로젝트 명을 DBConnectionTest 라고 지었습니다.)


그리고 아래와 같이 솔루션 탐색기의 참조를 우클릭하여 참조 추가(R)를 선택합니다.





아래와 같은 참조 관리자가 실행되는데 우측 상단에 검색란에 mysql이라고 검색합니다.


(만약 MySql.Data가 나타나지 않는다면 아랭의 찾아보기(B)를 눌러 위에서 설치한 Connect의 경로를 추가합니다)





참고로 제 데이터베이스 테이블입니다.


테이블 구조입니다.




데이터는 하나만 추가했습니다.






다시 Visual Studio로 와서 최상단에 아래와 같이 입력합니다.


using MySql.Data.MySqlClient;


참조했던 MySql.Data를 사용하겠다는 뜻입니다.


그리고 Form1 안에 아래와 같이 변수를 선언해줍니다.


public static String url = "SERVER=LOCALHOST; USER=; DATABASE=;" + 

            "PORT=3306; PASSWORD=; SSLMODE=NONE";

        // DB접속 URL 설정 - SERVER : DB주소, USER : ID명, DATABASE : DB명, PORT : TCP 포트번호

        // PASSWORD : 비밀번호, SSLMODE : NONE (SSL 사용안함)

private MySqlConnection mConnection; // DB접속

private MySqlCommand mCommand; // 쿼리문

private MySqlDataReader mDataReader; // 실행문


기본 설명은 주석으로 처리하였습니다.


Form1.cs[디자인]에서 폼을 더블클릭하여 Form1_Load를 생성하여 아래와 같이 작성합니다.


또한 TextBox도 하나 생성해줍시다.


private void Form1_Load(object sender, EventArgs e)

{

    mConnection = new MySqlConnection(url); // DB접속

    mCommand = new MySqlCommand(); // 쿼리문 생성

    mCommand.Connection = mConnection; // DB에 연결


    mCommand.CommandText = "SELECT * FROM TEST"; // 쿼리문 작성

    mConnection.Open(); // DB 오픈

    mDataReader = mCommand.ExecuteReader(); // 쿼리문 실행


    while (mDataReader.Read()) // 전부 다 읽어 옴

    {

        // 여기서 부터 원하는 데이터를 받아와서 처리

        string tempName = mDataReader["name"].ToString();

        string tempPhone = mDataReader["phone"].ToString();

        string tempAge = mDataReader["age"].ToString(); 


        textBox1.AppendText("이름 : " + tempName + "\n");

        textBox1.AppendText("전화번호 : " + tempPhone + "\n");

        textBox1.AppendText("나이 : " + tempAge + "\n");

    }


    mConnection.Close(); // 사용 후 객체 닫기

}


아래는 전체 코드입니다.


using MySql.Data.MySqlClient;

using System;

using System.Windows.Forms;


namespace DBConnectionTest

{

    public partial class Form1 : Form

    {

        public static String url = "SERVER=LOCALHOST; USER=; DATABASE=;" + 

            "PORT=3306; PASSWORD=; SSLMODE=NONE";

        // DB접속 URL 설정 - SERVER : DB주소, USER : ID명, DATABASE : DB명, PORT : TCP 포트번호

        // PASSWORD : 비밀번호, SSLMODE : NONE (SSL 사용안함)

        private MySqlConnection mConnection; // DB접속

        private MySqlCommand mCommand; // 쿼리문

        private MySqlDataReader mDataReader; // 실행문

        

        public Form1()

        {

            InitializeComponent();

        }


        private void Form1_Load(object sender, EventArgs e)

        {

            mConnection = new MySqlConnection(url); // DB접속

            mCommand = new MySqlCommand(); // 쿼리문 생성

            mCommand.Connection = mConnection; // DB에 연결


            mCommand.CommandText = "SELECT * FROM TEST"; // 쿼리문 작성

            mConnection.Open(); // DB 오픈

            mDataReader = mCommand.ExecuteReader(); // 쿼리문 실행


            while (mDataReader.Read()) // 전부 다 읽어 옴

            {

                // 여기서 부터 원하는 데이터를 받아와서 처리

                string tempName = mDataReader["name"].ToString();

                string tempPhone = mDataReader["phone"].ToString();

                string tempAge = mDataReader["age"].ToString(); 


                textBox1.AppendText("이름 : " + tempName + "\n");

                textBox1.AppendText("전화번호 : " + tempPhone + "\n");

                textBox1.AppendText("나이 : " + tempAge + "\n");

            }


            mConnection.Close(); // 사용 후 객체 닫기

        }

    }

}


실행화면입니다.


아래와 같이 데이터베이스에 존재하는 내용을 받아와 출력한 화면입니다.




이외에도 UPDATE, DELETE, INSERT와 같이 쿼리문과 코드만 살짝 수정해서 사용 할 수 있습니다.


지금까지 C#과 MySQL DataBase 연동하는 방법에 대해 알아보았습니다.






정보가 유익하셨다면 아래 공감버튼 눌러주시면 감사하겠습니다.

질문사항은 댓글로 달아주시면 성의껏 답변해드리겠습니다.





API를 사용하다보면 보통 해외에서 만든 소스가 대부분입니다.

따라서 한글을 지원하기도 하고 안하기도 하는데

한글을 지원하더라도 유니코드로 문자열이 처리가 되면 난감합니다.

그래서 이번엔 유니코드를 한글로 변환하는 프로그램을 작성해봤습니다.


- 소스코드


public string uni_to_kr(string uni)

{

     string line;

     uni = uni.ToUpper(); // 문자열을 모두 대문자로 변환

     // 파일 읽기

     System.IO.StreamReader file = new System.IO.StreamReader(@"d:\unicode.txt"); 

     while ((line = file.ReadLine()) != null) // 파일 한 줄 단위로 읽기

     {

          if (line.Contains(uni)) // 입력 한 유니코드가 포함 된 줄이면

          {

               file.Close(); // 파일 닫기

               return line.Split('\t')[1].ToString(); // 한글 문자열 반환

          }

     }

     return null;

}


unicode.txt



다음 유니코드가 저장 되어있는 파일을 읽어서 코드를 찾은 후 한글을 반환하는

아주 간단한 소스코드입니다.


질문 사항은 댓글로 달아주세요!




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

C# 기초다지기 - 문자열  (2) 2018.11.07
C# 기초다지기 - 배열  (1) 2018.11.06
C# 기초다지기 - 상수  (0) 2018.11.06
C# 기초다지기 - 캡슐화  (0) 2018.11.05
C# 기초다지기 - 프로그램 구조  (0) 2018.11.05
C# 기초다지기 - 변수  (0) 2018.11.05
C# DB연동  (1) 2018.08.29
[C#] Visual Studio 2017 C# OpenCV 라이브러리 설치  (0) 2018.08.18


안녕하세요 열코입니다!

OpenCV로 영상처리 및 패턴인식을 공부하는 동안 가장 기본적인 자동차 번호판 인식 프로그램을 

간단하게 제작해 보았습니다.


* 개발 환경

개발 툴 : Visual Studio 2017

개발 언어 : C#


* 기능

- IplImage Load(불러오기) 및 Save(저장)

- Web Image Load 및 Save

- Image GrayScale(흑백)

- Image Binary(이진화)

- Image CannyEdge(에지 검출)

- Templet Match 및 ROI(관심 영역 추출)

- Mouse Drag Event로 ROI

- Tesseract-OCR(API)

- OpenALPR(API)


* 소스 코드

전체 소스코드는 300줄가량 되며, 부분 소스코드만 공개하고 설명합니다.


- Binary 함수


1
2
3
4
5
6
7
8
9
IplImage gray = new IplImage(src.Size, BitDepth.U8, 1); // GrayScale 수행
 
Cv.CvtColor(src, gray, ColorConversion.BgrToGray);
 
IplImage bina = new IplImage(src.Size, BitDepth.U8, 1);
 
int temp = trackBar1.Value * 20// track bar 값을 받아와 적절한 수치로 변환
 
Binarizer.SauvolaFast(gray, bina, temp, 0.264); // Sauvola 방법으로 이진화 수행
cs



- Tesseract 함수


1
2
3
4
5
6
7
8
9
Bitmap img = new Bitmap(pictureBoxIpl2.Image);  
 
var ocr = new TesseractEngine("./tessdata""kor", EngineMode.Default);  
 
// ./tessdata : tesseract 문자 인식 훈련 데이터, kor : 한글 or eng : 영문
 
var texts = ocr.Process(img); 
 
textBox1.AppendText(texts.GetText());
cs




- OpenALPR


1
2
3
4
5
6
7
8
9
10
11
12
13
Task<string> recognizeTask = Task.Run(() => ProcessImage(savePath));
 
recognizeTask.Wait();
 
string task_result = recognizeTask.Result;
 
string result = task_result.Split(':')[11].Split(',')[0];
 
result = result.Replace("\"""");
 
result = result.Trim();  // 결과 값을 적절히 파싱
 
textBox1.AppendText(result);
cs





* 실행 화면

프로그램을 실행하면 아래 사진과 같은 화면이 실행됩니다.



Load Image를 눌러 로컬 컴퓨터 내 이미지를 불러오거나 Capture를 눌러 연결된 카메라로 사진을 불러올 수 있습니다. 먼저 Capture를 눌러 사진을 찍어보겠습니다.




제 책상 위의 아이폰을 한번 찍어봤습니다...

캡처된 이미지를 불러오기 성공했다는 로그가 뜨고 화면에 이미지를 불러옵니다.

이 사진은 딱히 패턴인식할 사진이 아니므로 Load Image로 자동차 사진을 불러오겠습니다.



자동차 이미지를 불러왔습니다.

자동차 번호판을 인식해야 하는데 먼저 전처리 과정을 거쳐야 인식률이 많이 높아집니다.

(사진 선명도 및 노이즈를 제거하기 위해 처리하는 과정입니다.)



- GrayScale은 RGB 컬러사진은 흑백 사진으로 변환해주는 버튼입니다.

- CannyEdge는 사진의 Edge(모서리) 영역만 감지하여 나타내주는 버튼입니다.

- Init은 작업한 사진을 초기화하는 버튼입니다.

- Binary Degree는 Track Bar로 구현했습니다. 수치의 degree( 정도) 값에 의해 Binary(이진화) 처리를 해줍니다.



120 degree로 Binary 처리한 결과입니다.

번호판 부분이 선명하게 처리되었습니다.



마우스 이벤트를 이용하여 마우스 드래그를 하여 마우스 X, Y좌표를 받아온 후 좌표 크기만큼 잘라서 따로 표시해줍니다. (패턴 인식 알고리즘 속도 향상을 위해)



패턴인식 알고리즘은 2가지를 사용했습니다.

Logic 1은 Open Library인 Tesseract 알고리즘을 사용했고,

Logic 2는 OpenALPR API를 사용했습니다.

(OpenALPR은 유료 라이브러리로 2000회 무료로 사용 가능합니다.) 

두 라이브러리 모두 인식률은 상용적으로 사용할 정도로 높진 않았습니다.



하지만 전처리 과정과 알고리즘 수정을 통해 어느 정도 인식률을 높이는 것이 가능합니다.

Logic 1 버튼을 눌러 결과를 확인하니 번호판을 정확히 인식하는 모습입니다.

실행 시간은 두 로직 모두 1~3초 정도 소요합니다. (더 많은 최소화 작업이 필요)  

Templet Match는 미리 저장해 둔 Templet 사진을 통해 기존 사진과 비교하여 번호판을 찾아내는 방법입니다. 번호판 모양이 제각각이기 때문에 인식률이 많이 낮았습니다.



Logic 2(OpenALPR) 실행 결과입니다.

실행 시간은 Logic 1(Tesseract) 조금(0.5초~1초) 더 걸리는 정도였습니다.

OpenALPR 홈페이지에서 데모 프로그램 실행 시 한글 인식이 잘 되는 걸로 확인했는데

소스코드로 구현하니 한글 인식이 안되는 걸로 나옵니다... (아시는 분 댓글로 부탁드립니다)


* 수정

- OpenALPR 한글지원 가능합니다.

PostAsync에서 API주소에 country를 us에서 kr로 변경하면 한글도 인식됩니다.

한글을 unicode로 처리하기 때문에 한글이 \ud638 이런식으로 출력됩니다.

유니코드를 한글로 변경하는 알고리즘을 따로 구현하여 처리하였습니다.


유니코드 한글로 변환하기


또 다른 차량 번호판 인식 결과입니다.



다른 차량 역시 번호판을 잘 인식하는 모습입니다.

위 사진처럼 깨끗하고 깔끔하게 번호판이 나온 경우 따로 전처리 작업을 해주지 않아도 인식하는 모습입니다.


알고리즘 및 전처리 과정을 수정하여 실시간 CCTV에서 번호판 인식이 가능하고, 자율 주행 자동차에서 도로 인식 및 표지판, 신호등을 인식하는 알고리즘을 만들어 볼 수 있겠네요




질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.







TCP/IP 는 패킷 통신 방식으로 IP(인터넷 프로토콜)와 TCP(전송제어 프로토콜)로 구성되어있습니다.

이번에는 C#으로 TCP/IP 통신 프로그램을 이용하여 간단한 채팅프로그램을 만들어보겠습니다.




* 개발 환경

개발 툴 : Visual Studio 15.0(2017)

개발 언어 : C#


* 소스 코드(서버)


TcpListener Server; // 소켓 서버

TcpClient Client; // 클라이언트

StreamReader Reader; 

StreamWriter Writer; 

NetworkStream stream; // 네트워크 스트림 연결

Thread ReceiveThread; 

bool Connected;

private delegate void AddTextDelegate(string strText); // 크로스 쓰레드 호출


public Form1()

{

     InitializeComponent();

}


private void Form1_Load(object sender, EventArgs e)

{

     Thread ListenThread = new Thread(new ThreadStart(Listen)); // 서버 시작

     ListenThread.Start();

}


private void button1_Click(object sender, EventArgs e) // 보내기 버튼

{

     textBox1.AppendText("Me : " + textBox2.Text + "\r\n"); // 화면에 출력

     Writer.WriteLine(textBox2.Text); // 보내버리기

     Writer.Flush();

     textBox2.Clear(); 

}


private void Form1_FormClosing(object sender, FormClosingEventArgs e) // 폼 종료

{

     Connected = false;

     if (Reader != null) Reader.Close();

     if (Writer != null) Writer.Close();

     if (Server != null) Server.Stop();

     if (Client != null) Client.Close();

     if (ReceiveThread != null) ReceiveThread.Abort(); // 사용한 객체를 모두 닫아준다

}


private void Listen() // 클라이언트와 연결하기

{

     AddTextDelegate AddText = new AddTextDelegate(textBox1.AppendText);

     IPAddress addr = new IPAddress(0); // 서버 ip

     int port = 8080; // 서버 포트

     Server = new TcpListener(addr, port);

     Server.Start(); // 서버 시작

     Invoke(AddText, "Server Start!" + "\r\n");

     Client = Server.AcceptTcpClient(); // 클라이언트 연결 수락

     Connected = true;

     Invoke(AddText, "Connected to Client!" + "\r\n");

     stream = Client.GetStream(); // 클라이언트 스트림 값 받아오기

     Reader = new StreamReader(stream);

     Writer = new StreamWriter(stream);

     ReceiveThread = new Thread(new ThreadStart(Receive)); // 값을 받기 위한 쓰레드

     ReceiveThread.Start();

}


private void Receive() // 클라이언트에게 받기

{

     AddTextDelegate AddText = new AddTextDelegate(textBox1.AppendText);

     while(Connected)

     {     

          Thread.Sleep(1);

          if(stream.CanRead) // 받아온 데이터가 있다면 출력

          {

               string tempStr = Reader.ReadLine();

               if(tempStr.Length > 0)

               {

                    Invoke(AddText, "You : " + tempStr + "\r\n");

               }

          }

     }

}



* 소스 코드(클라이언트) - 서버와 거의 비슷함


TcpListener Server;

TcpClient Client;

StreamReader Reader;

StreamWriter Writer;

NetworkStream stream;

Thread ReceiveThread;

bool Connected;


private delegate void AddTextDelegate(string strText);


public Form1()

{

     InitializeComponent();

}


private void Form1_FormClosing(object sender, FormClosingEventArgs e) // 폼 종료

{

     Connected = false;

     if (Reader != null) Reader.Close();

     if (Writer != null) Writer.Close();

     if (Server != null) Server.Stop();

     if (Client != null) Client.Close();

     if (ReceiveThread != null) ReceiveThread.Abort();

}


private void button1_Click(object sender, EventArgs e) // 보내기 버튼

{

     textBox1.AppendText("Me : " + textBox2.Text + "\r\n");

     Writer.WriteLine(textBox2.Text); // 보내버리기

     Writer.Flush();

     textBox2.Clear();

}


private void Form1_Load(object sender, EventArgs e) // 폼 실행

{

     String IP = "192.168.x.x"; // 접속 할 서버 아이피를 입력

     int port = 8080; // 포트

     Client = new TcpClient();

     Client.Connect(IP, port);

     stream = Client.GetStream();

     Connected = true;

     textBox1.AppendText("Connected to Server!" + "\r\n");

     Reader = new StreamReader(stream);

     Writer = new StreamWriter(stream);

     ReceiveThread = new Thread(new ThreadStart(Receive));

     ReceiveThread.Start();

}


private void Receive() // 서버로 부터 값 받아오기

{

     AddTextDelegate AddText = new AddTextDelegate(textBox1.AppendText);

     while (Connected)

     {

          Thread.Sleep(1);

          if (stream.CanRead)

          {

               string tempStr = Reader.ReadLine();

               if (tempStr.Length > 0)

               {

                    Invoke(AddText, "You : " + tempStr + "\r\n");

               }

          }

     }

}



* 실행 화면


서버(좌측), 클라이언트(우측) 실행화면




오류나 질문사항은 댓글로 달아주세요!!




to Top