一、摘要

  总结基于C#的UDP协议的同步通信。

二、实验平台

  Visual Studio 2010

三、实验原理

  UDP传输协议同TCP传输协议的区别可查阅相关文档,此处不再赘述。

四、实例

 4.1 采用socket实现UDP

  由于UDP是一种无连接的协议。因此,为了使服务器应用能够发送和接收UDP数据包,则需要做两件事情:
(1) 创建一个Socket对象;
(2) 将创建的套接字对象与本地IPEndPoint进行绑定。
  完成上述步骤后,那么创建的套接字就能够在IPEndPoint上接收流入的UDP数据包,或者将流出的UDP数据包发送到网络中其他任意设备。使用UDP进行通信时,不需要连接。因为异地的主机之间没有建立连接,所以UDP不能使用标准的Send()和Receive()t套接字方法,而是使用两个其他的方法:SendTo()和ReceiveFrom()。

SendTo()方法指定要发送的数据,和目标机器的IPEndPoint。该方法有多种不同的使用方法,可以根据具体的应用进行选择,但是至少要指定数据包和目标机器。如下:
    SendTo(byte[] data,EndPoint Remote)
    ReceiveFrom()方法同SendTo()方法类似,但是使用EndPoint对象声明的方式不一样。利用ref修饰,传递的不是一个EndPoint对象,而是将参数传递给一个EndPoint对象。

  UDP应用不是严格意义上的真正的服务器和客户机,而是平等的关系,即没有主与次的关系。为了简便起见,仍然把下面的这个应用叫做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");//得到客户机IPIPEndPoint 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地址创建一个IPEndPoint对象,以及合适的UDP端口号。上述范例程序中的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);//定义网络类型,数据连接类型和网络协议UDPSocket 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,IPV6private 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中的广播(broadcast)可以导致网络性能的下降甚至广播风暴(broadcast storm)。在IPv6中就不存在广播这一概念了,取而代之的是组播(multicast)和任意播(anycast)。

(2) IPV6地址表示方法:

a) X:X:X:X:X:X:X:X(每个X代表16位的16进制数字),不区分大小写;

b) 排头的0可省略,比如09C0就可以写成9C0,0000可以写成0;

c) 连续为0的字段可以以::来代替,但是整个地址中::只能出现一次,比如FF01:0:0:0:0:0:0:1就可以简写成FF01::1。

(3) 如果是采用窗体的形式建议使用这种格式,否则在接收数据时可能会出现死机的现象。

// 创建一个子线程
Thread thread = new Thread(delegate(){try{//在这里写你的代码
                    }catch (Exception ){}});thread.Start();

转载于:https://www.cnblogs.com/sunev/archive/2012/08/08/2627247.html

基于C#的UDP协议的同步实现相关推荐

  1. 基于TCP或UDP协议的应用层协议

    TCP和UDP都是传输层协议,上面是应用层,下面是网络层 TCP与UDP区别: TCP(传输控制协议)提供的是面向连接.可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连 ...

  2. udp协议没有粘包问题、基于socketserver实现并发的socket(基于tcp、udp协议)、基于udp协议的套接字、操作系统原理以及进程知识

    基于udp协议的套接字通信服务端 from socket import *server=socket(AF_INET,SOCK_DGRAM) #数据报协议->udp server.bind((' ...

  3. 基于Qt的UDP协议实现及解析数据

    一.前言 UDP 是一个不可靠的,面向数据报的协议.QUdpSocket 类可以用来发送和接收UDP数据报(datagram). 最常用的使用方式是使用bind()去绑定地址和端口号,然后使用writ ...

  4. PC基于wifi采用UDP协议实现ESP32无线图传显示在1.44寸屏幕

    开发环境:Ubuntu16.04 ESP32:Arduino PC图传:Python3.6.9 首先上python代码 import socket import cv2 import numpy as ...

  5. 基于 python 和 UDP 协议实现简易聊天室(多人群聊)----详细解析带字幕

    聊天室项目 功能介绍: 1.进入聊天室:输入姓名,用户名(不能重复) 2.某个成员进入聊天室后给其他所有所有成员发送消息 3.任何一个人发消息,其他人都会收到 4.某人退出聊天室,其他成员也会收到通知 ...

  6. 群聊系统项目(基于TCP、UDP实现)

    最近学习了网络编程后, 写了一个基于TCP.UDP协议的群聊系统. 技术栈 1.TCP.UDP通信       2.生产.消费模型, 支持并发       3.自定义协议封装数据 & json ...

  7. Socket:UDP协议小白

    UDP(user datagram protocol)用户数据报协议,属于传输层. 首先要搞清楚网络通信的几个层次: OSI 是 Open System Interconnection 的缩写,译为& ...

  8. 【JavaEE】TCP的五层协议栈之应用层与传输层的UDP协议

    文章目录 一.应用层 1.简单介绍 2.xml(Simple Object Access Protocol ) 2.json(JavaScript Object Notation) 4.protobu ...

  9. 【计算机网络】UDP协议

    目录 1. UDP协议头部格式 2. UDP协议的特点 2.1 无连接 2.2 不可靠 2.3 面向数据报 2.4 有接收缓冲区,没有发送缓冲区 2.5 大小受限 3. 基于UDP的应用层协议 4. ...

最新文章

  1. 湖北大学829数据库原理与c语言程序设计,2017年湖北大学教育学院829数据库原理与C语言程序设计考研强化模拟题...
  2. 世界AI大会三马纵论:马云乐观、马斯克悲观,马化腾认为技术孤立主义有大危害...
  3. 第一年的报告 工程系的研究生
  4. linux查看登录服务器的ip历史记录,通过登陆IP记录Linux所有用户登录所操作日志的方法...
  5. 深入学习SpringMVC以及学习总结
  6. Nhibernate出现No row with the given identifier exists问题的产生原因及解决方法
  7. Centos6.4系统局域网服务之DHCP
  8. 《Java编程思想》读书笔记-对象导论
  9. 【算法系列学习】Dijkstra单源最短路 [kuangbin带你飞]专题四 最短路练习 A - Til the Cows Come Home...
  10. linux安装远程桌面管理工具xrdp
  11. excel打开密码忘记了_Excel工作表密码忘记了怎么办?
  12. 用matlab编写SIR模型对SARS期间疫情数据进行模拟
  13. CentOS7安装DockerCentOS7安装DockerCompose
  14. 区别: @Secured(), @PreAuthorize() 及 @RolesAllowed()
  15. 2022中国智慧医疗领域最具商业合作价值企业盘点
  16. HEG安装教程以及闪退问题解决
  17. 易基因 | 精准医学:DNA甲基化图谱在发现和精确诊断神经肿瘤领域的应用
  18. 2022餐饮加盟3大核心,让赚钱变得简单
  19. utf8编码和utf8mb4编码(其它编码简介)
  20. vanta.js的使用(前端网站动态背景)

热门文章

  1. java的重点是什么_你知道初学者学习Java的重点是什么吗?
  2. pyqt怎么给字体加粗_微信拍一拍可设置后缀?怎么用?还有更多新功能!
  3. python image stiching_Python自然语言处理,词云图生成
  4. php 一秒操作一次_php守护进程 加linux命令nohup实现任务每秒执行一次
  5. 企业区块链应用程序的两个关键问题
  6. 力扣(LeetCode)刷题,简单题(第25期)
  7. OpenCV(十五)边缘检测1 -- Sobel算子(一阶微分算子,X、Y方向边缘检测)
  8. laravel carbon 格式化日期_Laravel 编码实践分享
  9. php slaveok_ZipArchive::open
  10. Tensorflow C++ API调用Keras模型实现RGB图像语义分割