>  기사  >  백엔드 개발  >  C#의 UDP 프로토콜 기반 동기 통신 샘플 코드에 대한 자세한 설명

C#의 UDP 프로토콜 기반 동기 통신 샘플 코드에 대한 자세한 설명

黄舟
黄舟원래의
2017-03-23 11:38:101961검색

이 글에서는 주로 C# 기반 UDP 프로토콜의 동기화 구현 코드를 소개합니다. 편집자는 꽤 좋다고 생각하여 지금부터 공유하고 참고용으로 제공하겠습니다. 에디터를 따라가서 살펴보겠습니다.

1. 요약

C# 기반 UDP 프로토콜의 동기식 통신 요약입니다.

2. 실험 플랫폼

Visual Studio 2010

3. 실험 원리

UDP 전송 프로토콜과 TCP 전송 프로토콜의 차이점은 해당 문서에서 확인할 수 있으므로 여기서는 설명하지 않겠습니다.

4. 예시

4.1 UDP 구현을 위한 소켓

UDP는 무선이기 때문에 연결 프로토콜. 따라서 서버 애플리케이션이 UDP 패킷을 보내고 받으려면 다음 두 가지 작업을 수행해야 합니다.

(1) 소켓 객체를 생성합니다.

(2 ) 생성된 소켓 개체를 로컬 IPEndPoint에 바인딩합니다.

위 단계를 완료하면 생성된 소켓은 IPEndPoint에서 들어오는 UDP 데이터 패킷을 수신하거나 나가는 UDP 데이터 패킷을 네트워크의 다른 장치로 보낼 수 있습니다. UDP를 사용하여 통신하는 경우 연결이 필요하지 않습니다. 원격 호스트 간에 설정된 연결이 없기 때문에 UDP는 표준 Send() 및 Receiver()t 소켓 메서드를 사용할 수 없지만 SendTo() 및 ReceiverFrom()이라는 두 가지 다른 메서드를 사용합니다.

SendTo() 메소드는 전송할 데이터와 대상 시스템의 IPEndPoint를 지정합니다. 이 방법은 특정 애플리케이션에 따라 여러 가지 방법으로 사용될 수 있지만 최소한 패킷과 대상 시스템을 지정해야 합니다.

SendTo(byte[] data,EndPoint Remote)

ReceiveFrom() 메서드는 SendTo() 메서드와 유사하지만 EndPoint 개체 선언을 사용하는 방법이 다릅니다. ref 수정을 사용하면 전달되는 것은 EndPoint 개체가 아니지만 매개 변수는 EndPoint 개체에 전달됩니다.

UDP 애플리케이션은 엄밀한 의미에서 실제 서버와 클라이언트가 아니라 동등한 관계, 즉 1차 관계와 2차 관계가 없습니다. 단순화를 위해 다음 애플리케이션을 여전히 UDP 서버라고 합니다.

서버측 코드:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace UDP
{
 class Program
 {
  static void Main(string[] args)
  {
   int recv;
   byte[] data = new byte[1024];

   //得到本机IP,设置TCP端口号   
   IPEndPoint ip = new IPEndPoint(IPAddress.Any, 8001);
   Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

   //绑定网络地址
   newsock.Bind(ip);

   Console.WriteLine("This is a Server, host name is {0}", Dns.GetHostName());

   //等待客户机连接
   Console.WriteLine("Waiting for a client");

   //得到客户机IP
   IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
   EndPoint Remote = (EndPoint)(sender);
   recv = newsock.ReceiveFrom(data, ref Remote);
   Console.WriteLine("Message received from {0}: ", Remote.ToString());
   Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));

   //客户机连接成功后,发送信息
   string welcome = "你好 ! ";

   //字符串与字节数组相互转换
   data = Encoding.ASCII.GetBytes(welcome);

   //发送信息
   newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
   while (true)
   {
    data = new byte[1024];
    //发送接收信息
    recv = newsock.ReceiveFrom(data, ref Remote);
    Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
    newsock.SendTo(data, recv, SocketFlags.None, Remote);
   }
  }

 }
}

UDP 서버 프로그램이 들어오는 메시지를 받으려면 프로그램이 로컬 시스템에 지정된 UDP 포트에 바인딩되어 있어야 합니다. 이는 적절한 로컬 IP 주소와 적절한 UDP 포트 번호를 사용하여 IPEndPoint 개체를 생성함으로써 수행됩니다. 위 예제 프로그램의 UDP 서버는 포트 8001의 네트워크에서 들어오는 UDP 패킷을 수신할 수 있습니다.

UDP 클라이언트 프로그램은 서버 프로그램과 매우 유사합니다.

클라이언트는 지정된 UDP 포트에서 들어오는 데이터를 기다릴 필요가 없으므로 Bind() 메서드를 사용하지 않고 데이터 전송 시 시스템에서 임의로 지정한 UDP 포트를 사용합니다. 사용되며 동일한 포트가 반환된 메시지를 수신합니다. 제품을 개발할 때 서버와 클라이언트 프로그램이 동일한 포트 번호를 사용하도록 클라이언트에 UDP 포트 세트를 지정하십시오. UDP 클라이언트 프로그램은 먼저 IPEndPoint를 정의하고 UDP 서버는 이 IPEndPoint로 데이터 패킷을 보냅니다. 원격 장치에서 UDP 서버 프로그램을 실행하는 경우 IPEndPoint 정의에 적절한 IP 주소와 UDP 포트 번호 정보를 입력해야 합니다.

클라이언트 코드 :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace UDPClient
{
 class Program
 {
  static void Main(string[] args)
  {
   byte[] data = new byte[1024];
   string input, stringData;

   //构建TCP 服务器
   Console.WriteLine("This is a Client, host name is {0}", Dns.GetHostName());

   //设置服务IP,设置TCP端口号
   IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8001);

   //定义网络类型,数据连接类型和网络协议UDP
   Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

   string welcome = "你好! ";
   data = Encoding.ASCII.GetBytes(welcome);
   server.SendTo(data, data.Length, SocketFlags.None, ip);
   IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
   EndPoint Remote = (EndPoint)sender;

   data = new byte[1024];
   //对于不存在的IP地址,加入此行代码后,可以在指定时间内解除阻塞模式限制
   int recv = server.ReceiveFrom(data, ref Remote);
   Console.WriteLine("Message received from {0}: ", Remote.ToString());
   Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
   while (true)
   {
    input = Console.ReadLine();
    if (input == "exit")
     break;
    server.SendTo(Encoding.ASCII.GetBytes(input), Remote);
    data = new byte[1024];
    recv = server.ReceiveFrom(data, ref Remote);
    stringData = Encoding.ASCII.GetString(data, 0, recv);
    Console.WriteLine(stringData);
   }
   Console.WriteLine("Stopping Client.");
   server.Close();
  }

 }
}

위 코드의 구현 로직은 해당 설정이 완료된 후 서버가 먼저 클라이언트에 정보를 보내고 클라이언트는 키보드를 통해 문자열을 보냅니다. , 서버가 수신한 후 루프와 같이 클라이언트로 전송됩니다.

4.2 UDPClient 클래스를 이용한 구현

서버측 코드:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class Custom
{
 // 设置IP,IPV6
 private static readonly IPAddress GroupAddress = IPAddress.Parse("IP地址");
 // 设置端口
 private const int GroupPort = 11000;

 private static void StartListener()
 {
  bool done = false;

  UdpClient listener = new UdpClient();

  IPEndPoint groupEP = new IPEndPoint(GroupAddress, GroupPort);

  try
  {
   //IPV6,组播
   listener.JoinMulticastGroup(GroupAddress);

   listener.Connect(groupEP);

   while (!done)
   {
    Console.WriteLine("Waiting for broadcast");

    byte[] bytes = listener.Receive(ref groupEP);

    Console.WriteLine("Received broadcast from {0} :\n {1}\n", groupEP.ToString(), Encoding.ASCII.GetString(bytes, 0, bytes.Length));
   }

   listener.Close();

  }
  catch (Exception e)
  {
   Console.WriteLine(e.ToString());
  }

 }

 public static int Main(String[] args)
 {
  StartListener();

  return 0;
 }
}

클라이언트측 코드:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class Client
{

 private static IPAddress GroupAddress = IPAddress.Parse("IP地址");

 private static int GroupPort = 11000;

 private static void Send(String message)
 {
  UdpClient sender = new UdpClient();

  IPEndPoint groupEP = new IPEndPoint(GroupAddress, GroupPort);

  try
  {
   Console.WriteLine("Sending datagram : {0}", message);

   byte[] bytes = Encoding.ASCII.GetBytes(message);

   sender.Send(bytes, bytes.Length, groupEP);

   sender.Close();

  }
  catch (Exception e)
  {
   Console.WriteLine(e.ToString());
  }

 }

 public static int Main(String[] args)
 {
  Send(args[0]);

  return 0;
 }
}

위 코드 설명 필요 예:

(1) 위 코드는 IPV6 주소 기반의 멀티캐스트 모드입니다. IPv4의 브로드캐스트는 네트워크 성능 저하 또는 브로드캐스트 폭풍을 일으킬 수 있습니다. IPv6에는 브로드캐스트라는 개념이 없으며, 멀티캐스트와 애니캐스트로 대체됩니다.

(2) IPV6 주소 표현 방법:

a) X:X:X:X:X:X:X:X (각 X는 16자리 16진수를 나타냄) , 아님 대소문자를 구분합니다.

b) 선행 0은 생략할 수 있습니다. 예를 들어 09C0은 9C0으로 쓸 수 있고, 0000은 0으로 쓸 수 있습니다.

c) 연속된 0이 있는 필드를 표현할 수 있습니다. by :: 대신 ::은 전체 주소에 한 번만 나타날 수 있습니다. 예를 들어 FF01:0:0:0:0:0:0:1은 FF01::1로 축약될 수 있습니다.

(3) 폼 형태인 경우에는 이 형식을 사용하는 것을 권장합니다. 그렇지 않으면 데이터 수신 시 크래시가 발생할 수 있습니다.

아아아아

위 내용은 C#의 UDP 프로토콜 기반 동기 통신 샘플 코드에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.