-
C#教程之C#教程之C# Socket异步实现消息发送--附带源码(3)
本站最新发布 C#从入门到精通
试听地址 https://www.xin3721.com/eschool/CSharpxin3721/
try { var key = dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[0].Value + ":" + dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[1].Value; SendSocket send = new SendSocket() { Message = this.txt_Mes.Text.Trim() }; Send(dic_ip[key].clientSocket, send.ToArray()); } catch (Exception ex) { MessageBox.Show("error ex=" + ex.Message + " " + ex.StackTrace); } } /// <summary> /// 发送震动 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_SendShake_Click(object sender, EventArgs e) { //根据选中的IP端口 获取对应客户端Socket var key = dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[0].Value + ":" + dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[1].Value; if (dic_ip.ContainsKey(key)) { SendSocket send = new SendSocket() { SendShake = true, Message = "震动", }; Send(dic_ip[key].clientSocket, send.ToArray()); } else { MessageBox.Show("选中数据无效,找不到客户端"); } } /// <summary> /// 发送图片 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_SendImg_Click(object sender, EventArgs e) { var key = dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[0].Value + ":" + dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[1].Value; if (dic_ip.ContainsKey(key)) { //初始化一个OpenFileDialog类 OpenFileDialog fileDialog = new OpenFileDialog(); //判断用户是否正确的选择了文件 if (fileDialog.ShowDialog() == DialogResult.OK) { string extension = Path.GetExtension(fileDialog.FileName); string[] str = new string[] { ".gif", ".jpge", ".jpg", "bmp" };//准许上传格式 if (!((IList)str).Contains(extension)) { MessageBox.Show("仅能上传gif,jpge,jpg,bmp格式的图片!"); } FileInfo fileInfo = new FileInfo(fileDialog.FileName); if (fileInfo.Length > 26214400)//不能大于25 { MessageBox.Show("图片不能大于25M"); } //将图片转成base64发送 SendSocket send = new SendSocket() { SendImg = true, ImgName = fileDialog.SafeFileName, }; using (FileStream file = new FileStream(fileDialog.FileName, FileMode.Open, FileAccess.Read)) { var imgby = new byte[file.Length]; file.Read(imgby, 0, imgby.Length); send.ImgBase64 = Convert.ToBase64String(imgby); } Send(dic_ip[key].clientSocket, send.ToArray()); } } else { MessageBox.Show("请正确选择,选中客户端不存在"); } } #region Socket 发送和接收 /// <summary> /// 发送消息 /// </summary> /// <param name="s_socket">指定客户端socket</param> /// <param name="message">发送消息</param> /// <param name="Shake">发送消息</param> private void Send(Socket c_socket, byte[] by) { try { //发送 c_socket.BeginSend(by, 0, by.Length, SocketFlags.None, asyncResult => { try { //完成消息发送 int len = c_socket.EndSend(asyncResult); } catch (Exception ex) { if (c_socket != null) { c_socket.Close(); c_socket = null; } Console.WriteLine("error ex=" + ex.Message + " " + ex.StackTrace); } }, null); this.txt_Mes.Text = null; } catch (Exception ex) { if (c_socket != null) { c_socket.Close(); c_socket = null; } Console.WriteLine("error ex=" + ex.Message + " " + ex.StackTrace); } } /// <summary> /// 数据接收 /// </summary> /// <param name="ar">请求的Socket</param> private void ReadCallback(IAsyncResult ar) { //获取并保存 ClientState obj = ar.AsyncState as ClientState; Socket c_socket = obj.clientSocket; try { int bytes = c_socket.EndReceive(ar); #region 接收数据 if (bytes == 16) { byte[] buf = obj.buffer; //判断头部是否正确 标识0-3 8888 if (buf[0] == 8 && buf[1] == 8 && buf[2] == 8 && buf[3] == 8) { //判断是否为震动 标识12-15 1111 if (buf[12] == 1 && buf[13] == 1 && buf[14] == 1 && buf[15] == 1) { //实现震动效果 this.BeginInvoke((MethodInvoker)delegate () { int x = 5, y = 10; for (int i = 0; i < 5; i++) { this.Left += x; Thread.Sleep(y); this.Top += x; Thread.Sleep(y); this.Left -= x; Thread.Sleep(y); this.Top -= x; Thread.Sleep(y); } }); } else { int totalLength = BitConverter.ToInt32(buf, 4);//获取数据总长度 //获取内容长度 int contentLength = BitConverter.ToInt32(buf, 8); obj.buffer = new byte[contentLength]; int readDataPtr = 0; while (readDataPtr < contentLength)//判断内容是否接收完成 { var re = c_socket.Receive(obj.buffer, readDataPtr, contentLength - readDataPtr, SocketFlags.None);//接收内容 readDataPtr += re; } //转换显示 UTF8 var str = Encoding.UTF8.GetString(obj.buffer, 0, contentLength); if (buf[12] == 2 && buf[13] == 2 && buf[14] == 2 && buf[15] == 2) { #region 解析报文 //显示到listbox this.BeginInvoke((MethodInvoker)delegate () { var time = DateTime.Now.ToString(); this.listBox_Mes.Items.Add(time + " " + c_socket.RemoteEndPoint.ToString()); this.listBox_Mes.Items.Add("接收到图片"); this.listBox_attribute.Items.Add(DateTime.Now.ToString()); this.listBox_attribute.Items.Add("数据总长度 " + totalLength + " 内容长度 " + contentLength); }); try { //解析XML 获取图片名称和BASE64字符串 XmlDocument document = new XmlDocument(); document.LoadXml(str); XmlNodeList root = document.SelectNodes("/ImgMessage"); string imgNmae = string.Empty, imgBase64 = string.Empty; foreach (XmlElement node in root) { imgNmae = node.GetElementsByTagName("ImgName")[0].InnerText; imgBase64 = node.GetElementsByTagName("ImgBase64")[0].InnerText; } //BASE64转成图片 byte[] imgbuf = Convert.FromBase64String(imgBase64); using (System.IO.MemoryStream m_Str = new System.IO.MemoryStream(imgbuf)) { using (Bitmap bit = new Bitmap(m_Str)) { //保存到本地并上屏 var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, imgNmae); bit.Save(path); pictureBox1.BeginInvoke((MethodInvoker)delegate () { lab_ImgName.Text = imgNmae; pictureBox1.ImageLocation = path; }); } } } catch (Exception ex) { Console.WriteLine(ex.Message + " " + ex.StackTrace); } #endregion } else { //显示到listbox this.BeginInvoke((MethodInvoker)delegate () { var time = DateTime.Now.ToString(); this.listBox_Mes.Items.Add(time + " " + c_socket.RemoteEndPoint.ToString()); this.listBox_Mes.Items.Add(str); this.listBox_attribute.Items.Add(DateTime.Now.ToString()); this.listBox_attribute.Items.Add("数据总长度 " + totalLength + " 内容长度 " + contentLength); }); } } } //接收完成 重新给出buffer接收 obj.buffer = new byte[ClientState.bufsize]; c_socket.BeginReceive(obj.buffer, 0, ClientState.bufsize, 0, new AsyncCallback(ReadCallback), obj); } else { UpdateControls(c_socket); } #endregion } catch (Exception ex) { UpdateControls(c_socket); } } /// <summary> /// 关闭指定客户端 更新控件 /// </summary> /// <param name="socket"></param> public void UpdateControls(Socket socket) { dic_ip.Remove(socket.RemoteEndPoint.ToString()); List<int> list = new List<int>(); for (int i = 0; i < dataGridView1.RowCount; i++) { var val = dataGridView1.Rows[i].Cells[0].Value + ":" + dataGridView1.Rows[i].Cells[1].Value; if (val != null && val.ToString() == socket.RemoteEndPoint.ToString()) { list.Add(i); } } this.BeginInvoke((MethodInvoker)delegate () { foreach (var item in list) { dataGridView1.Rows.Remove(dataGridView1.Rows[item]); } }); socket.Close(); socket.Dispose(); } #endregion /// <summary> /// 停止 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_Stop_Click(object sender, EventArgs e) { s_socket.Close(); this.txt_ip.Enabled = true; this.txt_port.Enabled = true; this.txt_Monitor.Text = null; } } }
试听地址 https://www.xin3721.com/eschool/CSharpxin3721/
try { var key = dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[0].Value + ":" + dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[1].Value; SendSocket send = new SendSocket() { Message = this.txt_Mes.Text.Trim() }; Send(dic_ip[key].clientSocket, send.ToArray()); } catch (Exception ex) { MessageBox.Show("error ex=" + ex.Message + " " + ex.StackTrace); } } /// <summary> /// 发送震动 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_SendShake_Click(object sender, EventArgs e) { //根据选中的IP端口 获取对应客户端Socket var key = dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[0].Value + ":" + dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[1].Value; if (dic_ip.ContainsKey(key)) { SendSocket send = new SendSocket() { SendShake = true, Message = "震动", }; Send(dic_ip[key].clientSocket, send.ToArray()); } else { MessageBox.Show("选中数据无效,找不到客户端"); } } /// <summary> /// 发送图片 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_SendImg_Click(object sender, EventArgs e) { var key = dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[0].Value + ":" + dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[1].Value; if (dic_ip.ContainsKey(key)) { //初始化一个OpenFileDialog类 OpenFileDialog fileDialog = new OpenFileDialog(); //判断用户是否正确的选择了文件 if (fileDialog.ShowDialog() == DialogResult.OK) { string extension = Path.GetExtension(fileDialog.FileName); string[] str = new string[] { ".gif", ".jpge", ".jpg", "bmp" };//准许上传格式 if (!((IList)str).Contains(extension)) { MessageBox.Show("仅能上传gif,jpge,jpg,bmp格式的图片!"); } FileInfo fileInfo = new FileInfo(fileDialog.FileName); if (fileInfo.Length > 26214400)//不能大于25 { MessageBox.Show("图片不能大于25M"); } //将图片转成base64发送 SendSocket send = new SendSocket() { SendImg = true, ImgName = fileDialog.SafeFileName, }; using (FileStream file = new FileStream(fileDialog.FileName, FileMode.Open, FileAccess.Read)) { var imgby = new byte[file.Length]; file.Read(imgby, 0, imgby.Length); send.ImgBase64 = Convert.ToBase64String(imgby); } Send(dic_ip[key].clientSocket, send.ToArray()); } } else { MessageBox.Show("请正确选择,选中客户端不存在"); } } #region Socket 发送和接收 /// <summary> /// 发送消息 /// </summary> /// <param name="s_socket">指定客户端socket</param> /// <param name="message">发送消息</param> /// <param name="Shake">发送消息</param> private void Send(Socket c_socket, byte[] by) { try { //发送 c_socket.BeginSend(by, 0, by.Length, SocketFlags.None, asyncResult => { try { //完成消息发送 int len = c_socket.EndSend(asyncResult); } catch (Exception ex) { if (c_socket != null) { c_socket.Close(); c_socket = null; } Console.WriteLine("error ex=" + ex.Message + " " + ex.StackTrace); } }, null); this.txt_Mes.Text = null; } catch (Exception ex) { if (c_socket != null) { c_socket.Close(); c_socket = null; } Console.WriteLine("error ex=" + ex.Message + " " + ex.StackTrace); } } /// <summary> /// 数据接收 /// </summary> /// <param name="ar">请求的Socket</param> private void ReadCallback(IAsyncResult ar) { //获取并保存 ClientState obj = ar.AsyncState as ClientState; Socket c_socket = obj.clientSocket; try { int bytes = c_socket.EndReceive(ar); #region 接收数据 if (bytes == 16) { byte[] buf = obj.buffer; //判断头部是否正确 标识0-3 8888 if (buf[0] == 8 && buf[1] == 8 && buf[2] == 8 && buf[3] == 8) { //判断是否为震动 标识12-15 1111 if (buf[12] == 1 && buf[13] == 1 && buf[14] == 1 && buf[15] == 1) { //实现震动效果 this.BeginInvoke((MethodInvoker)delegate () { int x = 5, y = 10; for (int i = 0; i < 5; i++) { this.Left += x; Thread.Sleep(y); this.Top += x; Thread.Sleep(y); this.Left -= x; Thread.Sleep(y); this.Top -= x; Thread.Sleep(y); } }); } else { int totalLength = BitConverter.ToInt32(buf, 4);//获取数据总长度 //获取内容长度 int contentLength = BitConverter.ToInt32(buf, 8); obj.buffer = new byte[contentLength]; int readDataPtr = 0; while (readDataPtr < contentLength)//判断内容是否接收完成 { var re = c_socket.Receive(obj.buffer, readDataPtr, contentLength - readDataPtr, SocketFlags.None);//接收内容 readDataPtr += re; } //转换显示 UTF8 var str = Encoding.UTF8.GetString(obj.buffer, 0, contentLength); if (buf[12] == 2 && buf[13] == 2 && buf[14] == 2 && buf[15] == 2) { #region 解析报文 //显示到listbox this.BeginInvoke((MethodInvoker)delegate () { var time = DateTime.Now.ToString(); this.listBox_Mes.Items.Add(time + " " + c_socket.RemoteEndPoint.ToString()); this.listBox_Mes.Items.Add("接收到图片"); this.listBox_attribute.Items.Add(DateTime.Now.ToString()); this.listBox_attribute.Items.Add("数据总长度 " + totalLength + " 内容长度 " + contentLength); }); try { //解析XML 获取图片名称和BASE64字符串 XmlDocument document = new XmlDocument(); document.LoadXml(str); XmlNodeList root = document.SelectNodes("/ImgMessage"); string imgNmae = string.Empty, imgBase64 = string.Empty; foreach (XmlElement node in root) { imgNmae = node.GetElementsByTagName("ImgName")[0].InnerText; imgBase64 = node.GetElementsByTagName("ImgBase64")[0].InnerText; } //BASE64转成图片 byte[] imgbuf = Convert.FromBase64String(imgBase64); using (System.IO.MemoryStream m_Str = new System.IO.MemoryStream(imgbuf)) { using (Bitmap bit = new Bitmap(m_Str)) { //保存到本地并上屏 var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, imgNmae); bit.Save(path); pictureBox1.BeginInvoke((MethodInvoker)delegate () { lab_ImgName.Text = imgNmae; pictureBox1.ImageLocation = path; }); } } } catch (Exception ex) { Console.WriteLine(ex.Message + " " + ex.StackTrace); } #endregion } else { //显示到listbox this.BeginInvoke((MethodInvoker)delegate () { var time = DateTime.Now.ToString(); this.listBox_Mes.Items.Add(time + " " + c_socket.RemoteEndPoint.ToString()); this.listBox_Mes.Items.Add(str); this.listBox_attribute.Items.Add(DateTime.Now.ToString()); this.listBox_attribute.Items.Add("数据总长度 " + totalLength + " 内容长度 " + contentLength); }); } } } //接收完成 重新给出buffer接收 obj.buffer = new byte[ClientState.bufsize]; c_socket.BeginReceive(obj.buffer, 0, ClientState.bufsize, 0, new AsyncCallback(ReadCallback), obj); } else { UpdateControls(c_socket); } #endregion } catch (Exception ex) { UpdateControls(c_socket); } } /// <summary> /// 关闭指定客户端 更新控件 /// </summary> /// <param name="socket"></param> public void UpdateControls(Socket socket) { dic_ip.Remove(socket.RemoteEndPoint.ToString()); List<int> list = new List<int>(); for (int i = 0; i < dataGridView1.RowCount; i++) { var val = dataGridView1.Rows[i].Cells[0].Value + ":" + dataGridView1.Rows[i].Cells[1].Value; if (val != null && val.ToString() == socket.RemoteEndPoint.ToString()) { list.Add(i); } } this.BeginInvoke((MethodInvoker)delegate () { foreach (var item in list) { dataGridView1.Rows.Remove(dataGridView1.Rows[item]); } }); socket.Close(); socket.Dispose(); } #endregion /// <summary> /// 停止 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btn_Stop_Click(object sender, EventArgs e) { s_socket.Close(); this.txt_ip.Enabled = true; this.txt_port.Enabled = true; this.txt_Monitor.Text = null; } } }
声明的类:
using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; namespace SocketService { /// <summary> /// 接收消息 /// </summary> public class ClientState { public Socket clientSocket = null; public const int bufsize = 16; public byte[] buffer = new byte[bufsize]; public StringBuilder str = new StringBuilder(); } /// <summary> /// 显示客户端IP 端口 /// </summary> public class ClientClass { public string IP { get; set; } public string Port { get; set; } } /// <summary> /// 0-3 标识码 4-7 总长度 8-11 内容长度 12-15补0 16开始为内容 /// </summary> public class SendSocket { /// <summary> /// 头 标识8888 /// </summary> byte[] Header = new byte[4] { 0x08, 0x08, 0x08, 0x08 }; /// <summary> /// 文本消息 /// </summary> public string Message; /// <summary> /// 是否发送震动 /// </summary> public bool SendShake = false; /// <summary> /// 是否发送图片 /// </summary> public bool SendImg = false; /// <summary> /// 图片名称 /// </summary> public string ImgName; /// <summary> /// 图片数据 /// </summary> public string ImgBase64; /// <summary> /// 组成特定格式的byte数据 /// 12-15 为指定发送内容 1111(震动) 2222(图片数据) /// </summary> /// <param name="mes">文本消息</param> /// <param name="Shake">震动</param> /// <param name="Img">图片</param> /// <returns>特定格式的byte</returns> public byte[] ToArray() { if (SendImg)//是否发送图片 { //组成XML接收 可以接收相关图片数据 StringBuilder xmlResult = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); xmlResult.Append("<ImgMessage>"); xmlResult.AppendFormat("<ImgName>{0}</ImgName>", ImgName); xmlResult.AppendFormat("<ImgBase64>{0}</ImgBase64>", ImgBase64); xmlResult.Append("</ImgMessage>"); Message = xmlResult.ToString(); } byte[] byteData = Encoding.UTF8.GetBytes(Message);//内容 int count = 16 + byteData.Length;//总长度 byte[] SendBy = new byte[count]; Array.Copy(Header, 0, SendBy, 0, Header.Length);//添加头 byte[] CountBy = BitConverter.GetBytes(count); Array.Copy(CountBy, 0, SendBy, 4, CountBy.Length);//总长度 byte[] ContentBy = BitConverter.GetBytes(byteData.Length); Array.Copy(ContentBy, 0, SendBy, 8, ContentBy.Length);//内容长度 if (SendShake)//发动震动 { var shakeBy = new byte[4] { 1, 1, 1, 1 }; Array.Copy(shakeBy, 0, SendBy, 12, shakeBy.Length);//震动 } if (SendImg)//发送图片 { var imgBy = new byte[4] { 2, 2, 2, 2 }; Array.Copy(imgBy, 0, SendBy, 12, imgBy.Length);//图片 } Array.Copy(byteData, 0, SendBy, 16, byteData.Length);//内容 return SendBy; } } }
客户端
窗体(UI)代码:
namespace SocketClient { partial class Form1 { /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 清理所有正在使用的资源。 /// </summary> /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要修改 /// 使用代码编辑器修改此方法的内容。 /// </summary> private void InitializeComponent() { this.btn_StopSocket = new System.Windows.Forms.Button(); this.txt_Monitor = new System.Windows.Forms.TextBox(); this.label3 = new System.Windows.Forms.Label(); this.btn_StartSocket = new System.Windows.Forms.Button(); this.txt_port = new System.Windows.Forms.TextBox(); this
栏目列表
最新更新
如何使用OS模块中的stat方法
Python os 模块
seek() 方法
python打开文件实例1
Python写入文件
什么是流?
文件操作如何进制逐行读取
Python相对路径
with创建临时运行环境
Python文件操作
.Net Standard(.Net Core)实现获取配置信息
Linux PXE + Kickstart 自动装机
Shell 编程 基础
Shell 编程 条件语句
CentOS8-网卡配置及详解
Linux中LVM逻辑卷管理
1.数码相框-相框框架分析(1)
Ubuntu armhf 版本国内源
Linux中raid磁盘阵列
搭建简易网站
access教程之Access简介
mysql 安装了最新版本8.x版本后的报错:
Mysql空间数据&空间索引(spatial)
如何远程连接SQL Server数据库的图文教程
复制SqlServer数据库的方法
搜索sql语句
sql中返回参数的值
sql中生成查询的模糊匹配字符串
数据定义功能
数据操作功能