(C#) 소켓 프로그래밍 기초
포스트
취소

(C#) 소켓 프로그래밍 기초

소켓 프로그래밍의 기초적인 코드를 짜고 적응해본다.

💻 코드

Server Code

먼저 DNS를 활용해 호스트 이름을 가져와 IP 주소로 바꿔준다.

바꿔준 IP 주소를 가지고 IPEndPoint에 포트번호와 함께 endPoint를 생성한다.

그 다음 소켓 생성을 위해 endPoint와 함께 TCP 모드로 listenSocket을 생성해준다.

1
2
3
4
5
6
7
8
// DNS (Domain Name System)
string host = Dns.GetHostName();
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddress = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddress, 5000);

// 문지기 ( SocketType.Stream, ProtocolType.Tcp 는 거의 묶음으로 사용한다. )
Socket listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);


바인드를 진행하고 최대 대기수를 설정한다.

1
2
3
4
5
6
// 문지기 교육
listenSocket.Bind(endPoint);

// 영업 시작
// backlog = 최대 대기수
listenSocket.Listen(10);


본격적으로 클라이언트의 입장을 받을 준비를 한다.

Accept()를 진행할 동안엔 다음 코드로 넘어가지 않고 무한대기를 한다.

만약 클라이언트가 서버에 접속할 경우 다음 코드가 진행된다.

클라이언트로부터 받을 버퍼를 생성해주고, Receive()를 통해 받아준다.

받은 데이터는 UTF8 인코딩을 해준다.

그 다음 클라이언트에게 입장 됐다고 알려줘야하기 때문에

보내줄 string 버퍼를 생성후 Send()를 진행한다.

모든 용무가 끝났으니 Shutdown(), Close()를 진행한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
while (true)
{
    Console.WriteLine("Listening...");

    // 손님을 입장시킨다. ( 클라이언트가 입장할 때까지 무한 대기 )
    Socket clientSocket = listenSocket.Accept();

    // 받는다
    byte[] recvBuff = new byte[1024];
    int recvBytes = clientSocket.Receive(recvBuff);
    string recvData = Encoding.UTF8.GetString(recvBuff, 0, recvBytes);    // 버퍼, 받을 데이터 시작 위치, 몇 만큼 받을지
    Console.WriteLine($"[From Client] {recvData}");

    // 보낸다
    byte[] sendBuff = Encoding.UTF8.GetBytes("Welcome to LHH Server !!");
    clientSocket.Send(sendBuff);

    // 쫓아낸다
    clientSocket.Shutdown(SocketShutdown.Both);
    clientSocket.Close();
}


혹시 모를 에러가 발생하면 디버깅해줘야 되기 때문에

try, catch 안에 방금 짠 코드를 넣어준다.

[ Source Code (Click) ]
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class Program
{ 
    static void Main(string[] args)
    {
        // DNS (Domain Name System)
        string host = Dns.GetHostName();
        IPHostEntry ipHost = Dns.GetHostEntry(host);
        IPAddress ipAddress = ipHost.AddressList[0];
        IPEndPoint endPoint = new IPEndPoint(ipAddress, 5000);

        // 문지기 ( SocketType.Stream, ProtocolType.Tcp 는 거의 묶음으로 사용한다. )
        Socket listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

        try
        {
            // 문지기 교육
            listenSocket.Bind(endPoint);

            // 영업 시작
            // backlog = 최대 대기수
            listenSocket.Listen(10);

            while (true)
            {
                Console.WriteLine("Listening...");

                // 손님을 입장시킨다. ( 클라이언트가 입장할 때까지 무한 대기 )
                Socket clientSocket = listenSocket.Accept();

                // 받는다
                byte[] recvBuff = new byte[1024];
                int recvBytes = clientSocket.Receive(recvBuff);
                string recvData = Encoding.UTF8.GetString(recvBuff, 0, recvBytes);    // 버퍼, 받을 데이터 시작 위치, 몇 만큼 받을지
                Console.WriteLine($"[From Client] {recvData}");

                // 보낸다
                byte[] sendBuff = Encoding.UTF8.GetBytes("Welcome to LHH Server !!");
                clientSocket.Send(sendBuff);

                // 쫓아낸다
                clientSocket.Shutdown(SocketShutdown.Both);
                clientSocket.Close();
            }
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }
}

Client Code

클라이언트도 서버와 비슷하게 구현된다.

소켓 생성까지는 서버와 같다.

[ Source Code (Click) ]
1
2
3
4
5
6
string host = Dns.GetHostName();
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddress = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddress, 5000);

Socket socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);


클라이언트는 서버에게 입장이 가능한지 물어봐야하기 때문에 Connect()를 진행한다.

그 다음 서버에게 보내고 싶은 메시지를 바이트로 Send() 해준다.

또한 받을 메시지가 있을 수 있으니 충분한 공간의 버퍼 생성 후 Receive() 해준다.

서버에서 나가도록 도와주겠지만 혹시 모르니 Shutdown(), Close()를 진행한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 서버에게 입장 문의
socket.Connect(endPoint);
Console.WriteLine($"Connected To {socket.RemoteEndPoint.ToString()}");

// 보낸다
byte[] sendBuff = Encoding.UTF8.GetBytes("Hello World!!");
int sendBytes = socket.Send(sendBuff);

// 받는다
byte[] recvBuff = new byte[1024];
int recvBytes = socket.Receive(recvBuff);
string recvData = Encoding.UTF8.GetString(recvBuff, 0, recvBytes);
Console.WriteLine($"[From Server] {recvData}");

// 나간다
socket.Shutdown(SocketShutdown.Both);
socket.Close();


이 클라이언트 코드 또한 에러 확인을 위해 try, catch에 넣어준다.

[ Source Code (Click) ]
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
32
33
34
35
36
static void Main(string[] args)
{
    // DNS (Domain Name System)
    string host = Dns.GetHostName();
    IPHostEntry ipHost = Dns.GetHostEntry(host);
    IPAddress ipAddress = ipHost.AddressList[0];
    IPEndPoint endPoint = new IPEndPoint(ipAddress, 5000);

    // 휴대폰 설정
    Socket socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

    try
    {
        // 문지기에게 입장 문의
        socket.Connect(endPoint);
        Console.WriteLine($"Connected To {socket.RemoteEndPoint.ToString()}");

        // 보낸다
        byte[] sendBuff = Encoding.UTF8.GetBytes("Hello World!!");
        int sendBytes = socket.Send(sendBuff);

        // 받는다
        byte[] recvBuff = new byte[1024];
        int recvBytes = socket.Receive(recvBuff);
        string recvData = Encoding.UTF8.GetString(recvBuff, 0, recvBytes);
        Console.WriteLine($"[From Server] {recvData}");

        // 나간다
        socket.Shutdown(SocketShutdown.Both);
        socket.Close();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}

🔍 결과

Server

server

Client

client


💡 참고

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.