在我的客户端服务器应用程序中,我想知道如何制作数据包并通过客户端将其发送到服务器
然后在服务器上我识别出这是哪个数据包并发送适当的重播
但突然间我遇到了这个话题,这让我担心如果我可能会遇到这个问题
问题
人们设计中最常见的初学者错误之一 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哪个编码更好?
答案 0 :(得分:1)
您可以做的最好方法是使用长度指示器。假设您正在发送10000字节的文件,首先发送文件的长度并从另一侧接收ack即“OK”字符串,然后继续按块发送10,000字节块(可能是您可以占用4096字节)。每次发送4096个字节两次,并在最后一个块上发送2000个奇数字节。在接收器端没有任何一个发送,你将收到整个4096字节的gauranty,所以你需要等到你得到4096字节,然后继续下一个4096字节。