请问按TCP协议,用soket发送这样的数据,应该按照什么格式?

问题描述:

图片说明
如图所示,每行数据都是一个控制电文。比如我想打开设备3,就发送图中所示的 01 05 00 02 FF 00 2D FA,这些都是十六进制数,用scoket发送。这个设备用的是虚拟串口,服务器端是硬件解包,我是做上位机(客户端)的。

以打开设备3为例,我尝试了发送
BYTE buff[]={0x01,0x05,0x00,0x02,0xFF,0x00,0x2D,0xFA};
send(sClient,(LPCSTR)buff,8,0)
但是设备3没有打开,我用一个叫net tools的小工具作为服务器端测试,显示没有接受到任何数据,但是我觉得这样是符合send函数的使用方法的啊,怎么会没反应的。。。
我又尝试了发送 char buff[]="01 05 00 02 FF 00 2D FA ",设备3还是没有打开,用net tools接收数据,显示接收到01 05 00 02 FF 00 2D FA.

我不明白的地方是,send 函数到底应该怎么发送十六进制的字符串呢?我觉得我第二次尝试的办法发送的不是十六进制数啊,它应该会根据ascii码解释为其他形式的十六进制数吧。ps:这个设备还有其他形式的电文 如wx2010+0x0A这样的形式,都是按
它们的ASCII码解的。
我是新手,刚接触这些,我用C++编写代码,但是我对string类了解不是很深刻,请问是应该用string类型发送吗?希望有高手可以帮我解答一下,最好可以给我推荐一些相关的书籍或者资料,非常感谢!!如果能有个例子的话,就更好了。

数据在传输过程中都是byte的,也就是説你发送或者接收的数据都是byte[]类型的,在程序中,协议和发送接收是分离开的,发送接收只负责接收byte[]数据或发送byte[]数据,不会又协议的问题导致无法接收到数据的情况。你这样测试:
首先测试下你的发送模块是否能发送出去数据,发送什么数据随意,接收端可以随便下载个socket测试工具来接收,能接收了再把服务端切换为自己写的接收程序,在Recevie的下一行直接打印出byte[]数据,如果能打印出来的话说明发送接收没问题,记得这个要多测试几遍。
发送接收没问题后要测试下协议的组装与解析有没有问题,先检查下发送的时候用的是什么编码方式,接收的时候你要用同样的编码方式来解析,按照:BYTE buff[]={0x01,0x05,0x00,0x02,0xFF,0x00,0x2D,0xFA};你这种做法就是直接16进制数据转byte的,所以你接收到数据后不能用ascii来解码,解码会出现乱码,这种情况你要对buff数据一个个位去转为16进制,然后判断每一位的值;
按照你后面说的char buff[]="01 05 00 02 FF 00 2D FA "其实就是一个string类型的,因为你后面还有wx2010+0x0A这种的报文;
所以你整个的做法应该是:
1、原始协议是字符串类型的,然后通过ascii编码转为byte数组,然后通过send(byte[],......)方法发送出去;
2、接收到byte数组后按照ascii编码把数据转为string,然后对string进行解析判断;

TCP是有连接的,在有连接的情况下无论接收端是否处理数据,都会发送成功(网卡已经缓存)

参考http://blog.csdn.net/prsniper/article/details/6781270

通过套接字发出去的肯定是Byte[]数组,下面这个ByteToHexString方法就是把Byte数组转换了字符串格式的十六进制字符串串。
例如:BYTE buff[]={0x01,0x05,0x00,0x02,0xFF,0x00,0x2D,0xFA};会转为 01050002FF002DFA
///
/// 将Byte数组的Hex以char形式转换出来
///
///
public string ByteToHexString(byte[] objByte)
{
string objStringList = string.Empty;
foreach (var objbyte in objByte)
{
objStringList += ByteToString(objbyte);
}
return objStringList;
}
///
/// 将一个Byte转换为String;
///
/// 一个Byte字节
///
private string ByteToString(byte data)
{
string objString = string.Empty;
objString += ByteToChar(GetHightBit(data)).ToString();
objString += ByteToChar(GetLowBit(data)).ToString();
return objString;
}
///
/// 获取Byte的高八位
///
///
///
private byte GetHightBit(byte data)
{
data >>= 4;
return data;
}
///
/// 提取Byte的低八位
///
///
///
private byte GetLowBit(byte data)
{
data &= 0x0f;
return data;
}
///
/// 将Byte转换为Char
///
///
///
private char ByteToChar(byte objByte)
{
if (objByte == 0x00) { return '0'; }
if (objByte == 0x01) { return '1'; }
if (objByte == 0x02) { return '2'; }
if (objByte == 0x03) { return '3'; }
if (objByte == 0x04) { return '4'; }
if (objByte == 0x05) { return '5'; }
if (objByte == 0x06) { return '6'; }
if (objByte == 0x07) { return '7'; }
if (objByte == 0x08) { return '8'; }
if (objByte == 0x09) { return '9'; }
if (objByte == 0x0A) { return 'A'; }
if (objByte == 0x0B) { return 'B'; }
if (objByte == 0x0C) { return 'C'; }
if (objByte == 0x0D) { return 'D'; }
if (objByte == 0x0E) { return 'E'; }
if (objByte == 0x0F) { return 'F'; }
else return ' ';

                    下面这段代码是用来做字符串求校验和输出的就是十六进制的字符串
                    /// <summary>
    /// Byte数组求累加和高位自动忽略
    /// </summary>
    /// <param name="SumByte"></param>
    /// <returns></returns>
    public string 十六进制字符串求和(byte[] SumByte)
    {
        int result = 0;
        for (int i = 0; i < SumByte.Length; i++)
        {
            result = (result + SumByte[i]) % 0xffff;
        }
        byte[] key = BitConverter.GetBytes(result);
        string returnString = string.Empty;
        returnString = ByteToString(key[0]);
        return returnString;
    }

手写一个recv的函数,然后看是否能收到数据,收到数据之后打印每个字节的值。

一般情况下不应该是这么做的,应该有个协议之类的文档,规定了消息发送的格式。