socket发过来的消息用什么符号做分割符

luluyy 2016-05-03 02:24:23
比如客户端要进行登录,需要把帐号、密码、验证码发给服务端,帐号、密码、验证码 三个条件用什么分隔符区分开呢?用, 还是| 还是# 但是不管用什么符号万一用户输入了这个符号就登录失败了,请问有什么好的办法吗? 别外socket的传输用的二进制的方式,我想问一个 一个对像 比如DataSet怎么转成二进制流呢 在线等 谢谢
...全文
847 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
luluyy 2016-05-06
  • 打赏
  • 举报
回复
引用 9 楼 crystal_lz 的回复:
所以说才有数据结构 和 消息协议这一东西的存在 我这人比较懒 通常以差不多这样的数据格式发送数据 { 2字节 -> 数据长度(不包括此两字节) 1字节 -> 消息类型(程序中被定义为枚举) x字节 -> 这里是数据部分(具体数据格式根据 上面的消息类型确定) } 而如果是对于你这种登录 估计我的数据包是这样的 { 17, //数据长度 1, //1被定义为登录 数据部分则表示 用户 密码 验证码 'user\0pass\0verify' //实际的数据 } 而上面的3个数据 我直接用 \0 才分 因为 如果是用户输入 用户是不可能从键盘上输入出 \0 出来的 如果说 用户自己发包模拟 自己乱构造数据 我以 \0 拆分出来的结果不是3个 我只能默默的返回 数据不合法了 不过在实际的项目中 通常我们会自己做web接口 所有的数据什么的 以web url的方式提交 这样自己就压根不用管数据以什么样子的形式传输 只管接受数据就是了
修改: 你说的可是webservice接口?
luluyy 2016-05-06
  • 打赏
  • 举报
回复
引用 9 楼 crystal_lz 的回复:
所以说才有数据结构 和 消息协议这一东西的存在 我这人比较懒 通常以差不多这样的数据格式发送数据 { 2字节 -> 数据长度(不包括此两字节) 1字节 -> 消息类型(程序中被定义为枚举) x字节 -> 这里是数据部分(具体数据格式根据 上面的消息类型确定) } 而如果是对于你这种登录 估计我的数据包是这样的 { 17, //数据长度 1, //1被定义为登录 数据部分则表示 用户 密码 验证码 'user\0pass\0verify' //实际的数据 } 而上面的3个数据 我直接用 \0 才分 因为 如果是用户输入 用户是不可能从键盘上输入出 \0 出来的 如果说 用户自己发包模拟 自己乱构造数据 我以 \0 拆分出来的结果不是3个 我只能默默的返回 数据不合法了 不过在实际的项目中 通常我们会自己做web接口 所有的数据什么的 以web url的方式提交 这样自己就压根不用管数据以什么样子的形式传输 只管接受数据就是了
亲 我说的可是webservice接口?
  • 打赏
  • 举报
回复
比如说上面有人说可以用 url 参数形式,这当然也是可以的。你在编写 web程序中应该学习过,就算是参数中有 & 符号,在形成 url 参数串的时候也被 UrlEncode 函数转义为不含 & 符号的内容了。因此UrlEncode 也是一种不错的形式(当然没有json那样能很好地表示复杂的对象结构)。总之,有无数种非常简单好用的编码形式,你都可以任选一种。 关于所谓“dataset转成二进制流”的问题,我觉得你有点过于纠结于底层了。在.net 中有大量现成的方法框架将dataset 通常序列化为 json、xml等层次的这些形式。 而所谓“二进制流”只是底层的东西,如果把低级的东西直接用来表示高层的东西那反而是搞不清楚的。
  • 打赏
  • 举报
回复
引用 13 楼 luluyy 的回复:
修改: 你说的可是webservice接口?
他说的是在每一个消息的开头的2个字节表示后边消息内容长短,而不用分隔符。这在传输纯二进制(而非文本)数据时,就只能如此来设计。
  • 打赏
  • 举报
回复
分隔符可以随便自定义。例如你用“982ladlfakl28349osfaks!@!#!akd"作为分隔符,那么万一发送消息中有“982ladlfakl28349osfaks!@!#!akd"内容,你可以要求它写为“982ladlfakl28349osfaks!@!#!akd982ladlfakl28349osfaks!@!#!akd"。在接收端,你在收到“982ladlfakl28349osfaks!@!#!akd",可以判断是否紧接着又是一个“982ladlfakl28349osfaks!@!#!akd",如果是则跳过(不作为分隔符)。 另外其它方面,假设你传输的信令是基于json或者xml的,你会看到,它们的标准形式根本不含有两个字节的 \r\n。(如果你看到一些打印内容包含 \r\n\,这实际上可以删除掉,而不影响 json、xml 的解析)。也就是说,有些内容根本不可能含有两个字节的 \r\n的,顶多是在字符串中含有文本的(4个字符的)\r\n,这跟两个字节的 \r\n 不一样。这个时候,用两个字节的 \r\n 也是一种通用的方法。许多基于文本的轻量级 IM 系统都是如此,都是用一行文本就代表一个消息。 实际上你可以看看 http 协议,它用一个 \r\n 作为每一行内容的结束,用两个连续的\r\n作为消息头跟消息体的分隔符。 可见分隔符可以基于二进制方式处理,也可以基于字符编码方式来设计。
liyi189 2016-05-04
  • 打赏
  • 举报
回复
看了半天,你是要用SOCKET实现远程登录吗?那你要定义数据包格式,还有相互之间的通讯协议,数据加密,身份验证等。以前做嵌入式开发的时候做过。如有需要可联系!
yang1216 2016-05-04
  • 打赏
  • 举报
回复
客户端不允许输入奇怪的字符呗
crystal_lz 2016-05-03
  • 打赏
  • 举报
回复
所以说才有数据结构 和 消息协议这一东西的存在 我这人比较懒 通常以差不多这样的数据格式发送数据 { 2字节 -> 数据长度(不包括此两字节) 1字节 -> 消息类型(程序中被定义为枚举) x字节 -> 这里是数据部分(具体数据格式根据 上面的消息类型确定) } 而如果是对于你这种登录 估计我的数据包是这样的 { 17, //数据长度 1, //1被定义为登录 数据部分则表示 用户 密码 验证码 'user\0pass\0verify' //实际的数据 } 而上面的3个数据 我直接用 \0 才分 因为 如果是用户输入 用户是不可能从键盘上输入出 \0 出来的 如果说 用户自己发包模拟 自己乱构造数据 我以 \0 拆分出来的结果不是3个 我只能默默的返回 数据不合法了 不过在实际的项目中 通常我们会自己做web接口 所有的数据什么的 以web url的方式提交 这样自己就压根不用管数据以什么样子的形式传输 只管接受数据就是了
luluyy 2016-05-03
  • 打赏
  • 举报
回复
引用 6 楼 xuzuning 的回复:
如使用 url 参数格式,就应遵守 RFC1738 协议 各种语言都提供有 url 编码和解码函数 所以不存在你的假如
我去试试
Poopaye 2016-05-03
  • 打赏
  • 举报
回复
比如你要发 user = "aaa" psw = "bbb"
//Write
using(BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8))
{
    writer.Write(user);
    writer.Write(psw);
}

//Read
using(BinaryReader reader = new BinaryReader(stream, Encoding.UTF8))
{
    user = reader.ReadString();
    psw = reader.ReadString();
}
xuzuning 2016-05-03
  • 打赏
  • 举报
回复
如使用 url 参数格式,就应遵守 RFC1738 协议 各种语言都提供有 url 编码和解码函数 所以不存在你的假如
luluyy 2016-05-03
  • 打赏
  • 举报
回复
引用 3 楼 xuzuning 的回复:
按行分隔,即用 \r\n 做分隔符 另类点可用 \t (制表符) 正规点用 url 参数串( username=帐号&password=密码&Verification=验证码),这样就不需要按空间位置来解释数据含义了
如果是这样的话 假如用户也输入了&字符 服务器收到了以后是username=帐号&&password=..... 这样我区分的时候怎么取呢
luluyy 2016-05-03
  • 打赏
  • 举报
回复
引用 1 楼 shingoscar 的回复:
长度 + 数据 DataSet可以用BinaryFormatter,json等序列化
现在定义的格式是 命令[比如login] ID值 发送的数据[二进制] 发送的数据里面就包括了用户名密码验证码这些东西 我应该怎么去改一下呢

            var ID = SocketBase.Utils.NetworkBitConverter.ToInt32(buffer.Array, buffer.Offset + 4);
            var flagLength = SocketBase.Utils.NetworkBitConverter.ToInt16(buffer.Array, buffer.Offset + 8);
            var ConName = Encoding.UTF8.GetString(buffer.Array, buffer.Offset + 10, flagLength);

            var dataLength = messageLength - 6 - flagLength;
            byte[] data = null;
            if (dataLength > 0)
            {
                data = new byte[dataLength];
                Buffer.BlockCopy(buffer.Array, buffer.Offset + 10 + flagLength, data, 0, dataLength);
            }

xuzuning 2016-05-03
  • 打赏
  • 举报
回复
按行分隔,即用 \r\n 做分隔符 另类点可用 \t (制表符) 正规点用 url 参数串( username=帐号&password=密码&Verification=验证码),这样就不需要按空间位置来解释数据含义了
Poopaye 2016-05-03
  • 打赏
  • 举报
回复
长度 + 数据 DataSet可以用BinaryFormatter,json等序列化
tinydyw 2016-05-03
  • 打赏
  • 举报
回复
...正常来说特殊符号是不允许用在登录账号和密码里的= =

111,097

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧