参考一下,向服务器发送socket数据流
1.socket连接上,向服务器发送指定格式的报文,将数据进行封包,命令头(1字节)+命令(2字节)+长度(2字节 什么数据的长度)+数据区域+crc32校验码(4字节)
2.按照业务流程进行发送报文,回来的报文数据进行拆包,按照回来的报文的数据格式进行解包。
【将数据进行封包,命令头(1字节)+命令(2字节)+长度(2字节 什么数据的长度)+数据区域+crc32校验码(4字节)】
这种使用C#代码怎么写??麻烦写个例子,谢谢。
@久久小垠: http://www.cnblogs.com/huapiaoshuiliuxi/p/4841011.html 如果文件还在的话自己弄来看。
@久久小垠: 这是我之前写的代码 个人理解 你可以参考一下 将要发送的文本或者数据进行封包成byte[] 通过socekt发送到服务端 具体按找你的报文格式进行修改(包头+内容+包尾)返回回来的流按照指定的报文格式进行拆包 得到数据
/// <summary>
/// 包头 0x68, 0x68, 0x16, 0x16
/// </summary>
/// <returns></returns>
public byte[] GetHeader()
{
byte[] header = new byte[4] { 0x68, 0x68, 0x16, 0x16 };
return header;
}
/// <summary>
/// 包尾 0x55, 0xAA, 0x55, 0xAA
/// </summary>
/// <returns></returns>
public byte[] GetEnder()
{
byte[] ender = new byte[4] { 0x55, 0xAA, 0x55, 0xAA };
return ender;
}
/// <summary>
/// 指令序号
/// </summary>
/// <returns></returns>
public static byte[] GetCmd()
{
byte[] cmd = new byte[4] { 0x0, 0x0, 0x0, 0x0 };
return cmd;
}
/// <summary>
/// 封包
/// </summary>
/// <param name="xmlData"></param>
/// <returns></returns>
public byte[] PackData(string xmlData)
{
//aes 加密 OK
string xml = MyAES.AESEncrypt(xmlData);//AES.AESEncrypt(xmlData);
byte[] _Data = Convert.FromBase64String(xml);
byte[] _LengthData = new byte[4];
MessageLength = 4 + _Data.Length;//4为指令序号的长度
_LengthData = BitConverter.GetBytes(MessageLength);
List<byte> _ValiData = new List<byte>();//有效数据
_ValiData.AddRange(GetCmd());
_ValiData.AddRange(_Data);
short crc = (short)CRCHelper.GetValue(_ValiData.ToArray(), 0, _ValiData.Count);
byte[] CRCCode = new byte[2];
CRCCode = BitConverter.GetBytes(crc);
List<byte> _PackData = new List<byte>();//完整包
//组合PackData
_PackData.AddRange(GetHeader());
_PackData.AddRange(_LengthData);
_PackData.AddRange(_ValiData);
_PackData.AddRange(CRCCode);
_PackData.AddRange(GetEnder());
return _PackData.ToArray();
}
@SAI2014: 谢谢,我先看一下
这个已经找到了,谢谢。现在正在搞解包的过程
@SAI2014: 你这个封包的过程很清楚,解包是怎么解的?
@久久小垠: 解包不是就逆向过程吗?根据返回包的信息组成协议进行解析。代码如下 参考一下
/// <summary>
/// 判断两个byte数组是否一致
/// </summary>
/// <param name="soure"></param>
/// <param name="target"></param>
/// <returns></returns>
public static bool IsSame(byte[] soure, byte[] target)
{
bool isSame = true; ;
if (soure.Length == target.Length)
{
for (int i = 0; i < soure.Length; i++)
{
if (soure[i] != target[i])
{
isSame = false;
break;
}
}
}
else
{
isSame = false;
}
return isSame;
}
public string UnPack(byte[] recByte)
{
byte[] header = new byte[4];
byte[] ender = new byte[4];
byte[] lengther = new byte[4];
byte[] cRcCode = new byte[2];
if (recByte.Length <= 4 + 4 + 4 + 2)
{
throw new Exception("网络流长度不正确");
}
Array.Copy(recByte, 0, header, 0, 4);
//不是包头
bool same = IsSame(GetHeader(), header);
if (!same)
{
throw new Exception("报文包头不匹配!");
}
Array.Copy(recByte, 4, lengther, 0, 4);
int validteLength = BitConverter.ToInt32(lengther, 0);
if (recByte.Length != (4 + 4 + validteLength + 2 + 4))
{
throw new Exception("报文长度不匹配");
}
byte[] validateData = new byte[validteLength];
byte[] xmlData = new byte[validteLength - 4];
Array.Copy(recByte, 8, validateData, 0, validteLength);
short crc = (short)CRCHelper.GetValue(validateData, 0, validateData.Length);
byte[] CRCCode = new byte[2];
CRCCode = BitConverter.GetBytes(crc);
Array.Copy(recByte, 8 + validteLength, cRcCode, 0, 2);
//找到CRC
bool crcsame = IsSame(cRcCode, CRCCode);
if (!crcsame)
{
throw new Exception("有效数据长度CRC验证失败!");
}
Array.Copy(validateData, 4, xmlData, 0, validteLength - 4);
string data = Convert.ToBase64String(xmlData);
string xml = MyAES.AESDecrypt(data);//解密得到内容
return xml;
}
1.socket是传出去一个字节流
2.这个字节流有格式.
3.格式就是1.第一个字节为0x02 2.接着2个字节是命令编号.比如你这个上传证书命令.编码就是0X0700 3.接着2个字节是后面的数据长度,4.然后接着要发送的实际数据字节流.5.crc校验码.这时要问一下.这个校验码包括哪些部分.是前面全部.还是只有数据域
校验码 前面的数据域那一部分
@久久小垠: 然后你的问题是啥.我有点搞不懂.这个图片上写的挺清楚的.
@吴瑞祥: 我不知道怎么写那个组装报文的代码,=_=||
@久久小垠: 意思是不会操作数组?
@吴瑞祥: 不是,我在网上找了些例子,我是直接定义数组还是组装好字符串之后转成Byte数组好一点?
@久久小垠: 你这个情况明显是字节数组啊.不管字符串的事情.
@吴瑞祥: 大神 CRC32 校验位怎么取?