[Network 09. 26]02. Chapter2 Socket

2010. 9. 26. 18:34Network

  이론을 넣어서 차근차근 정리할려고 했는데 이론은 솔찍히 알으면 좋긴 하지만 실제 사용하기 어려울수 있으며 그렇기 때문에 실제 네트워크 프로그래밍을 C#으로 작성된 내용으로 정리 해보려 하빈다.

소켓을 생성하기 위해서는 Socket클래스가 사용되며 생성자는 public Socket(socketInformation), public Socket(AdressFamily, SocketType, Protocoltype)두개의 생성자가 잇으며
public Socket(AddressFamily, SocketType, ProtocolType)
-AddressFamily(열거형) : 소켓의 주소 지정 방식을 선택
-SocketType (열거형) : 소켓의 종류를 구분
-ProtocolType(열거형) 프로토콜 종류의 구분

일반적으로 소켓통신을 하기 위해서는 아이피의 종단점이 필요하고 그 아이피 종단점을 구성하기 위해서 IPEndPoint클래스 객체를 생성하여 IP 종단점을 정의하며 그 생성자는
-public IPEndPoint(long, int)
-public IPEndPoint(IPAddress, int) 여기서 두번째 인자는 포트번호로써 0-65536의 범위까지 포트번호로 지정할 수 있다.

IPAddress 특수 IP주소

 Field Description  Version 
 IPAddress.Any  Listen for every interface   ipv4
 IPAddress.Broadcast  Broadcast address  ipv4 
 IpAddress.Ipv6Any   Listen for every interface   ipv6
 IPAddress.Ipv6Loopback  Loopback address   ipv6
 IpAddress.IPv6None  Do not listen for client   ipv6
 IPAddress.Loopback  Loopback address  ipv4
 IPAddress.None  Do not listen for client  ipv4

Socket 클래스의 메소드

 public void Bind(EndPoint)  종단점에 소켓을 바인딩
 public void Listen(int)  클라이언트로부터의 접속요청을 대기
 public void Connect(EndPoint)  서버에 접속을 시도
 public Socket Accept()  큐에 대기하고 있는 접속 요청을 수락
 public void Close()  소켓을 닫고 리소스 해제
 public int Send(byte[], int, SocketFlags)  데이터 송신-보낸 바이트수를 정수형으로 반환
 public int Receive(byte[])  데이터 수신-받은 바이트 수를 정수형으로 반환

일반적으로 소켓 프로그래밍 하면 제일 먼저 시작하는 에코 프로그램 인데 자기가 쓴 내용이 되돌아 오는 메아리 같은 프로그램이다.

1. 에코서버

첫째. 클래스를 사용하기 위해 C의 include와 비슷한 using으로 Socket클래스를 가장상단에 가져온다.
 using System.Net.Sockets;

둘째. 소켓을 객체를 만들어 준다. 이때 바인딩 하기 위해 종단점도 필요하므로 종단점도 생성해준다.
 Socket sSocket=new Socket(AddressFamily.InterNetwork,
                                                      SocketType.Stream, 
                                                        ProtocolType.Tcp);

 IPEndPoint sEndpoint= new IPEndPoint(IPAddress.Any, 8888);
 sSocket.Bind(sEndpoint);
 sSocket.Listen(1);
다음과 같은 작업을 하면 바인딩된 모습이다.
차례로 설명해보면 위에 소켓 클래스의 객체를 생성하고 그 객체는 내부네트워크망에 소켓 타입의 흐름 마지막으로 보호하기위해 Tcp방법을 사용하는 것으로 되어 있으며 종단점은 접속한 자기자신이 서버이므로 자기자신의 아이피를 가르키기 위해 IPAddress.Any 하고 포트번호를 8888로 하였습니다.

셋째. 이제 클라이언트 작업을 해주어야 하는데 이때도 Socket클래스의 객체를 생성해준다.
 Socket cSocket=sSocket.Accept(); 
이때 서버측의 클라이언트가 접속을 기다리기위해 Accept로 대기해주며 접속된다면 그 정보를 cSocket에 저장한다.

넷째. 이제 받은 내용을 돌리는 부분을 해보자...
string msg="";
byte[] buffer=new byte[256];
int byteRecv=0;
 while(!msg.Equals("Exit"))
{
      byteRecv=cSocket.Receive(buffer);
      msg=Encoding.ASCII.GetString(buffer,0,byteRecv);
      Console.WriteLine("Client>"+message);

      cSocket.Send(buffer,byteRecv,SocketFlags.None);
}
일단 클라이언트쪽이 Exit를 입력하였는지 확인한다. 만약 같다면 에크를 그만 두게 된다. 하지만 아니라면 
클라이언트 에서 보낸 데이터의 크기를 측정하고 그후 메시지의 내용을 인코딩한다 여기서는 아스키 코드로 작성하였기때문에 영문만 사용되며 한글을 입력하였으면 한글이 출력안되고 이상한 문자가 출력된다.
메시지를 인코딩하고 그걸 서버측에서 클라이언트가 뭐가 적혔는지 출력해준다. 출력 후 다시 클라이언트로 그 데이터를 돌려보낸다. 여기서 보낼때 메시지의 내용을 byte코드로 바꾼 내용 내용의 크기 그리고 플래그 비트가 있는지 없는지를 인자값으로 해서 전송한다. 

다섯째. 마지막으로 모든 작업을 마치고 싶어 Exit를 입력했다면 종료한다.
 cSocket.Close();
 sSocket.Close();


2.에코 클라이언트
클라이언트라고 별로 다른 내용이 없다 단지 서버가 없을뿐이며 종단점이 다를 뿐이다.
같은 부분은 제외하고 다른 부분만 작성해 보겠습니다.
 IPEndPoint ip= new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888);
 Socket cSocket.Connect(ip);

일단 종단점은 접속할 서버의 아이피를 입력하고 포트번호를 입력하고 소켓에 종단점을 넣어주면 이제 연결을 하기 위해 신호를 보낸다 그러면 서버쪽에서는 그 신호를 대기 하고 있다 Accept가 그 신호를 받고 받아 들여 연결 시킨다.

while(!msg.Equals("Exit"))
{
     do{
          Console.Write("Message>");
          msg=Console.ReadLine();
     }while(message.Length<1)
     byte[] data=Encoding.ASCII.GetBytes(msg);
     cSocket.Send(data,data.length,SocketFlags.None);
     byteRecv=cSocket.Receive(data);
     msg=Encoding.ASCII.GetString(data,0,byteRecv);
     Console.WriteLine("Server>"+msg);
위와 같이 작성 해놓으면 될 것이다. 하지만 아쉬운점은 다 영문만 된다는 것이다.
이를 또 고쳐보면 위에 Encoding 부분에서 ASCII를 Unicode로 서버랑 클라이언트에 바꿔주면 데이터가 한글도 인식하는 16비트의 유니코드로 인식된다.

추가로 서버에서 클라이언트의 주소를 알고 싶을때 EndPoint를 하나 만들어주고 클라이언트소켓의 정보를 IPEndPoint로 캐스팅하고 주소를 출력하면 클라이언트의 주소를 알수 잇다.
 EndPoint client=(IPEndPoint)cSocket.RemoteEndPoint;
Console.Write(client.Address);

'Network' 카테고리의 다른 글

[Network 11. 03]07. 졸업시험정리  (0) 2010.11.03
[Network 09. 28]05. Chapter5 UDP  (0) 2010.09.28
[Network 09. 27]04. Chapter4 Mulit Threaded Socket  (0) 2010.09.27
[Network 09. 27]03. Chapter3 TCP  (0) 2010.09.26
[Network 08. 31]01. Chapter1  (0) 2010.08.31