ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 소켓 프로그래밍 (네트워크) #2
    C# 예제 공부일기 2020. 7. 29. 20:01

    Socket클래스

    예제(1)

     Socket Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    소켓클래스의 생성자에는 주소모음(IPv4), 소켓형식(Stream:TCP 데이터 보내는 형식), 프로토콜형식(TCP)위와 같이 정의한다.  위와 같이 생성된 Socket클래스에서 생성된 Server객체는

    Server.Bind(new IPEndPoint(IPAddress.Any, 7000));

    Server 소켓에 IP주소와 포트번호를 묶는다. 여기서 IPAddress.Any는  아무 Ip주소나 7000번으로 들어오는 클라이언트를 저장한다.

    Server.Listen(100);

    Server에는 받은 클라이언트의 IP주소가 저장이 될건데 그렇다면 무작위로 클라이언트를 받는 것은 아니다. Listen에서 100은 최대 대기열 숫자를 의미하고,  보류 중인 연결 큐의 최대 길이이다.. 100개를 포함시킨다는 얘기가 아니라, 대기열을 말하는 것이다.

     

    Socket Client = Server.Accept();
                Console.WriteLine("Client Incomming");

    Server에 저장되어있는 받은 클라이언트를 Socket Client라는 객체에 저장한다. 이러한 구조는 클라이언트를 받아들이는 Socket 따로 받은 클라이언트를 처리하는 Socket이 따로 있는 2중구조이다.

     

    byte[] Buffer = new byte[] { 65, 66, 67, 68 };
                Client.Send(Buffer);
                
    
                Client.Close();
                Server.Close();

    처리할 클라이언트에 65.66.67.68을 보낸다. 그러면 클라이언트 창에서는 아스키코드 값인 ABCD가 출력이 될 것이고 Close에 의해 프로그램이 종료된다..

     

    예제(2)

     

    또 다른 Server와 클라이언트 간의 통신 예제

     

    1.서버

    Socket Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    Server.Bind(new IPEndPoint(IPAddress.Any, 7000));
    //Server.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.105"), 7000));

    위의 예제와 마찬가지로 Server 소켓 객체를 만들고 들어올 클라이언트의 Ip주소를 7000번 포트로 받는다.

    Server.Listen(100);
    Socket Client = Server.Accept();

    Listen에서 100은 최대 대기열 숫자를 의미하고,  보류 중인 연결 큐의 최대 길이이다. 

    그리고 서버로 받은 클라이언트 하나를 Socket Client에 저장시킨다.

     

     IPEndPoint SocketInfo = (IPEndPoint)Client.RemoteEndPoint;
    Console.WriteLine(Client.RemoteEndPoint);
    Console.WriteLine($"Client : {SocketInfo.Address.ToString()}:{SocketInfo.Port.ToString()}");

    받은 클라이언트의 Ip주소와 포트가 궁금해서 추가한 부분이다. Client의 IP와 포트를 IPEndPoint형식으로 캐스트해서 SocketInfo에 저장하고, Address부분과 port부분을 출력한다.

     

    byte[] Buffer = new byte[1024];
    
    int number = Client.Receive(Buffer); // blocking함수
    Console.WriteLine(Encoding.UTF8.GetString(Buffer, 0, number));
    
    //한글을 보내보자
    Buffer = Encoding.UTF8.GetBytes("집에 가기 15분전!");
    Client.Send(Buffer);

    Send와 Receive는 byte[]형식밖에 오고가지 못한다. 일단 byte[]자료형으로 생성된 Buffer에 클라이언트가 보낸 메세지를 받는다. 이때 Client.Receive의 반환타입은 int인데 number에 buffer가 보낸 자료의 길이가 저장되게 된다. 그리고 byte형식을 출력해서 내가 보기 위해서 Encoding.UTF8.GetString 을 사용한다.

    매개변수가 위와 같이 (출력할 문자열, 시작 위치, 글자 수)를 의미하는데, byte형식을 어떻게 글자모양으로 출력할 것인가를 해결해주는 메서드가 위 메서드이다. byte형식을 string으로 바꿔준다.

     

    그 밑의 Buffer에 이젠 서버가 클라이언트로 보내고싶은 메세지를 입력한 다음 Encoding.UTF8.GetBytes 를 사용해서 바이트로 변환한 후 Client.Send(Buffer)를 통해 전송한다.

     

    2. 클라이언트

    클라이언트는 서버에 비해 간단하다.

    Socket Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                   
    Server.Connect(new IPEndPoint(IPAddress.Parse("192.168.0.105"), 7000)); //접속접속 해당 IP와 포트번호로

    Server생성 부분은 위와 같고 Server에 접속하기 위해 Server의 IP주소와 포트번호로 접속한다.

    .Connect란 부분이 Bind와 다르다. 위에서는 192.168.0.105:7000에 접속할래 라는 뜻이다.

     

    byte[] Buffer = Encoding.UTF8.GetBytes("비가 오는 날엔 소세지빵");
    Server.Send(Buffer);
    
    Buffer = new byte[1024];
    
    int number = Server.Receive(Buffer); // blocking함수
    Console.WriteLine(Encoding.UTF8.GetString(Buffer, 0, number));

    위에서 스트링을 바이트형식으로 변환하고 Buffer에 저장한다. 그리고 일단 "비가 오는 날엔 소세지빵"이란 문자열이 byte형식으로 저장된 Buffer를 먼저 보내고, Buffer를 새로 생성한다. 그리고 서버가 보낸 "집에 가기 15분전!" 이라는 byte형식을 받아서 string으로 변환해서 화면에 띄운다.

     

    위는 서버고 아래는 클라이언트이다. 여기서 클라이언트는 분명 7000번 포트로 접속했는데 포트번호가 14582가 되어있는 이유는 한번 Accept된 클라이언트에는 임의의포트번호를 배정해준다. 7000번 포트로 다른 클라이언트가 접속할 수 있기 때문이다.

Designed by Tistory.