【问题标题】:C# Receiving Packet in System.SocketsC# 在 System.Sockets 中接收数据包
【发布时间】:2012-09-07 23:45:21
【问题描述】:

在我的客户端服务器应用程序中,我想知道如何制作数据包并通过客户端将其发送到服务器

然后在服务器上我识别出这是哪个数据包并发送正确的重播

但我突然想到了这个话题,这让我担心我是否会陷入这个问题

问题

设计人员最常见的初学者错误之一 TCP/IP 的协议是它们假设消息边界是 保存。例如,他们假设单个“发送”将导致 单个“接收”。

部分原因是某些 TCP/IP 文档。很多人读 关于 TCP/IP 如何保存数据包 - 必要时将它们拆分 并在接收方重新订购和重新组装。这是 完全正确;但是,单个“发送”不会发送单个 数据包。

本地机器(环回)测试证实了这种误解, 因为通常当客户端和服务器在同一台机器上时,它们 通信速度足够快,以至于单个“发送”实际上确实对应 单“收到”。不幸的是,这只是一个巧合。

此问题通常在尝试部署 互联网解决方案(增加客户端和 服务器)或尝试发送大量数据时(需要 碎片化)。不幸的是,在这一点上,该项目通常是 在其最后阶段,有时应用程序协议甚至 已发布!

真实故事:我曾经在一家开发定制客户端/服务器软件的公司工作。 原来的通讯代码做到了这一点 常见的错误。但是,他们都在专用网络上 高端硬件,所以根本问题只发生在非常 很少。当它发生时,运营商只会把它归结为“那个 错误的 Windows 操作系统”或“另一个网络故障”并重新启动。我的一个 这家公司的任务是改变沟通,包括很多 更多信息;当然,这导致了问题的体现 定期,并且整个应用程序协议必须更改为 修理它。真正令人惊奇的是,该软件已用于 20 年不计其数的 24x7 自动化系统;基本上是 坏了,没人注意到。

那么我怎样才能发送类似 AUTH_CALC,VALUE1=10,VALUE2=12 的数据包并以安全的方式从服务器接收它...

如果你想要一个我在这里做的例子,它在下面

[客户]

Send(Encoding.ASCII.GetBytes("1001:UN=user123&PW=123456")) //1001 is the ID

[服务器]

private void OnReceivePacket(byte[] arg1, Wrapper Client)
{
    try
    {
        int ID;
        string V = Encoding.ASCII.GetString(arg1).Split(':')[0];
        int.TryParse(V, out ID);

        switch (ID)
        {
            case 1001://Login Packet
                AppendToRichEditControl("LOGIN PACKET RECEIVED");
                break;

            case 1002:
                //OTHER IDs
                break;

            default:
                break;
        }
    }
    catch { }         
}

那么这是构造消息并在服务器上处理它的好方法吗?

另外,使用 ASCII 或 UTF8 哪种编码更好?

【问题讨论】:

  • 这不是很清楚 那么这是一种构建消息并在服务器上处理它的好方法吗?另外,使用 ASCII 或 UTF8 哪种编码更好?
  • 我没有编辑它:D 我的意思是我在发送和识别 [服务器端] 数据包时使用的方式是好的,我的意思是打包 id 的方式和这些东西?或者有更好的方法来发送数据包并在服务器上接收它??
  • 我宁愿Send(Encoding.ASCII.GetBytes("#1001:UN=user123&PW=123456\r\n")) 或者更好的是它的二进制等价物。正如安德鲁正确指出的那样,您需要标头或分隔符,并且您必须在服务器端缓冲并检查它们,除非您打开-关闭连接。
  • “这是构建消息的好方法吗”。不,不是。这甚至不是“构造消息”的方式。这只是一些有希望的代码,会犯与您的报价中描述的完全相同的错误。
  • 你只是告诉不,它不是,也没有为我提供任何关于如何构建消息以及如何不填写相同错误的参考!!!!

标签: c# sockets client-server


【解决方案1】:

最好的方法是使用长度指示器。假设您正在发送一个 10000 字节的文件,首先发送文件的长度并从另一端接收 ack 即“OK”字符串,然后继续逐块发送 10,000 字节(可能你可以占用 4096 字节)。每次发送 4096 个字节,分两次发送,最后一个块发送 2000 个奇数字节。在接收方,无法保证一次发送您将收到全部 4096 字节,因此您需要等到您收到 4096 字节,然后再继续下一个 4096 字节。

【讨论】:

    猜你喜欢
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    相关资源
    最近更新 更多