C#在System.Sockets中接收数据包

时间:2012-09-07 23:45:22

标签: c# sockets client-server

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

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

但突然间我遇到了这个话题,这让我担心如果我可能会遇到这个问题

  

问题

     

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

     

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

     

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

     

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

     

真实的故事:我曾经为一家开发自定义客户端/服务器软件的公司工作过。   最初的通信代码就是这样做的   常见的错误。然而,他们都在专用网络上   高端硬件,所以潜在的问题才会发生   很少。当它发生时,操作员就会把它归结为“那个   越野车Windows操作系统“或”另一个网络故障“并重新启动。我的一个   这家公司的任务是改变沟通,包括很多   更多信息;当然,这导致了问题的显现   定期,并且必须将整个应用程序协议更改为   修理它。真正令人惊奇的是这个软件已被用于   无数24x7自动化系统已有20年历史;从根本上说   破碎,没有人注意到。

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

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

[CLIENT]

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

[SERVER]

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 { }         
}

这是构建Message并在服务器上处理它的好方法吗?

使用ASCII或UTF8哪个编码更好?

1 个答案:

答案 0 :(得分:1)

您可以做的最好方法是使用长度指示器。假设您正在发送10000字节的文件,首先发送文件的长度并从另一侧接收ack即“OK”字符串,然后继续按块发送10,000字节块(可能是您可以占用4096字节)。每次发送4096个字节两次,并在最后一个块上发送2000个奇数字节。在接收器端没有任何一个发送,你将收到整个4096字节的gauranty,所以你需要等到你得到4096字节,然后继续下一个4096字节。