当前位置:
首页 > Python基础教程 >
-
C#教程之C# Socket异步实现消息发送--附带源码(5)
/// <param name="e"></param>
private void btn_SendImg_Click(object sender, EventArgs e)
{
//初始化一个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[this.txt_Monitor.Text.Trim()].serviceSocket, send.ToArray());
}
}
/// <summary>
/// 关闭socket
/// </summary>
public void Stop()
{
var key = this.txt_Monitor.Text.Trim();
if (dic_ip.ContainsKey(key))
{
dic_ip.Remove(key);
}
if (c_socket == null)
return;
if (!c_socket.Connected)
return;
try
{
c_socket.Close();
}
catch
{
}
this.txt_ip.Enabled = true;
this.txt_port.Enabled = true;
this.txt_Monitor.Text = null;
}
/// <summary>
/// 连接Socket
/// </summary>
public void Start()
{
try
{
string ip = this.txt_ip.Text.Trim();
int port = int.Parse(this.txt_port.Text.Trim());
var endPoint = new IPEndPoint(IPAddress.Parse(ip), port);
c_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
c_socket.BeginConnect(endPoint, new AsyncCallback(Connect), c_socket);
}
catch (SocketException ex)
{
Console.WriteLine("error ex=" + ex.Message + " " + ex.StackTrace);
this.txt_ip.Enabled = true;
this.txt_port.Enabled = true;
}
}
#region Socket 连接 发送 接收
/// <summary>
/// 连接服务端
/// </summary>
/// <param name="ar"></param>
private void Connect(IAsyncResult ar)
{
try
{
ServiceState obj = new ServiceState();
Socket client = ar.AsyncState as Socket;
obj.serviceSocket = client;
//获取服务端信息
client.EndConnect(ar);
//添加到字典集合
dic_ip.Add(client.RemoteEndPoint.ToString(), obj);
//显示到txt文本
this.BeginInvoke((MethodInvoker)delegate ()
{
this.txt_Monitor.Text = client.RemoteEndPoint.ToString();
});
//接收连接Socket数据
client.BeginReceive(obj.buffer, 0, ServiceState.bufsize, SocketFlags.None, new AsyncCallback(ReadCallback), obj);
ConnectionResult = 0;
}
catch (SocketException ex)
{
ConnectionResult = ex.ErrorCode;
Console.WriteLine(ex.Message + " " + ex.StackTrace);
}
}
/// <summary>
/// 数据接收
/// </summary>
/// <param name="ar"></param>
private void ReadCallback(IAsyncResult ar)
{
ServiceState obj = ar.AsyncState as ServiceState;
Socket s_socket = obj.serviceSocket;
try
{
if (s_socket.Connected)
{
#region 接收数据处理
int bytes = s_socket.EndReceive(ar);
if (bytes == 16)
{
byte[] buf = obj.buffer;
//判断头部是否正确
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;
}
//转换显示
var str = Encoding.UTF8.GetString(obj.buffer, 0, contentLength); //转换显示 UTF8
if (buf[12] == 2 && buf[13] == 2 && buf[14] == 2 && buf[15] == 2)
{
#region 解析报文
//解析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;
});
}
}
#endregion
}
else
{
this.BeginInvoke((MethodInvoker)delegate ()
{
this.listBox1.Items.Add(DateTime.Now.ToString() + ":" + " 数据总长度 " + totalLength + " 内容长度 " + contentLength);
this.listBox1.Items.Add(s_socket.RemoteEndPoint.ToString() + " " + str);
});
}
}
}
obj.buffer = new byte[ServiceState.bufsize];
s_socket.BeginReceive(obj.buffer, 0, ServiceState.bufsize, 0, new AsyncCallback(ReadCallback), obj);
}
#endregion
}
}
catch (SocketException ex)
{
ConnectionResult = ex.ErrorCode;
Console.WriteLine(ex.Message + " " + ex.StackTrace);
}
}
/// <summary>
/// 发送
/// </summary>
/// <param name="s_socket"></param>
/// <param name="mes"></param>
private void Send(Socket s_socket, byte[] by)
{
try
{
//发送
s_socket.BeginSend(by, 0, by.Length, SocketFlags.None, asyncResult =>
{
try
{
//完成消息发送
int len = s_socket.EndSend(asyncResult);
}
catch (SocketException ex)
{
ConnectionResult = ex.ErrorCode;
Console.WriteLine(ex.Message + " " + ex.StackTrace);
}
}, null);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + " " + ex.StackTrace);
}
}
#endregion
}
}
声明的类:
using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.Xml; namespace SocketClient { /// <summary> /// 接收消息 /// </summary> public class ServiceState { public Socket serviceSocket = null; public const int bufsize = 16; public byte[] buffer = new byte[bufsize]; public StringBuilder str = new StringBuilder(); } /// <summary> /// 0-3 标识码 4-7 总长度 8-11 内容长度 12-15 补0/震动补1 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; } } }
百度云盘下载地址:
链接:https://pan.baidu.com/s/1l8N1IQJn7Os15PIuSs6YjA
提取码:dprj