🪞.Net Framework/C# Winform

멀티 클라이언트 채팅서버 - C# winform

Mawile 2020. 12. 6.
728x90

 

개발환경 >> Visual Studio

언어 >> C# winform

운영체제 >> Windows10

 


 

안녕하세요

저번 글과의 텀이 꽤 길었습니다 (이제시험기간코앞이라 앞으로는 글이 거의없을겁니다)

이유는 C# winform을 공부했습니다.

2일 만에 소켓을 공부했는데(물론 자바문법을 알고있었고 유니티를 통해 C#기본문법은 익혀둔상태)

C#winform은 ui나 그래픽 같은 것을

c++과 달리 쉽게 구현이 가능해서 그 점이 매우 좋았습니다.

 

또, C++에서 화면 한 장 찍으려고 별 ㅈ... r을 다해서 몇십 줄 채워야 되는데

c#은 그냥 5줄이면 끝나더라고요 ㅋㅋ...

 

쨋든,,

이것을 통해서 저가 그렇게 구현하고 싶었던 여러 개의 클라이언트를 관리하며 특정 클라이언트를 지목해나가면서

해킹이 가능하며 콘솔이 아닌 gui의 다방향해킹 툴을 만들 수 있을 것 같은 느낌이 들더라고요.

 

물론 위 기능은 현재저의 c++실력으로 구현이 가능하지만 스크린샷, 실시간 화면 공유 같은 기능은 c++ api에 약한 저에게로서는 힘듭니다 ㅠㅠ...(C#은 가능할거같음!)

물론 구글링해서 복붙한뒤 짜집기하면 스크린샷도되지만, 저는 개인적으로 복붙을 되게싫어하고

뭔가 나의것이 아니라는생각때문에 찝찝해서 선호하는편은 아닙니다..

 

 

이렇게 된 거 올해 겨울방학은 c++ 드래곤 온라인프로젝트를 잠시 접어둔 채,

그냥 작정하고 C++과 C#, 파이썬 등등 여러 가지 언어를 섞어서 해킹 툴을 만들어보도록 하겠습니다.

(진짜로 작정하고 만들겁니다. 진짜 전문 해킹툴처럼 gui버전은 물론 콘솔버전도 만들겁니다.)

(콘솔관리쪽은C++, gui및 api쪽은 C#, opencv는 파이썬)

 

말이 길었네요 그럼 시작해보도록 하겠습니다!

 

 


[[[   참고자료   ]]]

 

 

[Program C#] 서버-클라이언트 1:N 통신

프로그램 설명 1:1 통신에 이어서 1:N 통신을 다루는 프로그램입니다. 각 클라이언트 소켓마다 쓰레드를 만들어서 통신하는 방법입니다. 실행 후 메신지 전송 후 프로그램 작성 순서 1. 서버 사이

it-jerryfamily.tistory.com

 

'참고'만했으며, 코드는 복붙을 아예안하고

오로지 이분의 소켓메커니즘을 보고

코딩은 저의 이론을 바탕으로 했습니다

 


[[[   소스코드(서버)   ]]]

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Diagnostics;
using System.Drawing.Imaging;

namespace Server
{
    public partial class serverForm : Form
    {
        public serverForm()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Thread thr = new Thread(accept); //쓰레드생성
            thr.IsBackground = true; //데몬쓰레드 선언
            thr.Start(); //시작
            button1.Enabled = false; //버튼끄기
        }

        public void accept()
        {
            TcpClient client; //클라이언트클래스
            TcpListener listener = new TcpListener(IPAddress.Any, 8080); //서버클래스
            client = default(TcpClient); //무슨 메소드인지는 모르겠네요
            listener.Start(); //서버시작

            while (true)
            {
                client = listener.AcceptTcpClient(); //클라이언트 acccept
                clients cList = new clients(); //클라이언트 데이터반환 쓰레드
                cList.set(client, listBox1); //설정+시작
            }
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void button2_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear(); //listBox청소(?)
        }
    }

    class clients {
        TcpClient tcp; //해당쓰레드에서 담당할 클라이언트 객체
        ListBox listBox; //리스트박스를 다른클래스에서 조정하기위해 만든 listBox
        public void set(TcpClient tcp,ListBox listBox)
        {
           this.tcp = tcp;
            this.listBox = listBox;
            Thread thr = new Thread(run);
            thr.IsBackground = true;
            thr.Start();
        }
        public void run()
        {
            byte[] bytes = new byte[1024];
            string str = string.Empty;
            NetworkStream net; //네트워크스트림(소켓상에 데이터가 존재하는곳)

            while (true)
            {
                for(int i=0;i<1024;i++) bytes[i] = 0; //c++로따지면 ZeroMemory(bytes,1024);
                net = tcp.GetStream(); //네트워크스트림 얻어오기
                net.Read(bytes, 0, bytes.Length); //스트림읽기 C++로따지면 recv함수
                str = Encoding.Default.GetString(bytes); //인코딩
                listBox.Items.Add(str); //표시
            }
        }
    }
}

 

 

 

[[[   소스코드(클라이언트)   ]]]

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;

namespace Client
{
    public partial class clientForm : Form
    {
        TcpClient client;
        public clientForm()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                client = new TcpClient(); //연결
                client.Connect("127.0.0.1", 8080); //설정
                button1.Enabled = false;
            } catch (SocketException)
            {
                button1.Enabled = true;
                MessageBox.Show("실패");
            }
            catch (Exception)
            {
                button1.Enabled = true;
                MessageBox.Show("실패");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            byte[] buffer = new byte[1024];
            string str = string.Empty;
            str = textBox1.Text;

            try
            {
                for (int i = 0; i < 1024; i++) buffer[i] = 0; //서버설명과 같음.
                buffer = Encoding.Default.GetBytes(str);
                NetworkStream net = client.GetStream(); //서버설명과 같음.
                net.Write(buffer, 0, buffer.Length); //버퍼에 데이터를 씀 c++로따지면 send함수
                net.Flush(); //버퍼비우기
                textBox1.Clear();
            } catch (SocketException se)
            {
                MessageBox.Show("실패");
            } catch (Exception ee)
            {
                MessageBox.Show("실패");
            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }
    }
}

 

 

 


 

 

C# 멀티 클라이언트 서버는 구현하기 쉽더라고요

구성 방식은 저가 지금까지 써왔던 c++멀티 클라이언트 구현 방식과 매우 유사합니다

 

재미있었고 이런 엄청난 언어가 제 주변에 있었는데 지금까지 안 만져본 것에 대해서 후회합니다 ㅠㅠㅠㅋㅋㅋㅋㅋ

 

밑에는 시연 영상입니다!

 

아또!! 여기서는 서버에서 특정 클라이언트에게 전송하는 기능이없는데

이거는 오늘 시간이없어서 못만들었습니다 나중에 저가 시험이끝나면 그때 이프로그램을 강화해서 또 관련글올리겠습니다.

아직은 정확한건아니지만 List에다가 client담아서 특정번호에있는 client객체를 NetworkStream으로 받아서 보내면

될듯하지만, 아직이론상이고 시행해본게아니라서 정확한건아닙니다.

 

 


[[[   시연 영상   ]]]

 

 

 

 


 

 

그럼 봐주셔서 감사합니다!!

728x90

댓글