/// <summary>
/// Socket通讯工具类
/// 约定:
/// 一个数据包前4个字节为数据长度【长度不包括数据包前面的8个字节】,
/// 中间的4个字节为数据类别: 1为Json,2为文件
/// 后面的均为 “数据”
/// </summary>
public class SocketTools
{
private readonly string mIp;
private readonly int mPort;
private Socket mClient;
/// <summary>
/// 当前连接状态:是否已经连接
/// </summary>
public bool Connected
{
get
{
try
{
if (this.mClient != null
&& this.mClient.Connected
&& this.mClient.Poll(100, SelectMode.SelectWrite))
{
return true;
}
}
catch (Exception)
{ }
return false;
}
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="ip">ip地址</param>
/// <param name="port">端口号</param>
public SocketTools(string ip, int port)
{
this.mIp = ip;
this.mPort = port;
}
/// <summary>
/// 连接服务器
/// </summary>
/// <returns></returns>
public SocketResult ConnectServer()
{
this.DisConnect();
try
{
//1.创建发送者
this.mClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//2.连接给谁发送
this.mClient.Connect(IPAddress.Parse(this.mIp), this.mPort);
this.mClient.SendBufferSize = 102400;
this.mClient.ReceiveBufferSize = 102400;
}
catch (Exception e)
{
return SocketResult.Error(e.Message);
}
return SocketResult.Success();
}
/// <summary>
/// 断开Socket连接
/// </summary>
/// <returns></returns>
public SocketResult DisConnect()
{
try
{
if (this.mClient != null && this.mClient.Connected)
this.mClient.Close();
}
catch (Exception e)
{
return SocketResult.Error(e.Message);
}
this.mClient = null;
return SocketResult.Success();
}
/// <summary>
/// 向手机端发送Json格式数据,返回Json格式数据
/// </summary>
/// <param name="json"></param>
/// <returns></returns>
public SocketResult SendJsonReceiveJson(SocketModel json)
{
SocketResult tmp = Connect();
if (!tmp.Result)
return tmp;
try
{
SendJson(json);
return ReceiveJson();
}
catch (Exception e)
{
return SocketResult.Error(e.Message);
}
}
/// <summary>
/// 向手机端发送Json格式数据,返回文件
/// 用于下载手机端的文件
/// </summary>
/// <param name="json"></param>
/// <returns></returns>
public SocketResult SendJsonReceiveFile(SocketModel json)
{
SocketResult tmp = Connect();
if (!tmp.Result)
return tmp;
try
{
SendJson(json);
return ReceiveFile();
}
catch (Exception e)
{
return SocketResult.Error(e.Message);
}
}
/// <summary>
/// 向手机端发送文件格式数据,返回Json
/// 向手机端上传文件
/// </summary>
/// <param name="json"></param>
/// <param name="fileName"></param>
/// <returns></returns>
public SocketResult SendFileReceiveModel(SocketModel json, string fileName)
{
SocketResult tmp = Connect();
if (!tmp.Result)
return tmp;
// 先发送Json 后发送文件
try
{
if (!File.Exists(fileName))
{
return SocketResult.Error("文件不存在");
}
SendJson(json);
SendFile(fileName);
return ReceiveJson();
}
catch (Exception e)
{
return SocketResult.Error(e.Message);
}
}
private SocketResult Connect()
{
if (!this.Connected && this.ConnectServer().Result)
{
return SocketResult.Error("无法连接到手机");
}
return SocketResult.Success();
}
private void SendFile(string fileName)
{
using (FileStream fs = File.OpenRead(fileName))
{
this.mClient.Send(BitConverter.GetBytes((int)fs.Length));
this.mClient.Send(BitConverter.GetBytes(2));//类型2:文件类型
while (fs.Position < fs.Length - 1)
{
byte[] tempBuffer = new byte[102400];
int tempLen = fs.Read(tempBuffer, 0, tempBuffer.Length);
this.mClient.Send(tempBuffer, 0, tempLen, SocketFlags.None);
}
fs.Close();
}
}
private SocketResult ReceiveFile()
{
// read json
MemoryStream ms = this.Read(2);
if (ms == null)
{
return SocketResult.Error("接收数据失败");
}
string tempFile = Path.GetTempFileName();
using (ms)
{
ms.Seek(8, SeekOrigin.Begin);
using (FileStream fs = File.Create(tempFile))
{
// 循环写入 每次100K
while (ms.Position < ms.Length - 1)
{
byte[] tempBuffer = new byte[102400];
int tempLen = ms.Read(tempBuffer, 0, tempBuffer.Length);
fs.Write(tempBuffer, 0, tempLen);
}
fs.Flush();
fs.Close();
}
ms.Close();
}
// 文件下载成功后 将临时文件 文件全路径返回
SocketResult result = SocketResult.Success();
result.Model = new SocketModel();
result.Model.Data.Add("FilePath", tempFile);
return result;
}
private void SendJson(SocketModel json)
{
byte[] data = JsonTools.SerializeToBuffer(json);
if (data == null || data.Length == 0)
throw new ArgumentNullException(" data is empty ");
this.mClient.Send(BitConverter.GetBytes(data.Length));
this.mClient.Send(BitConverter.GetBytes(1));//类型1:json类型
this.mClient.Send(data);
}
private SocketResult ReceiveJson()
{
// read json
MemoryStream ms = this.Read(1);
if (ms == null)
{
return SocketResult.Error("接收数据失败");
}
byte[] buffer = new byte[ms.Length - 8];
ms.Seek(8, SeekOrigin.Begin);
ms.Read(buffer, 0, (int)ms.Length - 8);
ms.Close();
ms.Dispose();
SocketResult socketResult = null;
SocketModel model = JsonTools.DeserializeToTFromBuffer<SocketModel>(buffer);
if (model == null || model.Result == 0)
{
socketResult = SocketResult.Error(model == null ? "接收数据失败" : model.Msg);
socketResult.Model = model;
return socketResult;
}
socketResult = SocketResult.Success();
socketResult.Model = model;
return socketResult;
}
private MemoryStream Read(int type)
{
MemoryStream ms = new MemoryStream();
while (true)
{
int next = GetNextCount(ms);
if (next < 0)
{
ms = null;
this.DisConnect();
break;
}
if (next == 0)
{
ms.Seek(4, SeekOrigin.Begin);
byte[] typeBuffer = new byte[4];
ms.Read(typeBuffer, 0, 4);
if (type != BitConverter.ToInt32(typeBuffer, 0))
{
ms = null;
this.DisConnect();
}
break;
}
long len = ms.Length;
ReadBuffer(ms, next);
// 判断本次读取是否成功
if (ms.Length == len)
{
ms = null;
this.DisConnect();
break;
}
}
return ms;
}
private void ReadBuffer(MemoryStream ms, int next)
{
try
{
byte[] buffer = new byte[next];
int len = 0;
if (this.mClient.Connected)
len = this.mClient.Receive(buffer, next, SocketFlags.None);
if (len > 0)
{
ms.Seek(0, SeekOrigin.End);//Seek函数为指定当前MemoryStream的当前位置。这里设置成End是因为:调用本函数的时候,是循环调用往MemoryStream里写入
ms.Write(buffer, 0, len);
}
}
catch (Exception)
{ }
}
private int GetNextCount(MemoryStream ms)
{
// 确定nextCount
int next = 0;
if (ms.Length < 8)
{
next = 8;
}
else
{
ms.Seek(0, SeekOrigin.Begin);
byte[] lenBuffer = new byte[4];
ms.Read(lenBuffer, 0, 4);
try
{
next = (BitConverter.ToInt32(lenBuffer, 0) + 8 - (int)ms.Length);
}
catch (Exception)
{
next = int.MinValue;
}
}
// 每次最多读取100K
if (next > 102400)
next = 102400;
return next;
}
}
/// <summary>
/// Socket命令类别
/// </summary>
public enum ESocketCmdType
{
/// <summary>
/// 下载文件
/// </summary>
GetFile = 1,
/// <summary>
/// 获取手机端的照片列表
/// </summary>
GetPicList = 2,
/// <summary>
/// 获取手机端的音乐列表
/// </summary>
GetMusicList = 3,
/// <summary>
/// 获取通讯录列表
/// </summary>
GetAddressListList = 4,
/// <summary>
/// 获取短信列表
/// </summary>
GetSMSList = 5,
/// <summary>
/// 上传文件
/// </summary>
UploadFile = 999,
}
/// <summary>
/// Socket通讯,Json实体类
/// </summary>
public class SocketModel
{
/// <summary>
/// 命令
/// </summary>
[JsonProperty("CMD")]
public ESocketCmdType CMD;
/// <summary>
/// 1:成功 0:失败
/// </summary>
[JsonProperty("Result")]
public int Result;
/// <summary>
/// 提示信息
/// </summary>
[JsonProperty("Msg")]
public string Msg;
/// <summary>
/// 命令附带参数
/// </summary>
[JsonProperty("Data")]
public Dictionary<string, object> Data;
public SocketModel()
{
this.Msg = string.Empty;
this.Data = new Dictionary<string, object>();
}
public SocketModel AddData(string key, object value)
{
if (this.Data != null && !this.Data.ContainsKey(key))
this.Data.Add(key, value);
return this;
}
public string GetString(string key)
{
if (this.Data != null && this.Data.ContainsKey(key) && this.Data[key] != null)
return this.Data[key].ToString().Trim();
return string.Empty;
}
public int GetInt(string key)
{
if (this.Data != null && this.Data.ContainsKey(key))
{
if (this.Data[key] is string)
{
return int.Parse((this.Data[key] as string).Trim());
}
if (this.Data[key] != null)
{
return int.Parse(this.Data[key].ToString().Trim());
}
}
return -1;
}
public double GetDouble(string key)
{
if (this.Data != null && this.Data.ContainsKey(key))
{
if (this.Data[key] is string)
{
return double.Parse((this.Data[key] as string).Trim());
}
if (this.Data[key] != null)
{
return double.Parse(this.Data[key].ToString().Trim());
}
}
return -1;
}
public Dictionary<string, object> GetDictionary(string key)
{
if (this.Data != null && this.Data.ContainsKey(key))
return JsonTools.Deserialize(this.Data[key]);
return null;
}
public Dictionary<string, string> GetDictionaryString(string key)
{
if (this.Data != null && this.Data.ContainsKey(key))
return JsonTools.DeserializeToTFromObject<Dictionary<string, string>>(this.Data[key]);
return null;
}
public T GetObject<T>(string key) where T : class
{
if (this.Data != null && this.Data.ContainsKey(key))
return JsonTools.DeserializeToTFromObject<T>(this.Data[key]);
return null;
}
}
/// <summary>
/// Socket通讯结果
/// </summary>
public class SocketResult
{
/// <summary>
/// 操作是否成功
/// </summary>
public bool Result;
/// <summary>
/// 失败时的错误提示信息
/// </summary>
public string Msg;
/// <summary>
/// 服务端返回的数据
/// </summary>
public SocketModel Model;
private SocketResult()
{ }
public static SocketResult Success()
{
SocketResult result = new SocketResult();
result.Result = true;
result.Msg = "操作成功";
return result;
}
public static SocketResult Error(string msg)
{
SocketResult result = new SocketResult();
result.Result = false;
result.Msg = msg;
return result;
}
}