zoukankan      html  css  js  c++  java
  • Socket无连接简单实例

    使用无连接的套接字,我们能够在自我包含的数据包里发送消息,采用独立的读函数读取消息,读取的消息是使用独立的发送函数发送的。但是UDP数据包不能保证可靠传输,存在许多的因素,比如网络繁忙等等,都有可能阻止数据包到达指定的目的地。
             (1)UDP的简单应用:
             由于UDP是一种无连接的协议。因此,为了使服务器应用能够发送和接收UDP数据包,则需要做两件事情:
             创建一个Socket对象;
             将创建的套接字对象与本地IPEndPoint进行绑定。
             完成上述步骤后,那么创建的套接字就能够在IPEndPoint上接收流入的UDP数据包,或者将流出的UDP数据包发送到网络中任意其他设备商。使用UDP进行通信时,不需要TCP连接。因为异地的主机之间没有建立连接,所以UDP不能使用标准的Send()和Receive()t套接字方法,而是使用两个其他的方法:SendTo()和ReceiveFrom()。
            SendTo()方法指定要发送的数据,和目标机器的IPEndPoint。该方法有多种不同的使用方法,可以根据具体的应用进行选择,但是至少要指定数据包和目标机器。如下:
            SendTo(byte[] data,EndPoint Remote)
            ReceiveFrom()方法同SendTo()方法类似,但是使用EndPoint对象声明的方式不一样。利用ref修饰,传递的不是一个EndPoint对象,而是将参数传递给一个EndPoint对象。
            (2)UDP服务器
            UDP应用不是严格意义上的真正的服务器和客户机,而是平等的关系,即没有主与次的关系。为了简便起见,仍然把下面的这个应用叫做UDP服务器。源代码如下:
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    namespace SimpleUdpSrvr
    {
        class Program
        {
            static void Main(string[] args)
            {
                int recv;
                byte[] data = new byte[1024];
                IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);//定义一网络端点
                Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);//定义一个Socket
                newsock.Bind(ipep);//Socket与本地的一个终结点相关联
                Console.WriteLine("Waiting for a client.....");

                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.GetBytes(data,0,recv));

                string welcome = "Welcome to my test server!";
                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地址创建一个IPEndPoint对象,以及何时的UDP端口号。上述范例程序中的UDP服务器能够在端口9050从网络上接收任意流入的UDP数据包。
            (3)UDP客户机
            UDP客户机程序与服务器程序非常类似。
            因为客户机不需要在指定的UDP端口等待流入的数据,因此,不使用Bind()方法,而是使用在数据发送时系统随机指定的一个UDP端口,而且使用同一个端口接收返回的消息。在看法产品时,要为客户机指定一套UDP端口,以便服务器和客户机程序使用相同的端口号。UDP客户机程序首先定义一个IPEndPoint,UDP服务器将发送数据包到这个IPEndPoint。如果在远程设备上运行UDP服务器程序,在IPEndPoint定义中必须输入适当的IP地址和UDP端口号信息。
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    namespace SimpleUdpClient
    {
        class Program
        {
            static void Main(string[] args)
            {
                byte[] data = new byte[1024];//定义一个数组用来做数据的缓冲区
                string input, stringData;
                IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);
                Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                string welcome = "Hello,are you there?";
                data = Encoding.ASCII.GetBytes(welcome);
                server.SendTo(data, data.Length, SocketFlags.None, ipep);//将数据发送到指定的终结点

                IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
                EndPoint Remote = (EndPoint)sender;
                data = new byte[1024];
                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 == "text")//结束标记
                    {
                        break;
                    }
                    server.SendTo(Encoding.ASCII.GetBytes(input), Remote);//将数据发送到指定的终结点Remote
                    data = new byte[1024];
                    recv = server.ReceiveFrom(data, ref Remote);//从Remote接受数据
                    stringData = Encoding.ASCII.GetString(data, 0, recv);
                    Console.WriteLine(stringData);
                }
                Console.WriteLine("Stopping client");
                server.Close();
            }
        }
    }       
             (4)测试服务器与客户机
              由于条件的限制,测试是在一台电脑上进行的。所以在客户机的定义中是将发送和接收信息的地址设置为本机的。
              先启动服务器,在启动客户机,按照提示输入信息即可。

    本文出自 “石头” 博客,请务必保留此出处http://rockchao.blog.51cto.com/133022/38849

  • 相关阅读:
    饮冰三年-人工智能-Python-35权限管理(万能的权限通用模块)
    饮冰三年-人工智能-Python-34CRM项目实战
    饮冰三年-人工智能-Python-33权限管理(通过配置快速生成列表)
    集腋成裘-15-MongoDB系列-02Find详细
    集腋成裘-14-MongoDB系列-01初识MongoDB
    饮冰三年-人工智能-Python-33博客园山寨版之报障管理
    饮冰三年-人工智能-Python-32博客园山寨版之后台管理
    JVM内存管理
    连接池实现原理
    定时器
  • 原文地址:https://www.cnblogs.com/armyfai/p/3534956.html
Copyright © 2011-2022 走看看