前面学习了Tcp通讯之后听老师同学们讲到Udp也可以通讯,实现还要跟简单,没有繁琐的连接,所以最近学习了一下,记录下来以便忘记,同时也发表出来与大家相互学习,下面是我自己写的一个聊天例子,实现了群聊私聊等功能。

通讯类(UdpInfo)

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Model
{
[Serializable]
public class UdpInfo
{
public string Name { get; set; }
public string Ip { get; set; }
public string Port { get; set; }
public string Message { get; set; }
public int Types { get; set; }//消息的类型
public bool IsFist { get; set; }//判断加载的成员是否是第一个
public string ToName { get; set; }//与谁私聊
public string LoginName { get; set; }//新加入成员的名字
}
}

服务器(Server)

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using Model; namespace Server
{
public partial class forUdp : Form
{
public forUdp()
{
InitializeComponent();
}
UdpClient server = null;
IPEndPoint ipEndPoint = null;
List<IPEndPoint> pointList = new List<IPEndPoint>();//成员集合
private delegate void BindDelegate(UdpInfo u);//(绑定信息)
BindDelegate bd = null;
private bool flag;//是否为添加的第一个成员
private string loginName;
private void Form1_Load(object sender, EventArgs e)
{
txtPort.Text = "";//默认的端口
}
public void Receices()//接收客户端的消息
{
while (true)
{
try
{
byte[] bytes = server.Receive(ref ipEndPoint);//获取消息
UdpInfo u = DeserializeObject(bytes) as UdpInfo;
bd = new BindDelegate(BindRtb);
this.Invoke(bd, u);
}
catch (Exception)
{
server.Close();//有异常关闭服务
}
}
}
public object DeserializeObject(byte[] pBytes)//反序列化二进制为对象
{
object newOjb = null;
if (pBytes == null)
return newOjb;
MemoryStream memory = new MemoryStream(pBytes);
memory.Position = ;
BinaryFormatter formatter = new BinaryFormatter();
newOjb = formatter.Deserialize(memory);
memory.Close();
return newOjb;
}
public byte[] SerializeObject(object pObj)//序列化对象为二进制的数
{
if (pObj == null)
return null;
MemoryStream memory = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(memory, pObj);
memory.Position = ;
byte[] read = new byte[memory.Length];
memory.Read(read, , read.Length);
memory.Close();
return read;
}
public void BindRtb(UdpInfo u) //添加信息,绑定信息
{
if(u.Types == )//如果消息类型为上线
{
pointList.Add(ipEndPoint);//添加成员
//u.Name = "1";
//获取需要的基本信息
loginName = u.Name;
u.Ip = ipEndPoint.ToString().Split(':')[];
u.Port = ipEndPoint.ToString().Split(':')[];
byte[] bytes = SerializeObject(u);
ListViewItem item = new ListViewItem(u.Name);//绑定添加到成员列表上
item.SubItems.Add(u.Ip);
item.SubItems.Add(u.Port);
lvInfo.Items.Add(item);//显示成员信息
BindListView(loginName);//成员发生改变的时候,发送成员信息给客户端,刷新客户端的成员信息
}
else if (u.Types == )//如果消息的类型是群聊的话就执行
{
foreach (ListViewItem items in lvInfo.Items)//循环每个成员
{
IPAddress ip = IPAddress.Parse(items.SubItems[].Text);
IPEndPoint ipEndPoint = new IPEndPoint(ip, Convert.ToInt32(items.SubItems[].Text));
byte[] bytes = SerializeObject(u);
server.Send(bytes, bytes.Length, ipEndPoint);//给每个用户发送信息
}
}
else if (u.Types == )//消息的类型是私聊
{
foreach(ListViewItem items in lvInfo.Items)
{
//如果该成员是指定成员才发送信息
if(u.ToName.Equals(items.SubItems[].Text))
{
IPAddress ip = IPAddress.Parse(items.SubItems[].Text);
IPEndPoint ipEndPoint = new IPEndPoint(ip, Convert.ToInt32(items.SubItems[].Text));
byte[] bytes = SerializeObject(u);
server.Send(bytes, bytes.Length, ipEndPoint);//发送消息给指定的用户
}
}
}
else if(u.Types == )//如果消息的类型是下线的话
{
IPEndPoint ipEndPoint = null;
foreach (ListViewItem items in lvInfo.Items)//循环每个成员
{
IPAddress ip = IPAddress.Parse(items.SubItems[].Text);
ipEndPoint = new IPEndPoint(ip, Convert.ToInt32(items.SubItems[].Text));
if(items.SubItems[].Text.Equals(u.Name))
{
lvInfo.Items.Remove(items);//从ListView集合中移除
pointList.Remove(ipEndPoint);//从List<IPEndPoint>集合中移除
continue;
}
byte[] bytes = SerializeObject(u);
server.Send(bytes, bytes.Length, ipEndPoint);//给每个用户发送信息
}
}
//服务器接收所有的消息
rtbMessage.Text += "\n" + u.Name + ":" + u.Message;
}
public void BindListView(string loginName) //有新成员加入的时候就绑定刷新成员列表
{
flag = true;
foreach (ListViewItem items in lvInfo.Items)//循环每个用户
{
foreach (ListViewItem item in lvInfo.Items)//给每个用户发送全部的成员信息
{
UdpInfo u = new UdpInfo();
u.Name = item.SubItems[].Text.ToString();
u.IsFist = flag;//添加第一个成员的时候因为要重新初始化客户端成员列表,而剩下的则不要初始化,所以要设置为true
flag = false;
u.LoginName = loginName;
u.Message = "上线了!";
u.Ip = item.SubItems[].Text.ToString();
u.Port = item.SubItems[].Text.ToString();
byte[] bytes = SerializeObject(u);
IPAddress ip = IPAddress.Parse(items.SubItems[].Text);
IPEndPoint ipp = new IPEndPoint(ip, Convert.ToInt32(items.SubItems[].Text));//得到成员的IPEndPoint
server.Send(bytes, bytes.Length, ipp);
}
}
}
private void 结束程序ToolStripMenuItem_Click(object sender, EventArgs e)
{
server.Close();
this.Dispose();
Application.Exit();
} private void 运行程序ToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbMessage.Text = "可以发送消息过来了!";
int port = Convert.ToInt32(txtPort.Text);
server = new UdpClient(port);
ipEndPoint = new IPEndPoint(IPAddress.Any, port);
Thread t = new Thread(new ThreadStart(Receices));
t.Start();
}
}
}

客户端(Client)

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Model;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary; namespace Client
{
public partial class forUdp : Form
{
public forUdp()
{
InitializeComponent();
}
UdpClient client = null;
IPEndPoint ipEndPoints = null;
private delegate void BindDelegate(UdpInfo u);
BindDelegate bd = null;
private void forUdp_Load(object sender, EventArgs e)
{
txtIP.Text = "192.168.1.109";
txtPort.Text = "";
txtName.Text = "小哈";
} private void 运行程序ToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbMessage.Text = "可以发送消息过去了!";
int port = Convert.ToInt32(txtPort.Text);
ipEndPoints = new IPEndPoint(IPAddress.Parse(txtIP.Text), port);
client = new UdpClient();
client.Connect(IPAddress.Parse(txtIP.Text), port);//关联此IP和端口
Send(new UdpInfo() {Name = txtName.Text,Message = "上线了!", Types = });
Thread t = new Thread(new ThreadStart(Receices));
t.Start();
} public void Receices()//接收客户端的消息
{
while (true)
{
try
{
byte[] bytes = client.Receive(ref ipEndPoints);
UdpInfo u = DeserializeObject(bytes) as UdpInfo;
bd = new BindDelegate(BindRtb);
this.Invoke(bd, u);
}
catch (Exception)
{
client.Close();
}
}
}
public object DeserializeObject(byte[] pBytes)//反序列化二进制为对象
{
object newOjb = null;
if (pBytes == null)
return newOjb;
MemoryStream memory = new MemoryStream(pBytes);
memory.Position = ;
BinaryFormatter formatter = new BinaryFormatter();
newOjb = formatter.Deserialize(memory);
memory.Close();
return newOjb;
}
public byte[] SerializeObject(object pObj)//序列化对象为二进制的数
{
if (pObj == null)
return null;
MemoryStream memory = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(memory, pObj);
memory.Position = ;
byte[] read = new byte[memory.Length];
memory.Read(read, , read.Length);
memory.Close();
return read;
}
public void BindRtb(UdpInfo u)//将消息添加到消息框中
{
if (u.Types == )
{
if (u.IsFist == true)
lvInfo.Items.Clear();
ListViewItem item = new ListViewItem(u.Name);
item.SubItems.Add(u.Ip);
item.SubItems.Add(u.Port);
lvInfo.Items.Add(item);
}
else if (u.Types == )//如果消息的类型是下线的话
{
IPEndPoint ipEndPoint = null;
foreach (ListViewItem items in lvInfo.Items)//循环每个成员
{
if (items.SubItems[].Text.Equals(u.Name))
{
IPAddress ip = IPAddress.Parse(items.SubItems[].Text);
ipEndPoint = new IPEndPoint(ip, Convert.ToInt32(items.SubItems[].Text));
lvInfo.Items.Remove(items);//从ListView集合中移除
continue;
}
}
}
foreach (ListViewItem items in lvInfo.Items)
{
if(items.SubItems[].Text.Equals(u.LoginName))
rtbMessage.Text += "\n" + u.Name + ":" + u.Message;
}
}
public void Send(UdpInfo u)//发送消息给服务器
{
byte[] bytes = SerializeObject(u);
client.Send(bytes, bytes.Length);
}
private void 结束程序ToolStripMenuItem_Click(object sender, EventArgs e)
{
Send(new UdpInfo() { Name = txtName.Text, Message = "下线了!", Types = });
client.Close();
Application.Exit();
} private void btnSend_Click(object sender, EventArgs e)
{
UdpInfo u = new UdpInfo() {
Name = txtName.Text, Message = rtbNews.Text, Types =
};
if (lvInfo.SelectedItems.Count > )//如果有选中的成员的话
{
u.Types = ;
u.ToName = lvInfo.SelectedItems[].SubItems[].Text;
}
Send(u);
lvInfo.SelectedItems.Clear();//清除上一次的痕迹
}
}
}

Udp通讯(零基础)的更多相关文章

  1. java基础55 UDP通讯协议和TCP通讯协议

    本文知识点(目录): 1.概述    2.UDP通讯协议    3.TCPP通讯协议 1.概述 1.在java中网络通讯作为Socket(插座)通讯,要求两台都必须安装socket.    2.不同的 ...

  2. IM开发者的零基础通信技术入门(二):通信交换技术的百年发展史(下)

    1.系列文章引言 1.1 适合谁来阅读? 本系列文章尽量使用最浅显易懂的文字.图片来组织内容,力求通信技术零基础的人群也能看懂.但个人建议,至少稍微了解过网络通信方面的知识后再看,会更有收获.如果您大 ...

  3. IM开发者的零基础通信技术入门(一):通信交换技术的百年发展史(上)

    [来源申明]本文原文来自:微信公众号“鲜枣课堂”,官方网站:xzclass.com,原题为:<通信交换的百年沧桑(上)>,本文引用时已征得原作者同意.为了更好的内容呈现,即时通讯网在收录时 ...

  4. IM开发者的零基础通信技术入门(三):国人通信方式的百年变迁

    [来源申明]本文原文来自:微信公众号“鲜枣课堂”,官方网站:xzclass.com,原题为:<中国通信的百年沉浮>,本文引用时已征得原作者同意.为了更好的内容呈现,即时通讯网在收录时内容有 ...

  5. 如何从零基础学习VR

    转载请声明转载地址:http://www.cnblogs.com/Rodolfo/,违者必究. 近期很多搞技术的朋友问我,如何步入VR的圈子?如何从零基础系统性的学习VR技术? 本人将于2017年1月 ...

  6. 零基础学习hadoop到上手工作线路指导

    零基础学习hadoop,没有想象的那么困难,也没有想象的那么容易.在刚接触云计算,曾经想过培训,但是培训机构的选择就让我很纠结.所以索性就自己学习了.整个过程整理一下,给大家参考,欢迎讨论,共同学习. ...

  7. FFMPEG视音频编解码零基础学习方法-b

    感谢大神分享,虽然现在还看不懂,留着大家一起看啦 PS:有不少人不清楚“FFmpeg”应该怎么读.它读作“ef ef em peg” 0. 背景知识 本章主要介绍一下FFMPEG都用在了哪里(在这里仅 ...

  8. [总结]FFMPEG视音频编解码零基础学习方法

    在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...

  9. Hadoop 2.x从零基础到挑战百万年薪第一季

    鉴于目前大数据Hadoop 2.x被企业广泛使用,在实际的企业项目中需要更加深入的灵活运用,并且Hadoop 2.x是大数据平台处理 的框架的基石,尤其在海量数据的存储HDFS.分布式资源管理和任务调 ...

随机推荐

  1. 2.SDK目录结构和adb工具及命令介绍

    安卓开发学习笔记 1.安卓开发之环境搭建 2.SDK目录结构和adb工具及命令介绍 1.SDK目录介绍: ******************************** add-ons:Androi ...

  2. Windows Azure Virtual Machine (30) 修改Azure VM 的Subnet

    <Windows Azure Platform 系列文章目录> 我在使用Azure Virtual Machine虚拟机的时候,常常会结合Virtual Network虚拟网络一起使用. ...

  3. Windows Azure Active Directory (1) 前言 - 基于声明的验证和授权

    <Windows Azure Platform 系列文章目录> 在我们介绍整套系统架构之前,我们需要首先定义一些基本的概念. 用户及其属性: 用户值得是要使用某项服务的个体.用户一般都有一 ...

  4. CSS易混淆知识点总结与分享-定位与布局

    CSS定位有四种模式:static.relative.absolute.fixed,其它static是默认值,下面分别讲解下各自的特点: static:静态定位,处于动态布局流中,按照页面中的各元素先 ...

  5. 《Inside UE4》-0-开篇

    <Inside UE4>-0-开篇 InsideUE4   前言 VR行业发展是越来越火热了,硬件设备上有HTC VIVE,Oculus rift,PS VR,各种魔镜:平台上有Steam ...

  6. 跟着官网的例子学Reacjs (一)FilterableProductTable

    最近开始学习React,发现最好的方法不是看这个书那个书,而是直接上官网,一步步的跟着学习,真的获益匪浅.许多翻译的书上漏掉的知识点都可以学到. 入门的一些准备工作可以参照官网的步骤,引入依赖的核心包 ...

  7. WMI 硬件类简单介绍,默认打印机

    获取默认打印机: SELECT * FROM Win32_Printer WHERE Default=True 常用的几个WMI: 主板:Win32_BaseBoard http://msdn.mic ...

  8. WCF快速上手

    需求:在同一台机子上,有一个B/S程序,和一个C/S程序(不要问为什么,事实就是这样),B/S程序需要主动和C/S程序通信(C/S程序主动与B/S程序通信的情况这里暂不讨论). 下面以最快的速度写一个 ...

  9. 对于一些Http远程连接Api安全的看法;

    文章来源于 :http://lesg.cn/?p=122 我的个人博客站点 对于一些Http远程连接Api安全的看法: 当不同系统需要互相通信的时候:如果无法用webservice等方式链接的时候另一 ...

  10. .NET框架体系结构

    刚开始接触.NET很疑惑,看完视频也不是太懂,通过总结和反复,从概括和概念入手,慢慢变得清晰了.这篇博客主要是我对.NET基础知识的了解,算作积累吧. .NET框架体系结构 由四个主要部分组成     ...