【问题标题】:What's the best way to send commands through TCP Sockets?通过 TCP 套接字发送命令的最佳方式是什么?
【发布时间】:2014-12-17 12:27:02
【问题描述】:

我目前对服务器和客户端所做的是使用简单的字符串到字节在它们之间发送命令。归根结底基本上是这样的(以向服务器发送消息为例):

byte[] outStream = System.Text.Encoding.UTF8.GetBytes("$msg:Test Message");
serverStream.Write(outStream, 0, outStream.Length);

接收端编码回字符串。它通过这样做来识别命令:

recievedstring.Split(':')[0]

并假设recievedstring.Split(':')[1] 是参数。如果用户在他们的消息中输入了一个冒号,那么它将在那里被切断。我觉得这是一种在两个端点之间发送数据的 hacky 方式。有没有更标准的方法来做到这一点?抱歉,如果我没有提供足够的信息,我是新手!

【问题讨论】:

    标签: c# .net sockets tcp command


    【解决方案1】:

    您不一定需要处理作为字符串传递的所有数据,您可以将数据作为字节传递,然后将字节转换为任何数据类型(由发送方发送)。

    更好的方法是为每个 msg 定义服务器和客户端之间的协议(例如数据包格式)。例如,您可以定义一个数据包,使前 4 个字节包含消息的长度,然后是指定长度的消息。您的数据包格式将是 [length:data]

    在发送端,您需要先在流上写入消息长度,然后再写入实际数据,而在接收端,您将首先接收一个 int(数据长度),然后接收那么多字节。

    此外,如果可以在端点之间通信多种类型的数据包,而不仅仅是 $msg (如您的情况),例如$command, $notification 等你也可以在你的数据包中定义一个消息类型的字段。您的数据包格式将变为 [length:type:data]

    【讨论】:

    • 如何将长度 int 转换为字节数组?长度字节数组的长度是否总是相同的?客户端如何知道如何分离类型和数据?
    • 您可以在 c# 中使用 BitConverter.GetBytes(length) 将 int 转换为字节数组,是的,它的长度将始终相同,即 4 个字节。为了区分类型和数据,type 也可以是 int,所以总是 4 个字节的长度。
    • 所以我的数据包格式会变成[typelength:datalength:type:data]?客户端如何知道要读取多少字节?我现在拥有的是:byte[] buffer = new byte[4096]; int length = serverStream.Read(buffer, 0, buffer.Length); byte[] newbuffer = buffer.Take(length).ToArray(); string returndata = Encoding.UTF8.GetString(newbuffer);
    • 您可以使用 int 作为类型,即 0 用于 msg,1 用于命令,2 用于通知等,如枚举,因此您不需要写入类型长度,客户端将首先读取 4 个字节(长度,并转换为int),比4字节(类型,并转换为int),比'length'字节的数据(因为现在你将拥有数据长度),你可以在收到数据长度时创建缓冲区跨度>
    • serverStream.Read 方法要求我指定一个长度作为参数。我是否会指定长度为 8(以获取类型和长度),然后根据长度创建缓冲区并再次调用 Read?非常感谢您的帮助,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多