zoukankan      html  css  js  c++  java
  • C#中UDP(Socket)

    复制代码

     1 使用无连接的套接字,我们能够在自我包含的数据包里发送消息,采用独立的读函数读取消息,读取的消息是使用独立的发送函数发送的。但是UDP数据包不能保证可靠传输,存在许多的因素,比如网络繁忙等等,都有可能阻止数据包到达指定的目的地。
     2    (1)UDP的简单应用:
     3     由于UDP是一种无连接的协议。因此,为了使服务器应用能够发送和接收UDP数据包,则需要做两件事情:
     4     创建一个Socket对象;
     5     将创建的套接字对象与本地IPEndPoint进行绑定。
     6     完成上述步骤后,那么创建的套接字就能够在IPEndPoint上接收流入的UDP数据包,或者将流出的UDP数据包发送到网络中任意其他设备商。使用UDP进行通信时,不需要TCP连接。因为异地的主机之间没有建立连接,所以UDP不能使用标准的Send()和Receive()t套接字方法,而是使用两个其他的方法:SendTo()和ReceiveFrom()。
     7     SendTo()方法指定要发送的数据,和目标机器的IPEndPoint。该方法有多种不同的使用方法,可以根据具体的应用进行选择,但是至少要指定数据包和目标机器。如下:
     8     SendTo(byte[] data,EndPoint Remote)
     9     ReceiveFrom()方法同SendTo()方法类似,但是使用EndPoint对象声明的方式不一样。利用ref修饰,传递的不是一个EndPoint对象,而是将参数传递给一个EndPoint对象。
    10    (2)UDP服务器
    11     UDP应用不是严格意义上的真正的服务器和客户机,而是平等的关系,即没有主与次的关系。为了简便起见,仍然把下面的这个应用叫做UDP服务器。源代码如下:
    12 using System;
    13 using System.Collections.Generic;
    14 using System.Text;
    15 using System.Net;
    16 using System.Net.Sockets;
    17 namespace SimpleUdpSrvr
    18 {
    19     class Program
    20     {
    21         static void Main(string[] args)
    22         {
    23             int recv;
    24             byte[] data = new byte[1024];
    25             IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);//定义一网络端点
    26             Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,ProtocolType.Udp);//定义一个Socket
    27             newsock.Bind(ipep);//Socket与本地的一个终结点相关联
    28             Console.WriteLine("Waiting for a client.....");
    29 
    30             IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);//定义要发送的计算机的地址
    31             EndPoint Remote = (EndPoint)(sender);//
    32             recv = newsock.ReceiveFrom(data, ref Remote);//接受数据          
    33             Console.WriteLine("Message received from{0}:", Remote.ToString());
    34             Console.WriteLine(Encoding.ASCII.GetBytes(data,0,recv));
    35 
    36             string welcome = "Welcome to my test server!";
    37             data = Encoding.ASCII.GetBytes(welcome);
    38             newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
    39             while (true)
    40             {
    41                 data = new byte[1024];
    42                 recv = newsock.ReceiveFrom(data, ref Remote);
    43                 Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
    44                 newsock.SendTo(data, recv, SocketFlags.None, Remote);
    45             }
    46         }
    47     }
    48 }
    49     对于接收流入的UDP服务器程序来说,必须将程序与本地系统中指定的UDP端口进行绑定。这就可以通过使用合适的本地IP地址创建一个IPEndPoint对象,以及何时的UDP端口号。上述范例程序中的UDP服务器能够在端口9050从网络上接收任意流入的UDP数据包。
    50    (3)UDP客户机
    51     UDP客户机程序与服务器程序非常类似。
    52     因为客户机不需要在指定的UDP端口等待流入的数据,因此,不使用Bind()方法,而是使用在数据发送时系统随机指定的一个UDP端口,而且使用同一个端口接收返回的消息。在看法产品时,要为客户机指定一套UDP端口,以便服务器和客户机程序使用相同的端口号。UDP客户机程序首先定义一个IPEndPoint,UDP服务器将发送数据包到这个IPEndPoint。如果在远程设备上运行UDP服务器程序,在IPEndPoint定义中必须输入适当的IP地址和UDP端口号信息。
    53 using System;
    54 using System.Collections.Generic;
    55 using System.Text;
    56 using System.Net;
    57 using System.Net.Sockets;
    58 namespace SimpleUdpClient
    59 {
    60     class Program
    61     {
    62         static void Main(string[] args)
    63         {
    64             byte[] data = new byte[1024];//定义一个数组用来做数据的缓冲区
    65             string input, stringData;
    66             IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);
    67             Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    68             string welcome = "Hello,are you there?";
    69             data = Encoding.ASCII.GetBytes(welcome);
    70             server.SendTo(data, data.Length, SocketFlags.None, ipep);//将数据发送到指定的终结点
    71 
    72             IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
    73             EndPoint Remote = (EndPoint)sender;
    74             data = new byte[1024];
    75             int recv = server.ReceiveFrom(data, ref Remote);//接受来自服务器的数据
    76 
    77             Console.WriteLine("Message received from{0}:", Remote.ToString());
    78             Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
    79             while (true)//读取数据
    80             {
    81                 input = Console.ReadLine();//从键盘读取数据
    82                 if (input == "text")//结束标记
    83                 {
    84                     break;
    85                 }
    86                 server.SendTo(Encoding.ASCII.GetBytes(input), Remote);//将数据发送到指定的终结点Remote
    87                 data = new byte[1024];
    88                 recv = server.ReceiveFrom(data, ref Remote);//从Remote接受数据
    89                 stringData = Encoding.ASCII.GetString(data, 0, recv);
    90                 Console.WriteLine(stringData);
    91             }
    92             Console.WriteLine("Stopping client");
    93             server.Close();
    94         }
    95     }
    96 }       
    97    (4)测试服务器与客户机
    98     由于条件的限制,测试是在一台电脑上进行的。所以在客户机的定义中是将发送和接收信息的地址设置为本机的。
    99     先启动服务器,在启动客户机,按照提示输入信息即可。
    复制代码
  • 相关阅读:
    解决servlet在web.xml中的路径跳转问题
    浅谈上市公司期权
    spring 与mybatis 整合总结
    学习ssm心得
    django中ORM的事务操作
    Celery快速入门
    vagrant 使用指南
    数据库之mysql
    python之pip
    linux基础
  • 原文地址:https://www.cnblogs.com/zoujinhua/p/11152661.html
Copyright © 2011-2022 走看看