Bladeren bron

添加项目文件。

master
xuliang 5 jaren geleden
bovenliggende
commit
039b031f30
8 gewijzigde bestanden met toevoegingen van 1646 en 0 verwijderingen
  1. +94
    -0
      GT808ClientTest.csproj
  2. +35
    -0
      GT808ClientTest.sln
  3. +493
    -0
      Program.cs
  4. +36
    -0
      Properties/AssemblyInfo.cs
  5. +903
    -0
      TcpPack.cs
  6. +85
    -0
      app.config
  7. BIN
      dll/Plugin.Common.dll
  8. BIN
      dll/log4net.dll

+ 94
- 0
GT808ClientTest.csproj Bestand weergeven

@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{DAEB7DF5-2FA8-4663-A15C-F8E52C1A19A9}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>GT808ClientTest</RootNamespace>
<AssemblyName>GT808ClientTest</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net">
<HintPath>..\Libs\log4net.dll</HintPath>
</Reference>
<Reference Include="Plugin.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>bin\Debug\Plugin.Common.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TcpPack.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="dll\log4net.dll" />
<Content Include="dll\Plugin.Common.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

+ 35
- 0
GT808ClientTest.sln Bestand weergeven

@@ -0,0 +1,35 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.539
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GT808ClientTest", "GT808ClientTest.csproj", "{DAEB7DF5-2FA8-4663-A15C-F8E52C1A19A9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DAEB7DF5-2FA8-4663-A15C-F8E52C1A19A9}.Debug|Any CPU.ActiveCfg = Debug|x86
{DAEB7DF5-2FA8-4663-A15C-F8E52C1A19A9}.Debug|x64.ActiveCfg = Debug|x64
{DAEB7DF5-2FA8-4663-A15C-F8E52C1A19A9}.Debug|x64.Build.0 = Debug|x64
{DAEB7DF5-2FA8-4663-A15C-F8E52C1A19A9}.Debug|x86.ActiveCfg = Debug|x86
{DAEB7DF5-2FA8-4663-A15C-F8E52C1A19A9}.Debug|x86.Build.0 = Debug|x86
{DAEB7DF5-2FA8-4663-A15C-F8E52C1A19A9}.Release|Any CPU.ActiveCfg = Release|x86
{DAEB7DF5-2FA8-4663-A15C-F8E52C1A19A9}.Release|x64.ActiveCfg = Release|x64
{DAEB7DF5-2FA8-4663-A15C-F8E52C1A19A9}.Release|x64.Build.0 = Release|x64
{DAEB7DF5-2FA8-4663-A15C-F8E52C1A19A9}.Release|x86.ActiveCfg = Release|x86
{DAEB7DF5-2FA8-4663-A15C-F8E52C1A19A9}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BAA1F5E7-D1F4-4D5E-A8BD-C3C293C9BA3B}
EndGlobalSection
EndGlobal

+ 493
- 0
Program.cs Bestand weergeven

@@ -0,0 +1,493 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Diagnostics;
using System.Threading;
using Gps.Plugin.Tcp.GT808;
using Gps.Plugin.Common.Helpers;
using System.Configuration;

namespace GT808ClientTest
{
class Program
{
protected static log4net.ILog log = null;
private string ip;
private int port;
private string deviceId;
Random r = new Random();
private int interval;
private int sendCountByOneDevice;
private ProcessCounter processCounter;
private static bool sendLogPrint;
private static bool waitReceive;
private static bool receiveLogPrint;

static Program()
{
log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile));
log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
}
private double initLat = 38.01342;
private double initLon = 114.560478;

public Program(string ip, int port, string deviceId, int interval, int sendCountByOneDevice, ProcessCounter processCounter)
{
// TODO: Complete member initialization
this.latlonBuilder = new LatlonBuilder(initLat, initLon, 31.802893, 39.300299, 104.941406, 117.861328);
this.ip = ip;
this.port = port;
this.deviceId = deviceId;
this.interval = interval;
this.sendCountByOneDevice = sendCountByOneDevice;
this.processCounter = processCounter;
}

private static byte[] stringtobytes(string str)
{
string[] strs = str.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
byte[] buffer = new byte[strs.Length];
for (int i = 0; i < strs.Length; ++i)
{
buffer[i] = Convert.ToByte(strs[i], 16);
}

return buffer;
}

static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

//var headpack = new Gps.Plugin.Tcp.GT808.HeadPack();
//byte[] packBytes = stringtobytes("7E-01-02-00-0E-00-20-47-05-52-32-00-00-32-30-31-32-30-31-31-39-30-38-31-30-34-37-0D-7E");
//if (RawFormatter.Instance.Bytes2Struct(headpack, packBytes , 1, HeadPack.PackSize))
//{
// Console.WriteLine("OK");
// Console.ReadKey();
//}

//MessageContext pack = new MessageContext();
//byte[] packBytes = stringtobytes("68-68-25-00-00-00-00-00-00-00-12-34-56-00-18-10-DC-01-13-13-06-17-04-14-11-DC-0C-4A-7F-5C-1A-00-00-00-00-00-00-00-00-00-0A-0D");
//if (RawFormatter.Instance.Bytes2Struct(pack, packBytes, BodyData.PackSize, MessageContext.PackSize))
//{
// Console.WriteLine("OK");
// Console.ReadKey();
//}

sendLogPrint = Convert.ToBoolean(ConfigurationManager.AppSettings["sendLogPrint"]);
waitReceive = Convert.ToBoolean(ConfigurationManager.AppSettings["waitReceive"]);
receiveLogPrint = Convert.ToBoolean(ConfigurationManager.AppSettings["receiveLogPrint"]);

string ip = "";
int port = 0;
while (port == 0 || string.IsNullOrEmpty(ip))
{
string line = "";
string configValue = ConfigurationManager.AppSettings["remoteServerPort"];
if (string.IsNullOrEmpty(configValue))
{
Console.Write("请输入服务器IP和端口(113.31.92.200:8201):");
line = Console.ReadLine();
}
else
{
line = configValue;
}

if (string.IsNullOrEmpty(line))
line = "113.31.92.200:8201";

int pos = line.IndexOf(':');
if (pos == -1)
{
Console.WriteLine("正确格式:xx.xxx.xxx.xxx:xxxx");
continue;
}

ip = line.Substring(0, pos);
string strPort = line.Substring(pos + 1);

int.TryParse(strPort, out port);
}

int min = 0, max = 0;
string deviceIdRangeValue = ConfigurationManager.AppSettings["deviceIdRange"];
if (string.IsNullOrEmpty(deviceIdRangeValue))
{
Console.WriteLine("生成设备标识格式为:0000000000000000,0000000000000001....");
Console.Write("依客户端网络情况输入要模拟的客户端数量(1-10000):");
string strCount = Console.ReadLine();
max = int.Parse(strCount);
}
else
{
string[] items = deviceIdRangeValue.Split('-');
min = int.Parse(items[0]);
max = int.Parse(items[1]);
}

int interval = 30;
string strInterval = ConfigurationManager.AppSettings["interval"];
if (string.IsNullOrEmpty(strInterval))
{
Console.Write("每个消息间隔(秒):");
strInterval = Console.ReadLine();
interval = int.Parse(strInterval);
}
else
{
interval = int.Parse(strInterval);
}

int sendCountByOneDevice = 30;
string strSendCountByOneDevice = ConfigurationManager.AppSettings["sendCountByOneDevice"];
if (string.IsNullOrEmpty(strSendCountByOneDevice))
{
Console.Write("每个设备发送共多少个包后断开连接:");
strSendCountByOneDevice = Console.ReadLine();
sendCountByOneDevice = int.Parse(strSendCountByOneDevice);
}
else
{
sendCountByOneDevice = int.Parse(strSendCountByOneDevice);
}

ProcessCounter processCounter = new ProcessCounter((max - min + 1) * sendCountByOneDevice, pc =>
{
Console.Title = pc.ToString();
});

for (int i = min; i <= max; ++i)
{
string deviceId = string.Concat("010000", i.ToString("00000"));

Program p = new Program(ip, port, deviceId, interval, sendCountByOneDevice, processCounter);

//p.Run();
Thread iThred = new Thread(p.Run);
iThred.Start();

//Thread.SpinWait(2);
}
Console.ReadLine();
}

private void Run()
{
Console.WriteLine("Thread {0} Start {1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString());

Socket tcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
tcp.Connect(IPAddress.Parse(ip), port);

try
{
while (this.sendCountByOneDevice-- > 0)
{
if (SendPosition(tcp))
{
processCounter.IncrSuccess();
}
else
{
processCounter.IncrFailed();
}
Thread.Sleep(interval * 1000);
//Thread.Sleep(100);
}
/*
if (SendPosition(tcp))
{
processCounter.IncrSuccess();
}
else
{
processCounter.IncrFailed();
}

if (--this.sendCountByOneDevice <= 0)
{
//timer.Change(-1, -1);
//try
//{
// tcp.Disconnect(true);
// tcp.Dispose();
//}
//catch (Exception exp)
//{
// log.Warn("断开连接出错:" + exp.Message);
//}
}
else
{
//SendPosition(tcp);
//timer.Change(Math.Max(1, interval * 1000 - watch.ElapsedMilliseconds), -1);
}
*/
}
catch (SocketException exp)
{
log.Debug("连接已经断开, 重连接中");
//timer.Change(Timeout.Infinite, Timeout.Infinite);
this.Run();
}
catch (Exception ex)
{
log.Error(ex.Message, ex);
//timer.Change(Math.Max(1, interval * 1000 - watch.ElapsedMilliseconds), -1);
}
}
catch (ThreadAbortException)
{
return;
}
catch (Exception exp)
{
log.Error(exp);

}
Console.WriteLine("Thread {0} End {1}", Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString());

}

ushort seqNum = 1;
ushort GetNextSeqNum()
{
lock (this)
{
return ++seqNum;
}
}

private byte[] bufferRecv = new byte[1024];
private LatlonBuilder latlonBuilder;

private bool SendPosition(Socket tcp)
{
HeadPack head = new HeadPack() { SeqNO = GetNextSeqNum(), MessageId = (ushort)MessageIds.PositionReport, BodyProp = (ushort)0 };
head.SetDeviceId(this.deviceId);

double lat;
double lon;
int speed = 10 + r.Next(90);
latlonBuilder.GetNextLatlon(speed, out lat, out lon);

PositionReportPack pack = new PositionReportPack()
{
AlermFlags = 0,
Speed = (ushort)(speed * 10),
State = 0,
Latitude = Convert.ToUInt32(lat * 1000000),
Longitude = Convert.ToUInt32(lon * 1000000),
Altitude = 200,
Direction = 0,
Time = DateTime.Now.ToString("yyMMddHHmmss")
};

byte[] bytesSend = RawFormatter.Instance.Struct2Bytes(pack);

BodyPropertyHelper.SetMessageLength(ref head.BodyProp, (ushort)bytesSend.Length);

byte[] headBytes = RawFormatter.Instance.Struct2Bytes(head);
byte[] fullBytes = headBytes.Concat(bytesSend).ToArray();
byte checkByte = PackHelper.CalcCheckByte(fullBytes, 0, fullBytes.Length);

bytesSend = (new byte[] { 0x7e }
.Concat(PackHelper.EncodeBytes(fullBytes).Concat(new byte[] { checkByte }))
.Concat(new byte[] { 0x7e })).ToArray();

//发送消息
SendBytes(tcp, bytesSend);
//控制台打印日志cpu占用太高
if (sendLogPrint)
{
Console.WriteLine("{0} {1}, LatLon:{2:0.000000},{3:0.000000}", head.GetDeviceId(), DateTime.Now.ToString(), lat, lon);
}
//等待接收服务端返回值
var success = true;
if (waitReceive)
{
success = RecvBytes(tcp);
//var success = true;
}
return success;
}
void SendBytes(Socket tcp, byte[] bytes)
{
lock (System.Reflection.MethodBase.GetCurrentMethod())
{
if (bytes.Length != tcp.Send(bytes))
{
throw new SocketException((int)SocketError.ConnectionReset);
}
}
}

private bool RecvBytes(Socket tcp)
{
lock (bufferRecv)
{
byte[] buffer = bufferRecv;

int received = tcp.Receive(buffer);
//received = tcp.ReceiveAsync.Receive(buffer);

byte[] bytesReceived = PackHelper.DecodeBytes(buffer, 1, received - 2);
int rightSize = HeadPack.PackSize + ServerAnswerPack.PackSize + 1;
if (bytesReceived.Length != rightSize)
{
log.WarnFormat("返回消息长度不正确:" + bytesReceived.Length + "!=" + rightSize);
}

ServerAnswerPack pack = new ServerAnswerPack();
RawFormatter.Instance.Bytes2Struct(pack, bytesReceived, HeadPack.PackSize, ServerAnswerPack.PackSize);

if (pack.Result != 0)
{
log.WarnFormat("发送失败:" + pack.Result.ToString());
}
if(waitReceive && receiveLogPrint)
{
Console.WriteLine("SeqNO:{0} MessageId:{1} Result:{2}", pack.SeqNO,pack.MessageId,pack.Result);
}
return pack.Result == 0;
}
}

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
log.Error(e.ExceptionObject);
}
}

class LatlonBuilder
{
private double lat;
private double lon;
private double minLat;
private double maxLat;
private double minLon;
private double maxLon;
private int direction = 0;
private Random r = new Random();
public LatlonBuilder(double lat, double lon, double minLat, double maxlat, double minLon, double maxLon)
{
this.lat = lat;
this.lon = lon;
this.minLat = minLat;
this.maxLat = maxlat;
this.minLon = minLon;
this.maxLon = maxLon;

this.direction = r.Next(360);
}

public bool GetNextLatlon(int speed, out double lat, out double lon)
{
direction = (direction + (r.Next(30) - 15)) % 360;
double angle = Math.PI * this.direction / 180.0;
double latAdd = speed / 1000.0 * Math.Sin(angle);
double lonAdd = speed / 1000.0 * Math.Cos(angle);

this.lat = lat = this.lat + latAdd;
this.lon = lon = this.lon + lonAdd;

if (lat < minLat || lat > maxLat || lon < minLon || lon > maxLon)
{
direction = (direction + 180) % 360;
return GetNextLatlon(speed, out lat, out lon);
}


return true;
}
}

class ProcessCounter
{
private long current = 0, failedCounter = 0;
private Thread thread;
private AutoResetEvent evtUpdateUI = new AutoResetEvent(false);
private long updatePerCount;
private long lastUpdateVal;
public ProcessCounter(long max, Action<ProcessCounter> updateUI)
{
this.Max = max;
this.updatePerCount = max / 100;
this.thread = new Thread(new ThreadStart(() =>
{
while (true)
{
try
{
evtUpdateUI.WaitOne(500);
this.lastUpdateVal = Interlocked.Read(ref current);
updateUI(this);
}
catch (ThreadAbortException)
{
return;
}
catch (Exception exp)
{
Console.WriteLine(exp.Message);
}
}
}));
this.thread.IsBackground = true;
this.thread.Start();

}

public long Max { get; set; }


internal void IncrSuccess()
{
lock (this)
Incr();
}
internal void IncrFailed()
{
lock (this)
{
Incr();
Interlocked.Increment(ref failedCounter);
}
}

private void Incr()
{
var val = Interlocked.Increment(ref current);
if (val - lastUpdateVal > this.updatePerCount)
{
this.evtUpdateUI.Set();
}

if (val == Max)
{
Console.WriteLine("Done");
}
}

public override string ToString()
{
long curr = Interlocked.Read(ref current);
float g = Convert.ToSingle(curr / (Max / 100.0));
string ret = string.Concat(curr, "/", Max, "=>", g.ToString("##.00"), "%");

long failed = Interlocked.Read(ref failedCounter);
if (failed > 0)
ret = string.Concat(ret, "(Success:" + (curr - failed), ", Failed:", failed, ")");

return ret;
}


}
}

+ 36
- 0
Properties/AssemblyInfo.cs Bestand weergeven

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("GT808ClientTest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GT808ClientTest")]
[assembly: AssemblyCopyright("Copyright © 2012")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]

// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("13ae5af7-0f7a-4428-88fe-e41cf030f0a2")]

// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 内部版本号
// 修订号
//
// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

+ 903
- 0
TcpPack.cs Bestand weergeven

@@ -0,0 +1,903 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics.Contracts;
using System.Net;
using Gps.Plugin.Common.Helpers;
using System.IO;
using System.Collections;

namespace Gps.Plugin.Tcp.GT808
{
public class PackHelper
{
public static byte[] ToBytes(string deviceId, MessageIds messageId, ushort seqNO, byte[] bodyBytesReturn)
{

HeadPack head = new HeadPack()
{
BodyProp = 0,
MessageId = (ushort)messageId,
SeqNO = seqNO
};

head.SetDeviceId(deviceId);
//BodyPropertyHelper.SetMessageLength(ref head.BodyProp,(ushort)bodyBytesReturn.Length);

BodyPropertyHelper.SetMessageLength(ref head.BodyProp, (ushort)bodyBytesReturn.Length);


return RawFormatter.Instance.Struct2Bytes(head).Concat(bodyBytesReturn).ToArray();

}

public static byte[] DecodeBytes(byte[] buffer)
{
return DecodeBytes(buffer, 0, buffer.Length);
}

public static byte[] DecodeBytes(byte[] bytes, int offset, int length)
{
int index = 0;
int endOffset = Math.Min(length, bytes.Length - offset) + offset;
for (int i = offset; i < endOffset; )
{
if (bytes[i] == 0x7d && bytes[i + 1] == 0x02)
{
bytes[index++] = 0x7e;
i += 2;
}
else if (bytes[i] == 0x7d && bytes[i + 1] == 0x01)
{
bytes[index++] = 0x7d;
i += 2;
}
else
{
bytes[index++] = bytes[i++];
}
}

return bytes.Take(index).ToArray();
}


public static byte[] EncodeBytes(IEnumerable<byte> bytes)
{
MemoryStream ms = new MemoryStream();
foreach (var b in bytes)
{
if (b == 0x7e)
{
ms.WriteByte(0x7d);
ms.WriteByte(0x02);
}
else if (b == 0x7d)
{
ms.WriteByte(0x7d);
ms.WriteByte(0x01);
}
else
{
ms.WriteByte(b);
}

}

return ms.ToArray();
}

/// <summary>
/// 计算校验位
/// </summary>
/// <param name="bytes"></param>
/// <param name="offset"></param>
/// <param name="count"></param>
/// <returns></returns>
public static byte CalcCheckByte(byte[] bytes, int offset, int count)
{
if (count == 0)
return 0;

byte ret = bytes[offset];
for (int i = offset + 1; i < offset + count; ++i)
{
ret ^= bytes[i];
}

return ret;
}

/// <summary>
/// 计算校验位
/// </summary>
/// <param name="bytes"></param>
public static void CalcCheckByte(byte[] bytes)
{
if (bytes.Length == 0)
return;

bytes[bytes.Length - 1] = CalcCheckByte(bytes, 0, bytes.Length - 1);
}

}


/*
车载GPS定位器通信协议(GT808)(TCP_6004).pdf
P2
*
* 7E-01-02-00-06-00-20-47-05-52-32-00-00-30-31-32-33-34-35-06-7E
*/

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public class HeadPack
{
public static byte FixPrefix = 0x7e;




public static Int32 PackSize = Marshal.SizeOf(typeof(HeadPack));

/// <summary>
/// 消息 ID
/// </summary>
public BigEndianUInt16 MessageId;

/// <summary>
/// 消息体属性
/// </summary>
public BigEndianUInt16 BodyProp;

/// <summary>
/// 终端手机号
/// </summary>
protected BCD8421_6BytesString DeviceId;


/// <summary>
/// 自增一序列号
/// </summary>
public BigEndianUInt16 SeqNO;


public string GetDeviceId()
{
return string.Concat("460", DeviceId);
}

public void SetDeviceId(string value)
{
if (value.Length > 12)
{
DeviceId = value.Substring(value.Length - 12, 12);
}
else
{
DeviceId = value.PadLeft(12, '0');
}
}

}


public static class BodyPropertyHelper
{
/// <summary>
/// 9-0 BIT
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
public static Int16 GetMessageLength(BigEndianUInt16 val)
{
return (Int16)((UInt16)val & 0x03ff);
}

/// <summary>
/// 9-0 BIT
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
public static void SetMessageLength(ref BigEndianUInt16 val, UInt16 length)
{
val = (UInt16)(((UInt16)val & (~0x03ff)) + length);
}

/// <summary>
/// 12-10 BIT
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
public static Byte GetEncodeType(BigEndianUInt16 val)
{
return (Byte)((val >> 10) & 0x03);
}


public static void SetEncodeType(ref BigEndianUInt16 val, byte encType)
{
ushort v = val;

v = (ushort)(v & ~(0x03 << 10) + encType << 10);

val = v;
}

/// <summary>
/// 13 BIT
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
public static bool IsMutliPack(this BigEndianUInt16 val)
{
return ((val >> 13) & 0x01) == 0x0001;
}
}


[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public class PackProperty
{
public static Int32 PackSize = Marshal.SizeOf(typeof(PackProperty));

public BigEndianUInt16 Total;
public BigEndianUInt16 Index;
}


[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public class ServerAnswerPack
{
public static Int32 PackSize = Marshal.SizeOf(typeof(ServerAnswerPack));


/// <summary>
/// 流水
/// </summary>
public BigEndianUInt16 SeqNO;

/// <summary>
/// 消息ID
/// </summary>
public BigEndianUInt16 MessageId;


/// <summary>
/// 结果 0:成功/确认 1:失败 2:消息有误 3:不支持 4:报警处理确认
/// </summary>
public byte Result;
}

/// <summary>
/// 终端通用应答
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public class ClientAnswerPack
{
public static Int32 PackSize = Marshal.SizeOf(typeof(ServerAnswerPack));


/// <summary>
/// 流水
/// </summary>
public BigEndianUInt16 SeqNO;

/// <summary>
/// 消息ID
/// </summary>
public BigEndianUInt16 MessageId;


/// <summary>
/// 结果 0:成功/确认 1:失败 2:消息有误 3:不支持
/// </summary>
public byte Result;
}

/// <summary>
/// 终端注册 最后是GBK字串,车牌号
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public class ClientRegistPack
{
public static Int32 PackSize = Marshal.SizeOf(typeof(ClientRegistPack));

/// <summary>
/// 省
/// </summary>
public BigEndianUInt16 Province;

/// <summary>
/// 市
/// </summary>
public BigEndianUInt16 City;

/// <summary>
/// 制造商
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] Manufacturer;

/// <summary>
/// 终端型号
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] DeviceModel;


/// <summary>
/// 终端ID
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
public byte[] DeviceId;


/// <summary>
/// 车牌颜色
/// </summary>
public byte CarColor;


//最后是GBK字串,车牌号


}


[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public class ClientRegistReturnPack
{
/// <summary>
/// 自增一序列号
/// </summary>
public BigEndianUInt16 SeqNum;

/// <summary>
/// 0成功, 1车辆已经注册, 2数据库中无此车辆, 3终端已经被注册, 4数据库中无该终端
/// </summary>
public Byte Result;
}

/// <summary>
/// 位置包汇报
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public class PositionReportPack
{
public static Int32 PackSize = Marshal.SizeOf(typeof(PositionReportPack));

/// <summary>
/// 报警标志
/// </summary>
public BigEndianUInt32 AlermFlags;


/// <summary>
/// 状态
/// </summary>
public BigEndianUInt32 State;



/// <summary>
/// 纬度 度*10^6
/// </summary>
public BigEndianUInt32 Latitude;

/// <summary>
/// 经度 度*10^6
/// </summary>
public BigEndianUInt32 Longitude;

/// <summary>
/// 高程 单位为米
/// </summary>
public BigEndianUInt16 Altitude;

/// <summary>
/// 速度 1/10KM/H
/// </summary>
public BigEndianUInt16 Speed;


/// <summary>
/// 方向 0~359 正北为0 顺时针
/// </summary>
public BigEndianUInt16 Direction;

/// <summary>
/// 时间
/// </summary>
public BCD8421_6BytesString Time;



}

/// <summary>
/// 立即拍照命令
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public class CmdPhotographePack
{
/// <summary>
/// 通道ID > 0
/// </summary>
public Byte Channel;

/// <summary>
/// 拍摄命令 0表示停止拍摄;0xffff表示录像;其它表示拍摄张数
/// </summary>
public BigEndianUInt16 Cmd;

/// <summary>
/// 拍照间隔,录像时间。 单位为秒,0表示最小间隔拍照或者一直录像
/// </summary>
public BigEndianUInt16 Interval;

/// <summary>
/// 保存标志 1保存 0立即上传
/// </summary>
public byte Deal;

/// <summary>
/// 图像分辨率 0x01:320*240 0x02:640*480 0x03:800*600 0x04:1024*768
/// 0x05:176*144(Qcif) 0x06:352*288(Cif) 0x07:704*288(HALF D1) 0x08:704*546(D1)
/// </summary>
public byte Resolution;

/// <summary>
/// 图像质量 1 ~ 10 1表示质量损失最小, 10表示压缩最大
/// </summary>
public byte Quality;

/// <summary>
/// 亮度 0 ~ 255
/// </summary>
public byte Brightness;

/// <summary>
/// 对比度 0 ~ 127
/// </summary>
public byte Contrast;

/// <summary>
/// 饱和度 0 ~ 127
/// </summary>
public byte Saturation;


/// <summary>
/// 色度 0 ~ 255
/// </summary>
public byte Chroma;



}

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public class CmdSendTextPack
{
public byte Flag;


/// <summary>
/// 紧急
/// </summary>
public bool IsUrgent
{
get { return (Flag & 0x01) == 0x01; }
set { Flag = (byte)(Flag | 0x01); }
}

/// <summary>
/// 终端显示器显示
/// </summary>
public bool IsDisplay
{
get { return (Flag & 0x04) == 0x04; }
set { Flag = (byte)(Flag | 0x04); }
}
/// <summary>
/// 终端显示器显示
/// </summary>
public bool IsTTS
{
get { return (Flag & 0x08) == 0x08; }
set { Flag = (byte)(Flag | 0x08); }
}

/// <summary>
/// 终端显示器显示
/// </summary>
public bool IsAD
{
get { return (Flag & 0x10) == 0x10; }
set { Flag = (byte)(Flag | 0x10); }
}

//[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0)]
//public byte[] MessageBytes;
}


/// <summary>
/// 多媒体数据上传
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public class GpsMultimediaUploadPack
{
public static Int32 PackSize = Marshal.SizeOf(typeof(GpsMultimediaUploadPack));

/// <summary>
/// 多媒体ID >0
/// </summary>
public BigEndianUInt32 ID;

/// <summary>
/// 多媒体类型 0:图像 1:音频 2:视频
/// </summary>
public Byte Type;

/// <summary>
/// 多媒体格式编码 0:JPEG 1:TIF 2:MP3 3:WAV 4:WMV
/// </summary>
public byte Format;

/// <summary>
/// 事件项编码 0:平台下发指令 1:定时动作 2:抢劫报警触发 3:碰撞侧翻触发报警 4:保留
/// </summary>
public byte EventCode;

/// <summary>
/// 通道ID > 0
/// </summary>
public Byte Channel;



}

/// <summary>
/// 多媒体数据上传
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public class GpsMultimediaReUploadPack
{
public static Int32 PackSize = Marshal.SizeOf(typeof(GpsMultimediaReUploadPack));

/// <summary>
/// 多媒体ID >0
/// </summary>
public BigEndianUInt32 ID;

/// <summary>
/// 多媒体类型 0:图像 1:音频 2:视频
/// </summary>
public Byte Count;

///// <summary>
///// 要求重发的下一个包
///// </summary>
//public Byte NextIndex;



}


public class BitValueState
{
private BitArray bitArray;
public BitValueState(ushort state)
{
this.bitArray = new BitArray(BitConverter.GetBytes(state));
}

/// <summary>
/// ACC 开关
/// </summary>
bool ACC
{
get
{
return bitArray[0];
}
set
{
bitArray[0] = value;
}
}

/// <summary>
/// 是否定位
/// </summary>
//Position = 0x0002,
bool Position
{
get
{
return bitArray[1];
}
set
{
bitArray[1] = value;
}
}

/// <summary>
/// 0北纬 1南纬
/// </summary>
//NorthOrSouth = 0x0004,
bool IsSouth
{
get
{
return bitArray[2];
}
set
{
bitArray[2] = value;
}
}
/// <summary>
/// 0东经 1西经
/// </summary>
//EastOrWest = 0x0008,
bool IsWest
{
get
{
return bitArray[3];
}
set
{
bitArray[3] = value;
}
}
/// <summary>
/// 0运营状态 1停运
/// </summary>
//OperationState = 0x0010,
bool OperationStoped
{
get
{
return bitArray[4];
}
set
{
bitArray[4] = value;
}
}
/// <summary>
/// 经纬度是否加密
/// </summary>
//EncodeLongitudeLatitude = 0x0020,
bool EncodeLongitudeLatitude
{
get
{
return bitArray[5];
}
set
{
bitArray[5] = value;
}
}
/// <summary>
/// 0车辆油路正常 1断开
/// </summary>
//CarOilchannel = 0x0400,
bool CarOilchannelBreaked
{
get
{
return bitArray[10];
}
set
{
bitArray[10] = value;
}
}
/// <summary>
/// 0车辆电子正常 1断开
/// </summary>
//CarCircuit = 0x0800,
bool CarCircuitBreaked
{
get
{
return bitArray[11];
}
set
{
bitArray[11] = value;
}
}
/// <summary>
/// 0车辆车门解锁 1加锁
/// </summary>
//CarDoorLock = 0x1000
bool CarDoorLocked
{
get
{
return bitArray[12];
}
set
{
bitArray[12] = value;
}
}
}

public class BitValueAlerm
{
//private uint data;
private BitArray bitArray;
public BitValueAlerm(UInt32 alerm)
{
//this.data = alerm;
bitArray = new BitArray(new int[] { (int)alerm });
}

/// <summary>
/// 紧急报警, 触动报警开关后触发 收到答应后清除
/// </summary>
bool Urgent
{
get
{
return bitArray[0];
}
set
{
bitArray[0] = value;
}

}

/// <summary>
/// 超速报警 标志维持到报警条件解除
/// </summary>
bool Speeding
{
get
{
return bitArray[1];
}
set
{
bitArray[1] = value;
}

}


/// <summary>
/// 疲劳驾驶 标志维持到报警条件解除
/// </summary>
bool Fatigue
{
get
{
return bitArray[2];
}
set
{
bitArray[2] = value;
}

}

/// <summary>
/// 预警 收到答应后清除
/// </summary>
bool Forewarning
{
get
{
return bitArray[3];
}
set
{
bitArray[3] = value;
}

}

//TODO:未完, 以后用到添加

}




public enum MessageIds : ushort
{

/// <summary>
/// 终端通用应答
/// </summary>
ClientAnswer = 0x0001,



/// <summary>
/// 终端心跳
/// </summary>
ClientPump = 0x0002,

/// <summary>
/// 终端注销
/// </summary>
ClientUnregist = 0x0003,


/// <summary>
/// 终端注册
/// </summary>
ClientRegist = 0x0100,


/// <summary>
/// 终端鉴权
/// </summary>
ClientAuth = 0x0102,

/// <summary>
/// 位置信息汇报
/// </summary>
PositionReport = 0x0200,

/// <summary>
/// 多媒体事件信息上传
/// </summary>
MultimediaEventUpload = 0x0800,

/// <summary>
/// 多媒体数据上传
/// </summary>
MultimediaUpload = 0x0801,

/// <summary>
/// 多媒体数据上传
/// </summary>
MultimediaUploadAnswer = 0x8800,

/// <summary>
/// 平台通用应答
/// </summary>
ServerAnswer = 0x8001,


/// <summary>
/// 终端注册应答
/// </summary>
ClientRegistReturn = 0x8100,

/// <summary>
/// 立即拍照
/// </summary>
Photographe = 0x8801,

/// <summary>
/// 下发文本
/// </summary>
SendTextMessage = 0x8300



}





}

+ 85
- 0
app.config Bestand weergeven

@@ -0,0 +1,85 @@
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>

</configSections>
<appSettings>
<!--服务器IP和端口(113.31.92.200:8201)-->
<add key="remoteServerPort" value="10.1.97.12:32195"/>
<!--模拟终端id区间(设置200000-200100,将自动生成010000200000-010000200100这样101个设备)-->
<add key="deviceIdRange" value="200000-200010"/>
<!--每个消息间隔(秒)-->
<add key="interval" value="1"/>
<!--每个设备发送共多少个包(默认0x0200)后断开连接-->
<add key="sendCountByOneDevice" value="10"/>
<!--控制台是否打印发送日志(消耗大量cpu)true or false-->
<add key="sendLogPrint" value="false"/>
<!--消息是否等待服务端同步应答(如果开启,服务器来不及回复应答的时候,控制台看上去就像假死了)true or false-->
<add key="waitReceive" value="false"/>
<!--控制台是否打印接收日志(消耗大量cpu),该开关只有开启了服务端应答之后才有效 true or false-->
<add key="receiveLogPrint" value="false"/>
</appSettings>
<log4net debug="false">
<root>
<level value="DEBUG"/>
<appender-ref ref="RollingLogFileAppender"/>
<appender-ref ref="log_console"/>
</root>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="log\applog.txt"/>
<param name="AppendToFile" value="true"/>
<param name="MaxSizeRollBackups" value="10"/>
<param name="MaximumFileSize" value="5MB"/>
<param name="RollingStyle" value="Size"/>
<param name="StaticLogFileName" value="true"/>
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c %n%m%n"/>
</layout>
</appender>
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<!-- A1 uses PatternLayout -->
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-4timestamp [%thread] %-5level %logger %ndc - %message%newline"/>
</layout>
</appender>
<appender name="UdpAppender" type="log4net.Appender.UdpAppender">
<param name="RemoteAddress" value="localhost"/>
<param name="RemotePort" value="4931"/>
<param name="Encoding" value="utf-8"/>
<layout type="log4net.Layout.PatternLayout" value="{%level}%date{MM/dd HH:mm:ss} - %message"/>
</appender>
<appender name="log_console" type="log4net.Appender.ColoredConsoleAppender, log4net">
<mapping>
<level value="FATAL"/>
<foreColor value="Red"/>
<backColor value="White"/>
</mapping>
<mapping>
<level value="ERROR"/>
<foreColor value="Red, HighIntensity"/>
</mapping>
<mapping>
<level value="WARN"/>
<foreColor value="Yellow"/>
</mapping>
<mapping>
<level value="INFO"/>
<foreColor value="Cyan"/>
</mapping>
<mapping>
<level value="DEBUG"/>
<foreColor value="Green"/>
</mapping>
<layout type="log4net.Layout.PatternLayout">
<param name="Header" value="*********************************** "/>
<param name="Footer" value=" "/>
<param name="ConversionPattern" value="[%p] %message%newline"/>
</layout>
</appender>

</log4net>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>

BIN
dll/Plugin.Common.dll Bestand weergeven


BIN
dll/log4net.dll Bestand weergeven


Laden…
Annuleren
Opslaan