본문 바로가기
wpf/c#, wpf 채팅프로그램

c# 채팅프로그램 만들기 - 1 - 소켓통신(TcpListener, TcpClient)을 이용한 간단한 1:1 통신을 해보자(동기서버, 클라이언트, 단발성)

by devjh 2020. 5. 25.
반응형

c# 채팅프로그램을 검색해보면 좋은자료가 많긴 하지만 설명이 부족해 처음 접근할때 난이도가 너무 높거나

 

한두개의 게시글만 올리고 완성품이 없는경우도 많아 아쉬운적이 많았습니다.

 

그래서 최대한 쉽게 c#과 wpf를 통해 채팅프로그램을 구현해 포스팅하려고합니다.

 

c#은 윈도우애플리케이션을 만들때 많이 사용되고(윈폼, WPF) 윈도우앱은 장비나 병원등에서 많이 사용되며

 

장비들과의 인터페이스로는 소켓통신을 많이 사용하니 만들어보시면 도움이 되실 것 같습니다.

 

Tcpclient와 TcpListener를 통해 구현 할 예정이며(개념만 알면 Socket클래스도 거의 비슷합니다)

 

총 12개의 게시글로 구현할 예정입니다.

 

첫번째 게시글 : 1:1단발성통신(동기서버 동기클라)

 

두번째 게시글 : 1:1지속성통신(동기서버 완성본 동기 클라이언트)

 

세번째 게시글 : 1:1통신(비동기서버)

 

네번째 게시글: 1:N통신(여기서부터는 여러명을 받아야하므로 당연히 비동기서버입니다.)

 

다섯번째 게시글 : 채팅프로그램 콘솔 서버

 

여섯번째 게시글 : 채팅프로그램 콘솔 클라이언트

 

일곱번째 게시글 : wpf를 통해 View를 구현한 서버

 

여덟번째 게시글 : wpf를 통해 View를 구현한 클라이언트(메인화면 만들기)

 

아홉번째 게시글 : wpf를 통해 View를 구현한 클라이언트(로그인화면 만들기)

 

열번째 게시글 : wpf를 통해 View를 구현한 클라이언트(채팅상대 선택화면 만들기)

 

열한번째 게시글 : wpf를 통해 View를 구현한 클라이언트(채팅화면 만들기)

 

열두번째 게시글 : wpf를 통해 View를 구현한 클라이언트(로직 구현)

 

C#에서 소켓통신을 통한 Tcp통신의 방법에는 크게 socket 클래스를 이용하는 방식과

TcpListener, Tcpclient 클래스를 이용하는 방법이 있습니다.

이번 포스팅에서는 비교적 간단한 TcpListener과 Tcpclient를 이용해 1:1 통신을 구현해보겠습니다.

 

1. 서버구현.

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("서버콘솔창 \n\n\n");

        // TcpListener 생성자에 붙는 매개변수는 
        // 첫번째는 IP를 두번째는 port 번호입니다.
        TcpListener server = new TcpListener(IPAddress.Any, 9999);

        // 서버를 시작합니다.
        server.Start();


        // 클라이언트 객체를 만들어 9999에 연결한 client를 받아옵니다
        // 클라이언트가 접속할때까지 서버는 해당구문에서 블락됩니다.
        TcpClient client = server.AcceptTcpClient();


        // NetworkStream 객체를 만들어 client에서 보낸 데이터를 받을 객체를 생성합니다.
        NetworkStream ns = client.GetStream();

        // Socket은 byte[] 형식으로 데이터를 주고받으므로 byte[]형 변수를 선언합니다.
        byte[] byteData = new byte[1024];

        // 클라이언트가 write한 데이터를 읽어옵니다.
        // 아래의 작업 이후에 byteData에는 읽어온 데이터가 들어갑니다.
        // 동기서버의 경우 해당코드에서 읽을데이터가 올때까지 대기합니다.
        ns.Read(byteData, 0, byteData.Length);


        // 출력을 위해 byteData를 string형으로 바꿔줍니다.
        string stringData = Encoding.Default.GetString(byteData);

        Console.WriteLine(stringData);

        server.Stop();
        ns.Close();
    }
}

 

편의를 위해 NetworkStream객체를 따로 만들지 않고 한줄에 표현할 수 있습니다.

TcpClient client = server.AcceptTcpClient();

byte[] byteData = new byte[1024];

client.GetStream().Read(byteData,0,byteData.Length);

Console.WriteLine(Encoding.Default.GetString(byteData));​

앞으로 위의 코드를 이용해 구현 할 예정입니다.

 

아래는 편의를 위해 수정된 코드입니다.

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("서버콘솔창. \n\n\n");

        // TcpListener 생성자에 붙는 매개변수는 
        // 첫번째는 IP를 두번째는 port 번호입니다.
        TcpListener server = new TcpListener(IPAddress.Any, 9999);

        // 서버를 시작합니다.
        server.Start();


        // 클라이언트 객체를 만들어 9999에 연결한 client를 받아옵니다
        // 클라이언트가 접속할때까지 서버는 해당구문에서 블락됩니다.
        TcpClient client = server.AcceptTcpClient();

        // Socket은 byte[] 형식으로 데이터를 주고받으므로 byte[]형 변수를 선언합니다.
        byte[] byteData = new byte[1024];


        // client가 write한 정보를 읽어옵니다.
        // 아래의 작업 이후에 byteData에는 읽어온 데이터가 들어갑니다.
        // 동기서버의 경우 해당코드에서 읽을데이터가 올때까지 대기합니다.
        client.GetStream().Read(byteData,0,byteData.Length);


        // 출력을 위해 string형으로 바꿔줍니다.
        Console.WriteLine(Encoding.Default.GetString(byteData));

        server.Stop();
    }
}

서버에의 기본기능은 다음과 같습니다.

server를 생성해주고 Tcpclient객체를 생성하고 서버에 연결된 클라이언트를 받아와

byte[] 변수를 만들어주고,

GetStream().Read(byte,0,byte.Length)를 이용해 클라이언트가 보낸 byte데이터를 읽어 출력

 

2. 클라이언트 구현

 

클라이언트는 비교적 간단합니다.

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("클라이언트콘솔창. \n\n\n");

        TcpClient client = new TcpClient();

        // 첫번째 매개변수는 접속할 IP
        // 서버가 내 PC에서 돌아가므로 127.0.0.1(자기자신을 나타내는 루프백IP)
        // 두번째 매개변수는 서버에서 설정한 포트번호 를 입력해줍니다.
        client.Connect("127.0.0.1", 9999);

        // "클라이언트 : 접속합니다" 를 stream으로 보내기 위해 byte[]형으로 바꿔줍니다.
        byte[] buf = Encoding.Default.GetBytes("클라이언트 : 접속합니다");

        // 서버에서 Read하는 방식과 비슷한 형식으로 Wirte 시켜줍니다.
        client.GetStream().Write(buf, 0, buf.Length);

        client.Close();
    }
}

 

클라이언트에서의 기본기능은 다음과 같습니다.

connect메서드에 서버의 ip와 포트번호를 입력하여 서버에 접속

보낼 데이터를 byte[] 형식으로 바꿔 GetStream().Write(byte,0,byte.Length) 로 보내기

 

3. 결과화면

 

동기서버클라.zip
0.07MB

 

 

반응형

댓글