本章主要實現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; }
}
}