C# 네트워크 프로그래밍 - devpia 펌

DNS와 IP 주소~~

우리가 현재 사용하고 있는 URL은 다음과 같이 4 부분으로 구성이 되어 있습니다.

프로토콜 ://도메인이름:포트 번호/경로

http://www.kbook.co.kr:80/books/list.asp

하지만 대부분의 사람들은 .. 이렇게 쓰지 않죠!!!  도메인 이름만 쓰고 엔터키를 누르게 됩니다....

그래도 연결이 되니깐요.

결국 도메인이름호스트를 나타낸다고 보면 되겠죠. -  과연 도메인 이름은 무엇일까요?

간단히 말해서... IP의 대체라고 할 수 있습니다.


[예제 Source]

using System;

using System.Collections.Generic;

using System.Text;

using System.Net;

 

namespace DnsResolve

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.Write("원하는 도메인 이름을 입력하세요.");

 

            string domainName = Console.ReadLine();

 

            IPHostEntry ipHostEntry = null;

 

            try

            {

                //ipHostEntry = Dns.Resolve(domainName);

                ipHostEntry = Dns.GetHostEntry(domainName);

            }

            catch (Exception e)

            {

                Console.WriteLine(e.Message);

                return;

            }

 

            if (ipHostEntry != null)

            {

                foreach (IPAddress ip in ipHostEntry.AddressList)

                {

                    Console.WriteLine(ip.ToString());

                }

            }

 

        }

    }

}


[작업화면]

[if gte vml 1]> <![endif]




2월 14일 - 오후 2시 03분

System.Ner요소 (네트워크 설정)

 

.NET Framework의 네트워크 연결 방법을 지정하는 설정을 포함합니다.

 

IPHostEntry 클래스

- 인터넷 호스트 주소 정보에 컨테이너 클래스를 제공합니다.

네임스페이스 : System.Net

어셈블리 : System(system.dll)

 

구문

C#

public class IPHostEntry

설명

IPHostEntry 클래스는 DNS(Domain Name System) 호스트  이름을 별칭의 배열 및 해당 IP 주소의 배열과 연결합니다.

IPHostEntry 클래스Dns 클래스의 도우미 클래스로 사용됩니다.




DNS 클래스


단순 도메인 이름 확인 기능이 제공됩니다.


네임스페이스 : System.Net

어셈블리 : System(System.dll)


구문

C#

public static class Dns

설명

Dns 클래스는 특정 호스트의 정보를 인터넷 DNS(Domain Name System)에서 검색하는 정적 클래스입니다.


DNS 쿼리에서 검색한 호스트 정보는 IPHostEntry 클래스의 인스턴스에 반환됩니다.

지정된 호스트의 DNS 데이터베이스에 여러 항목이 있으면 IPHostEntry에 여러 개의 IP 주소와 별칭이 포함됩니다.


다음 예제에서는 호스트인 www.contoso.com에 대한 정보를 DNS 데이터베이스에 쿼리합니다.

IPHostEntry hostInfo = Dns.GetHostByName("www.contoso.com");


상속 계층 구조

System.Object

  System.Net.Dns


Dns 멤버

 - 단순 도메인 이름 확인 기능이 제공됩니다.

다음 표에서는  Dns 형식에 의해 노출되는 멤버를 보여 줍니다.


Public 메서드


이름


public method, Static

BeginGetHostAddresses

지정된 호스트의 IP(인터넷 프로토콜) 주소를 비동기적으로 반환합니다.


BeginGetHostByName

지정된 DNS 호스트 이름에 대한 IPHostEntry 정보의 비동기 요청을 시작합니다.


GetHostAddresses

지정된 호스트의 IP(인터넷 프로토콜) 주소를 반환합니다.

GetHostByAddress

오버로드되었습니다. IP 주소에 대한 DNS 호스트 정보를 가져옵니다








IPAddress


IPAddress 클래스


 IP(인터넷 프로토콜) 주소를 제공합니다.


 네임 스페이스 : System.Net

 어셈블리 : System(system.dll)


 구문(C#)

[SerializableAttribute]

public class IPAddress


설명

IPAddress 클래스에는 컴퓨터의 IP 네트워크 주소가 포함되어 있습니다.



IPHostEntry.AddressList 속성


호스트와 연결된 IP 주소 목록을 가져오거나 설정합니다.


네임스페이스 : System.Net

어셈블리 : System(system.dll)

구문

public IPAddress[] AddressList { get; set;}


속성 값


Aliases 속성에 포함된 호스트 이름을 확인하는 IP 주소가 포함된 IPAddress 형식의 배열입니다.


UDP 소켓 프로그래밍


SOCKET  -

소켓 기반 네트워크 프로그래밍에서는 패킷을 전송하고 수집하기 위해 직접 네트워크 인터페이스 장치를 접근할 필요가 없다.

대신, 네트워크와의 프로그래밍 인터페이스를 처리해줄 중간 단계의 파일 기술자를 생성하여 사용한다.

네트워크 연결을 참조하는데 사용하는 특정 파일 기술자를 소켓(socket)이라 부른다.


TCP와 UDP의 차이


TCP는 스트림 서비스를 제공하고, UDP는 데이터그램 서비스를 제공하는 것으로 구분지을 수 있습니다.


TCP는 스트림 서비스를 제공하기 때문에 데이터의 경계가 없고, 데이터의 순서가 올발라야하며. 손실이  있으면 안됩니다.

그래서 접속(connection)이라는 과정을 거쳐 서로 전송을 할 준비를 함으로써 지속적이고 신뢰성있는 서비스를 제공하게 됩니다.

또한,  오류도 복구하여....주며 및 파일을 다루는 것과 같은 쉬운 Interface를 제공한다.


 UDP는 데이터그램을 서로 간의 준비과정없이 바로 보낼 수 있습니다. (UDP의 패킷도 데이터그램의 서비스를 사용하므로 데이터이라고한다.) 서로 준비과정이 없으므로 원격 호스트까지 도달한다는 보장도 해주지 않고, 중복되어 올 수도 있으며 , 순서가 바뀔 수도 있고 이러한 순서에 대한 오류 보정도 해주지 않습니다. 그러나 ....  CheckSum 기능이 있어서... 데이터그램 단위의 오류 검출  기능은 지원한다.


 그래서 TCP를  연결지향    UDP를 비연결 지향이라고 나누기도 한다... 이렇게 스트림 서비스를 기반으로 신뢰성을 제공해주고 - UDP는 데이터그램 서비스를 기반으로 효율성을 제공해 준다.


포트 -

각각의 호스트를 IP 주소를 이용하여 구분을 한다고 하였다.  그런데 호스트에서는 수많은 응용 프로그램이 난무하며 실행되고 있고 수많은 소켓이 존재할 수 있다.

같은 호스트 내의 이러한 구분을 포트 번호가 .... 해결을 해준다..  포트 번호가 해결사인줄 이재야 알겠군~

일반적으로 IP 주소와 포트 번호를 합쳐서 종단 점(end point)이라고 이라고 하~며 소켓을 구분하는 용도로 사용이 되어집니다.


그리고 TCP와 UDP는 데이터를 하나의 종단 프로그램에서 다른 종단 프로그램까지 전달한다는 의미에서 종단 간 전송(end-to-end transport)프로토콜이라고 한다.

결국, 서로 통신을 할 소켓 간에는 종단점을 알아야 하고 - 당연- 포트 번호는 미리 합의가 되어 있어야 하는 것이다. 그래서 우리가 많이 사용하고 있는 서비스들은 이미 포트 번호가 예약이 되어 있다.

예를 들어, HTTP 서버는 80번 포트를 FTP 서버는 21번 포트를 사용하는 것과 같습니다.


UDP 프로그래밍


img1.gif


위와 같은 구조로 프로그래밍해주시면 됩니다.


우선 소켓을 생성하고 Bind를 하여 초기화를 한다. 그 후 .....


Server 와 Client 는 통신과 처리를 반복한다... 글고... 종료를 할때.... 소켓을 닫아주면 됩니다.

이러한  UDP는 연결과정이... 필요없으므로 바로  .. 보낼 수 있고  바로 받을 수 있다... 각 데이터그램은 최~대 65507 바이트의 데이터를 주고... 받는다.

UDP는 신뢰성이 없는 프로토콜이므로 처리과정에서 오류 제어도 처리하여 주어야 할 것이다... (귀찮군...)

또한, 연결과정이 없으므로       사용자 관리와 보안에도..... 신경을 써야한다... (머리 아프겠군)


2008년 2월 15일 추가내용

비관리 코드 호출불완전 코드 사용

C# 언어는 - 기본적으로 공통언어 런타임이 관리하는 관리 코드(managed code)모드로 동작하지만

C# 언어는 - 기본적으로 공통언어 런타임이 관리하는 관리 코드(managed code)모드로 동작하지만

경우에 따라서는

공통언어 런타임이 관리하지 않는 비관리 코드(unmanaged code)를 호출해야 하는 경우가 있습니다.

이것을 다른 말로 플랫폼  호출(platform Invoke) 또는 줄여서 PInvoke라고도 합니다.

예를들어, 메시지 대화상자를 표시하는 Win32 API의 MesageBox 함수는 다음과 같은 원형을 갖습니다.

int MessageBox  (

    HWND hwnd,               //소유자 원도우 핸들

    LPCTSTR lpText,        //메시지 대화상자에 표시할 텍스트

    LPCTSTR lpCaption,   //메시지 대화상자의 타이틀

    UINT uType );            // 메시지 대화상자의 형식




 C# 코드가 직접 호출할 수 있는 비관리 코드에는 동적 링크 라이브러리(DLL)의 익스포트 함수(Export functioin)와 COM 객체의 인터페이스 메서드가 있습니다.


C# 코드에서  DLL 익스포트 함수를 호출하기 위해서는 먼저 해당 함수에 대응되는 static extern 메서드를 선언해야 합니다.


class MyClass  {

    public static extern int MessageBox (

        int hwnd,

        string text,

        string caption,

        int type

);

}



다음에는 이 메서드에 DllImport 애트리뷰트를 지정합니다. DllImport 애트리뷰트에는 이 익스포트 함수를 포함하는 DLL의 이름을

지정합니다.

MessageBox 함수는 user32.dll 안에 포함되어 있으므로, 다음과 같이 DllImport 애트리뷰트를 지정합니다.


class MyClass  {

[DllImport("user32.dll" )]

    public static extern int MessageBox (

        int hwnd,

        string text,

        string caption,

        int type

);

}


이제 우리는 다음과 같이 MessageBox 함수를 호출할 수 있습니다.


MessageBox(0,"안녕하세요 여러분","인사말",0);

[전체 Source]

using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.InteropServices;


namespace ConsoleApplication1

{

    class MyClass

    {

        [DllImport("user32.dll")]

        public static extern int MessageBox(

            int hwnd,

            string text,

            string caption,

            int type

    );

    }


    class Program

    {

        static void Main(string[] args)

        {

            MyClass.MessageBox(0, "안녕", "인사말", 0);

        }

    }

}



이 코드가 실행이 되면... 다음과 같은 화면이 출력이 됩니다...



[결과화면]

img1.jpg



 다시 .네트워크 프로그램 ...


[Server 쪽 프로그램 Source]

using System;

using System.Collections.Generic;

using System.Text;

using System.Net;

using System.Net.Sockets;


namespace UdpEchoServer

{

    class Program

    {

        private const int ServerPortNumber = 5432;

         

        static void Main(string[] args)

        {

            try

            {

                //UDP Socket을 만든다.

                Socket udpSocket = new Socket(AddressFamily.InterNetwork,

                    SocketType.Dgram, ProtocolType.Udp);


                EndPoint localEP = new IPEndPoint(IPAddress.Any, ServerPortNumber);


                EndPoint remoteEP = new IPEndPoint(IPAddress.None, ServerPortNumber);


                udpSocket.Bind(localEP);



                byte[] receivedBuffer = new byte[512];



                Console.WriteLine("서버가 실행중에 있습니다....");


                try

                {

                    while (true)

                    {

                        int receivedSize = udpSocket.ReceiveFrom(receivedBuffer, ref remoteEP);


                        udpSocket.SendTo(receivedBuffer, receivedSize, SocketFlags.None, remoteEP);



                       


                    }


                   

                }

                finally

                {

                    udpSocket.Close();

                }

            }

            catch (SocketException se)

            {

                Console.WriteLine(se.ToString());

            }


        }

    }

}


[Client 쪽 프로그램 Source]


using System;

using System.Collections.Generic;

using System.Text;

using System.Net;

using System.Net.Sockets;


namespace UdpEchoClient

{

    class Program

    {

        private const int ServerPortNumber = 5432;


        static void Main(string[] args)

        {

            try

            {

                Socket udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);


                EndPoint localEP = new IPEndPoint(IPAddress.Any , 0);


                EndPoint remoteEP = new IPEndPoint(IPAddress.Loopback, ServerPortNumber);


                udpSocket.Bind(localEP);


                byte[] sendBuffer;


                sendBuffer = Encoding.ASCII.GetBytes("Hello?");


                udpSocket.SendTo(sendBuffer, remoteEP);



                byte[] receivedBuffer = new Byte[512];


                int receivedSize = udpSocket.ReceiveFrom(receivedBuffer, ref remoteEP);


                Console.WriteLine(Encoding.ASCII.GetString(receivedBuffer, 0, receivedSize));


                udpSocket.Close();


            }

            catch (SocketException se)

            {

                Console.WriteLine(se.ToString());

            }

        }

    }

}



System.Net.Sockets 네임스페이스는 네트워크에 대한 액세스를 엄격하게 제어해야 하는 개발자에게 Windows Socket(Winsock) 인터페이스의 관리되는 구현을 제공합니다.


TcpClient, TcpListener 및 UdpClient 클래스는 TCP 및 UDP 방식으로 인터넷에 연결하기 위한 자세한 정보를 캡슐화합니다.



Socket 클래스


Berkeley 소켓 인터페이스를 구현합니다.


네임스페이스 : System.Net.Sockets

어셈블리 : System(system.dll)


구문 C#  -

public class Socket : IDisposable


설명

Socket 클래스는 네크워크 통신을 위한 풍부한 메서드 및 속성 집합을 제공합니다.

Socket 클래스를 사용하면 ProtocolType 열거형에 나열된 통신 프로토콜을 사용하여 동기 및 비동기 데이터 전송을 수행할 수 있습니다.

Socket 클래스는 비동기 메서드에 대해 .NET Framework 명명 패턴을 따릅니다.예를 들어, 동기 Receive 메서드는 비동기 BeginReceive 및 EndReceive 메서드에 해당합니다.


실행하는 동안 응용 프로그램에 하나의 스레드만 필요한 경우 동기 작업 모드용으로 디자인된 다음 메서드를 사용합니다.


- TCP와 같은 연결 지향 프로토콜을 사용하는 경우 서버는 Listen메서드를 사용하여 연결을 수신할 수 있습니다. Accept 메서드는 들어오는 연결 요청을 처리하고 원격 호스트와 데이터를 주고 받는 데 사용할 수 있는 Socket를 반환합니다. 반환된 해당  Socket을 사용하여 Send 또는 Receive 메서드를 호출합니다.

로컬 IP주소 및 포트 번호를 지정하려면 Listen메서드를 호출하기 전에 Bind 메서드를 호출합니다. 내부 서비스 공급자가 사용 가능한 포트를 할당하게 하려면 포트 번호로 0을 사용합니다. 수신 호스트에 연결하려면 Connect메서드를 호출합니다. 데이터를 보내고 받으려면 Send 또는 Receive메서드를 호출합니다.\\\


- UDP와 같은 연결 없는 프로토콜을 사용하는 경우 연결을 수신할 필요가 없습니다. ReceiveFrom 메서드를 호출하여 들어오는 데이터그램을 허용합니다. SendTo 메서드를 사용하여 원격 호스트에 데이터그램을 보냅니다.


실행 중에 별도의 스레드를 사용하여 통신을 처리하려면 비동기 작업 모드용으로 디자인된 다음 메서드를 사용합니다.


- TCP와 같은 연결 지향 프로토콜을 사용하는 경우 Socket, BeginConnect 및 EndConnect 메서드를 사용하여 수신 호스트와 연결합니다. 데이터를 비동기적으로 주고 받으려면 BeginSend 및 EndSend  또는 BeginReveive 및 EndReceive 메서드를 사용합니다. 들어오는 연결 요청은 BeginAccept 및 EndAccept를 사용하여 처리할 수 있습니다.


UDP와 같은 연결 없는 프로토콜을 사용하는 경우 BeginSendTo 및 EndSendTo를 사용하여 데이터그램을 보내고 BeginReceiveFrom  및 EndReceiveFrom을 사용하여 데이터그램을 받을 수 있습니다.


한 소켓에서 여러 개의 비동기 작업을 수행하는 경우 작업이 시작된 순서대로 완료되지 않아도 됩니다.


    

데이터를 보내고 받는 일이 끝나면 Shutdown 메서드를 사용하여  Socket을 비활성합니다. Shutdown을 호출한 후에 Close 메서드를 호출하여 Socket과 관련된 모든 리소스를 해제합니다.


Socket 클래스를 사용하면 SetSocketOption메서드를 통해 Socket을 구성할 수 있습니다.

GetSocketOption 메서드를 사용하여 이러한 설정을 검색합니다.


참고

비교적 간단한 응용 프로그램을 작성하거나 최대 성능이 필요하지 않은 경우 TcpClient, TcpListener 및 UdpClient를 사용해 보십시오. 이러한 클래스는 Socket통신을 위한 보다 간단하고 친숙한 인터페이스를 제공합니다.



ProtocolType

Socket 클래스가  지원하는 프로토콜을 지원합니다.


네임스페이스 : System.Net.Sockets

어셈블리 : System(system.dll)


구문

public enum ProtocolType


멤버이름


Tcp

Transmission Control 프로토콜입니다.

Udp

User Datagram 프로토콜입니다

Socket 클래스는 ProtocolType 열거형을 사용하여 프로토콜의 Windows 소켓 API에 알립니다. 필요한 프로토콜에 대한 하위 수준 소프트웨어 드라이버는 Socket이 만들어질 컴퓨터에 있어야 합니다.




Socket.ReceiveFrom 메서드

데이터그램을 받고 소스 끝점을 저장합니다.



오버로드 목록


이름

설명

Socket.ReceiveFrom(Byte[],EndPoint)

데이터 버퍼에 데이터그램을 받고 끝점을 저장합니다.




Socket.SendTo 메서드

특정 끝점에 데이터를 보냅니다.


오버로드 목록



이름

설명

Socket.SendTo(Byte[], EndPoint)

지정된 끝점에 데이터를 보냅니다.       .NET Compact Framework에서 지원됩니다.

Socket.SendTo(Byte[],SocketFlags,EndPoint)

지정된 SocketFlags를 사용하여 특정 끝점에 데이터를 보냅니다.



ref(C# 참조)


ref 키워드는 인수를 참조로 전달하는 데 사용됩니다.메서드의 모든 매개 변수 변경 사항은 호출하는 메서드로 제어가 다시 전달될 때 해당 변수에 반영됩니다.  ref 매개변수를 사용하려면 메서드 정의와 호출하는 메서드에서 모두 ref 키워드를 명시적으로 사용해야 합니다.

예를 들면 다음과 같습니다.


class RefExample

{

    static void Method(ref int i)

    {

        i = 44;

    }


    static void Main()

    {

        int val = 0;

        Method(ref val);

        // val is now 44

    }

}


ref 매개 변수에 전달되는 인수는 먼저 초기화되어야 합니다. 이는 해당 인수를 전달하기 전에 명시적으로 초기화할 필요가 없는 out과 다른 점입니다.


ref 및 out은  런타임에 서로 다르게 취급되지만 컴파일 타임에는 동일하게 취급됩니다. 따라서 한 메서드는 ref인수를 사용하고 다른 메서드는 out인수를 사용하는 경우 메서드를 오버로드할 수 없습니다.

예를 들어, 이러한 두 메서드는 컴파일할 때 동일하게 간주하므로 다음과 같은 코드는 컴파일되지 않습니다.


class CS0663_Example

{

    // compiler error CS0663: "cannot define overloaded

    // methods that differ only on ref and out"

    public void SampleMethod(ref int i) {  }

    public void SampleMethod(out int i) {  }

}


그러나 한 메서드가 ref 또는  out  인수를 사용하고 다른 메서드는 두 인수 중 어느 것도 사용하지 않는 경우 다음과 같이 오버로드할 수 있습니다.


class RefOutOverloadExample

{

    public void SampleMethod(int i) {  }

    public void SampleMethod(ref int i) {  }

}


속성은 변수가 아니므로 ref 매개변수로 전달할 수 없습니다.



스트링과 스트림

스트링(string)

.NET에서의 스트링은 유니코드를 사용하기 때문에 한 문자는 2byte  이다.  System.String 클래스로 표현하며 C#에서는 string이라는 키워드가 이를 대신 할 수도 있다.


*** Dictionary

유니코드

- 유니코드는 세계 각 국의 언어를 통일된 방법으로 표현할 수 있게 제안된 국제적인 코드 규약의 이름을 말한다.

기존의 문자체계(대표적으로 Ascii와 MBCS)가 가지는 문제점인 인코딩 방식의 다양성을 통일된 형식으로 표준화하기 위해 고안된 것이다.

유니코드에서 하나의 문자는 16Bit이며 ...



Encoding  클래스


문자 인코딩을 나타냅니다.


네임스페이스 : System.Text

어셈블리 : mscorlib(mscorlib.dll)


[SerializableAttribute]

[ComVisibleAttribute(true)]

public abstract class Encoding : ICloneable


설명

- 인코딩은 유니코드 문자집합을 바이트 시퀀스로 변환하는 프로세스이며

디코딩은 그 반대로, 인코딩된 바이트 시퀀스를 유니코드 문자 집합으로 변환하는 프로세스입니다.


소켓 프로그래밍


TCP 프로그래밍

- TCP 가 UDP 와 비교했을 때 가장 큰 차이점은 신뢰성 있는 스트림을 지원하기 위해 접속의 과정이 필요하다는 것이다.

접속이 되면 두 호스트 간에 연결이 이루어지고, 연결된 동안 지속적이고 안정적인 통신이 가능하게 된다.

또한 연결이 이루어 지면 서로 상대방의 호스트끼리의 통신만 가능하며 각 호스트에 별도의 서비스가 가능하다는 장점이 있다.


서로 통신이 끝나면 연결을 끊어야 한다는 사실도 잊어서는 안된다.

그리고 TCP스트림의 통신이라는 점을 기억해 두어야 한다.... 하지만 자주 까먹는다. ^^;


[TO Be Continue.........]

2월 17일 .... 일요일 한가한 오후에.. TCP의 작동  과정을 그려봤습니다.


img1.gif


이제.. 이 작동 과정에 기초해서 .. 프로그램만 짜면. .되겠죠...  



TCP 에코 서버 만들기


using System;

using System.Collections.Generic;

using System.Text;

using System.Net;

using System.Net.Sockets;

using System.IO;



namespace TcpEchoServer

{

    class Program

    {

        // 서버로 사용할 포트 번호.

        private const int ServerPort = 4576;

         

        static void Main(string[] args)

        {

            try

            {

                // TCP 소켓을 만든다.

                Socket listenSocket = new Socket(AddressFamily.InterNetwork,

                    SocketType.Stream, ProtocolType.Tcp);


                try

                {

                    // 이 try 문은 finally문에서 listen 소켓을 닫아준다.

                    IPEndPoint listenEP = new IPEndPoint(IPAddress.Any, ServerPort);

                    // 종단점을 바인드한다.

                    listenSocket.Bind(listenEP);

                    // 접속을 기다리도록 설정한다.

                    listenSocket.Listen(5);


                    // 클라이언트 소켓을 나타냄

                    Socket clientSocket = null;


                    // 데이터를 받기 위해 버퍼를 설정하자

                    byte[] receiveBuffer = new byte[512];


                    while (true)

                    {

                        // 접속된 클라이언트를 얻어온다.

                        clientSocket = listenSocket.Accept();


                        // 클라이언트로부터 받은 데이터를 바로 보낸다.


                        int receiveSize = clientSocket.Receive(receiveBuffer, 512, SocketFlags.None);


                        while (receiveSize > 0)

                        {

                           

                            clientSocket.Send(receiveBuffer, receiveSize, SocketFlags.None);


                            receiveSize = clientSocket.Receive(receiveBuffer, 512, SocketFlags.None);


                        }


                        // 더 이상 통신할 수 없도록 한다.

                        clientSocket.Shutdown(SocketShutdown.Both);

                        clientSocket.Close();


                    }

                }

                finally

                {

                    // 종료할 때 listen 소켓도 닫자.

                    listenSocket.Close();

                }

            }

            catch (Exception e)

            {

                Console.WriteLine(e.ToString());

            }

        }

    }

}



TCP 에코 클라이언트 만들기


 using System;

using System.Collections.Generic;

using System.Text;

using System.Net;

using System.Net.Sockets;

using System.IO;


namespace TcpEchoClient

{

    class Program

    {

        // 서버로 사용할 포트 번호

        private const int ServerPort = 4576;



        static void Main(string[] args)

        {

            try

            {

                // 1) TCP socket을 만든다.

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


                // 서버에 접속을 하자.


                // 서버의 종단점을  설정한다.


                IPEndPoint serverEP = new IPEndPoint(IPAddress.Loopback, ServerPort);


                // 서버에 접속을 하자.

                clientSocket.Connect(serverEP);


                // 3) 서버로 데이터를 보내자

                // Hello? 문자열을 Ascii로 인코딩하여 버퍼에 담는다.

                byte[] sendBuffer;


                sendBuffer = Encoding.ASCII.GetBytes("Hello?\r\n");


                // 소켓을 이용해 서버로 문자열을 보낸다.

                clientSocket.Send(sendBuffer);


                // 서버로부터 데이터를 받자.


                // 받을 버퍼를 만들자.


                byte[] receiveBuffer = new byte[512];


                int receiveSize = clientSocket.Receive(receiveBuffer, 512, SocketFlags.None);


                Console.Write(Encoding.ASCII.GetString(receiveBuffer, 0, receiveSize));


                // 5) 마무리


                // 더 이상 통신할 수 없도록 한다.


                clientSocket.Shutdown(SocketShutdown.Both);

                // 소켓을 닫자.

                // 소켓을 닫으면 서버와의 연결이 끊어지고

                // 서버의 Receive는  0을 리턴해 접속의 종료를 알 수 있다.

                clientSocket.Close();

            } catch(Exception e)

            {

                Console.WriteLine(e.ToString());

            }

        }

    }

}


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


TCP 소켓을 생성한다. 약간의 옵션이 바뀌었을 뿐 UDP 소켓의 생성과 크게 다르지 않음을 알 수 있다.

생성자의 매개변수로 AddressFamily.InterNetwork를 넘겨 IP 주소임을 나타내고 SocketType.Stream을 넘겨 스트림 기반 통신을 나타내며 ProtocolType.Tcp를 넘김으로 Tcp 프로토콜을 사용한다는 것을 알린다.


UDP가 SocketType.Dgram과 ProtocolType.Udp를 사용해야 하는 것처럼 TCP는 SocketType.Stream과  ProtocolType.Tcp를 사용해야 한다.



재미가 없네요..

아.. 그리고 네트워크 프로그램 작성하실 때 스레드도 중요하니깐 공부해 두시는것이 좋을거에요. 그럼. 이만


그럼 정말 즐프하세요

Posted by 퓨전마법사
,