本章主要实现TCP客户端功能的实现,服务端功能实现参见https://blog.csdn.net/liwan09/article/details/106320516
一、项目创建
1、VS2017创建winform项目
2、Nuget搜索并安装SuperSocket.ClientEngine、SuperSocket.ProtoBase
二、客户端功能实现
1、页面设计
————————————————
2、后端代码
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 SuperSocket.ClientEngine;
using Newtonsoft.Json;
using SockectClient.Model;
namespace SockectClient
{
public partial class frmMain : Form
{
//EasyClient easyClient;
AsyncTcpSession asyncTcpSession;
public frmMain()
{
InitializeComponent();
}
private void frmMain_Load(object sender, EventArgs e)
{
this.txtIpAddress.Text = "127.0.0.1";
this.txtPort.Text = "4141";
this.btnDisconnect.Enabled = false;
}
/// <summary>
/// 启动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnConnect_Click(object sender, EventArgs e)
{
string ipAddress = txtIpAddress.Text.Trim();
int port = Convert.ToInt32(txtPort.Text.Trim());
#region AsyncTcpSession连接方式
asyncTcpSession = new AsyncTcpSession();
asyncTcpSession.Closed += client_Closed;
asyncTcpSession.Connected += client_Connected;
asyncTcpSession.Error += client_Error;
asyncTcpSession.DataReceived += client_DataReceived;
try
{
asyncTcpSession.Connect(new IPEndPoint(IPAddress.Parse(ipAddress), port));
txtLog.Text += "连接成功!\r\n";
txtIpAddress.Enabled = false;
txtPort.Enabled = false;
btnConnect.Enabled = false;
btnDisconnect.Enabled = true;
}
catch(Exception ex)
{
txtLog.Text += "连接失败!\r\n";
}
#endregion
#region EasyClient连接方式
//easyClient = new EasyClient();
//easyClient.Closed += client_Closed;
//easyClient.Connected += client_Connected;
//easyClient.Error += client_Error;
//easyClient.Initialize(new ReceiveFilter(), (request) =>
//{
// // handle the received request
//});
//var result=easyClient.ConnectAsync(new IPEndPoint(IPAddress.Parse(ipAddress), port));
//if (result.Result)
//{
// txtLog.Text += "连接成功!\r\n";
// txtIpAddress.Enabled = false;
// txtPort.Enabled = false;
// btnConnect.Enabled = false;
// btnDisconnect.Enabled = true;
//}
//else
//{
// txtLog.Text += "连接失败!\r\n";
//}
#endregion
}
/// <summary>
/// 数据接收事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void client_DataReceived(object sender, DataEventArgs e)
{
string msg = Encoding.Default.GetString(e.Data);
this.Invoke(new Action(() =>
{
txtLog.Text +="【"+DateTime.Now.ToString()+ "】接收的消息:\r\n"+msg+"\r\n";
}));
}
/// <summary>
/// 服务端关闭事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void client_Closed(object sender,EventArgs e)
{
//EasyClient client = sender as EasyClient;
AsyncTcpSession client = sender as AsyncTcpSession;
this.Invoke(new Action(() => {
txtLog.Text += "服务端关闭\r\n";
//easyClient = null;
asyncTcpSession = null;
txtIpAddress.Enabled = true;
txtPort.Enabled = true;
btnConnect.Enabled = true;
btnDisconnect.Enabled = false;
}));
}
/// <summary>
/// 连接事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void client_Connected(object sender, EventArgs e)
{
//EasyClient client = sender as EasyClient;
AsyncTcpSession client = sender as AsyncTcpSession;
}
/// <summary>
/// 错误事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void client_Error(object sender, ErrorEventArgs e)
{
//EasyClient client = sender as EasyClient;
AsyncTcpSession client = sender as AsyncTcpSession;
this.Invoke(new Action(()=> {
txtLog.Text += "Error:" + e.Exception + "\r\n";
}));
}
/// <summary>
/// 断开
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnDisconnect_Click(object sender, EventArgs e)
{
#region asyncTcpSession断开方式
try
{
asyncTcpSession.Close();
txtLog.Text += "断开成功!\r\n";
asyncTcpSession = null;
txtIpAddress.Enabled = true;
txtPort.Enabled = true;
btnConnect.Enabled = true;
btnDisconnect.Enabled = false;
}
catch(Exception ex)
{
txtLog.Text += "断开失败!\r\n";
}
#endregion
#region easyClient断开方式
//var result = easyClient.Close();
//if (result.Result)
//{
// txtLog.Text += "断开成功!\r\n";
// easyClient = null;
// txtIpAddress.Enabled = true;
// txtPort.Enabled = true;
// btnConnect.Enabled = true;
// btnDisconnect.Enabled = false;
//}
//else
//{
// txtLog.Text += "断开失败!\r\n";
//}
#endregion
}
private void btnSendLogin_Click(object sender, EventArgs e)
{
AppDeviceData appDeviceData = new AppDeviceData();
appDeviceData.DeviceID =cbDevice.Text.ToString();
appDeviceData.LoginName = "admin";
appDeviceData.BatteryLeft = "90%";
ReceiveData receiveData = new ReceiveData();
receiveData.MessageType = "1";
receiveData.MessageContent = JsonConvert.SerializeObject(appDeviceData);
string sendMsg= JsonConvert.SerializeObject(receiveData)+"\r\n";//必须以\r\n结尾
byte[] bytes = Encoding.Default.GetBytes(sendMsg);
try
{
//easyClient.Send(bytes);//easyClient 消息发送方式
asyncTcpSession.Send(bytes,0,bytes.Length);//asyncTcpSession 消息发送方式
txtLog.Text += "【"+DateTime.Now.ToString()+"】发送消息:\r\n" + sendMsg + "\r\n";
}
catch(Exception ex)
{
txtLog.Text += sendMsg+"消息发送失败:" + ex.Message+"\r\n";
}
}
private void btnEquipFault_Click(object sender, EventArgs e)
{
EquipmentFault equipmentFault = new EquipmentFault();
equipmentFault.MessageTitle = "设备故障";
equipmentFault.MessageUID = Guid.NewGuid().ToString();
equipmentFault.FaultTime = DateTime.Now;
equipmentFault.SubAPPName = "weixiu";
equipmentFault.TargetPhoneID = cbDevice.Text.ToString();
equipmentFault.EmergenceLevel = "Low";
ReceiveData receiveData = new ReceiveData();
receiveData.MessageType = "2";
receiveData.MessageContent = JsonConvert.SerializeObject(equipmentFault);
string sendMsg = JsonConvert.SerializeObject(receiveData) + "\r\n";//必须以\r\n结尾
byte[] bytes = Encoding.Default.GetBytes(sendMsg);
try
{
//easyClient.Send(bytes);//easyClient 消息发送方式
asyncTcpSession.Send(bytes, 0, bytes.Length);//asyncTcpSession 消息发送方式
txtLog.Text += "【" + DateTime.Now.ToString() + "】发送消息:\r\n" + sendMsg + "\r\n";
}
catch (Exception ex)
{
txtLog.Text += sendMsg + "消息发送失败:" + ex.Message+"\r\n";
}
}
}
}
3、其他相关代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SuperSocket.ProtoBase;
namespace SockectClient
{
/// <summary>
/// 带起止符协议过滤
/// </summary>
public class ReceiveFilter : BeginEndMarkReceiveFilter<StringPackageInfo>
{
//可选继承类:
//TerminatorReceiveFilter 结束符协议
//BeginEndMarkReceiveFilter 带起止符的协议
//FixedHeaderReceiveFilter 头部格式固定并且包含内容长度的协议
//FixedSizeReceiveFilter 固定请求大小的协议
//CountSpliterReceiveFilter 固定数量分隔符协议
public ReceiveFilter()
: base(Encoding.ASCII.GetBytes("#"), Encoding.ASCII.GetBytes("$\r\n"))
{
}
/// <summary>
/// 经过过滤器,收到的字符串会到这个函数
/// </summary>
/// <param name="bufferStream"></param>
/// <returns></returns>
public override StringPackageInfo ResolvePackage(IBufferStream bufferStream)
{
return null;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SockectClient.Model
{
/// <summary>
/// App端传输的数据
/// </summary>
public class AppDeviceData
{
/// <summary>
/// 登录设备的ID
/// </summary>
public string DeviceID { get; set; }
/// <summary>
/// 登录的账户名称
/// </summary>
public string LoginName { get; set; }
/// <summary>
/// 剩余电量
/// </summary>
public string BatteryLeft { get; set; }
/// <summary>
/// 在线状态 0:不在线 1在线 默认在线
/// </summary>
public int IsOnline { get; set; } = 1;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SockectClient.Model
{
/// <summary>
/// 设备故障信息
/// </summary>
public class EquipmentFault
{
/// <summary>
/// 目标手机设备ID
/// </summary>
public string TargetPhoneID { get; set; }
/// <summary>
/// 故障发生时间
/// </summary>
public DateTime FaultTime { get; set; }
/// <summary>
/// 消息id
/// </summary>
public string MessageUID { get; set; }
/// <summary>
/// 消息标题
/// </summary>
public string MessageTitle { get; set; }
/// <summary>
/// 发送给App(消息类型)
/// </summary>
public string SubAPPName { get; set; }
/// <summary>
/// 故障等级 Low,Default,High,Emergent
/// </summary>
public string EmergenceLevel { get; set; }
/// <summary>
/// 是否已读 0:否 1:是 默认否
/// </summary>
public int IsRead { get; set; } = 0;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SockectClient.Model
{
/// <summary>
/// 接收的消息
/// </summary>
public class ReceiveData
{
/// <summary>
/// 接收的消息类型 1:App端登录 2:设备故障信息推送
/// </summary>
public string MessageType { get; set; }
/// <summary>
/// 消息内容
/// </summary>
public string MessageContent { get; set; }
}
}
版权声明:本文为CSDN博主「蓝晶之心」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/liwan09/article/details/106320716
https://blog.csdn.net/liwan09/article/details/106320716