在我的客户端服务器应用程序中,我想知道如何制作一个数据包并通过客户端将其发送到服务器
然后在服务器上我识别出这是哪个数据包并发送正确的重播
但是突然间我遇到了这个话题,这让我担心我是否会陷入这个问题
问题
对于为 TCP/IP 设计协议的人来说,最常见的初学者错误之一是他们假设消息边界被保留。例如,他们假设单个“发送”将导致单个“接收”。
部分 TCP/IP 文档应归咎于此。许多人读到 TCP/IP 如何保存数据包——在必要时将它们拆分,并在接收端重新排序和重新组装它们。这是完全正确的;但是,单个“发送”不会发送单个数据包。
本地机器(环回)测试证实了这种误解,因为通常当客户端和服务器在同一台机器上时,它们的通信速度足够快,以至于单个“发送”实际上对应于单个“接收”。不幸的是,这只是一个巧合。
当尝试将解决方案部署到 Internet(增加客户端和服务器之间的延迟)或尝试发送大量数据(需要分段)时,通常会出现此问题。不幸的是,此时项目通常处于最后阶段,有时甚至已经发布了应用协议!
真实故事:我曾经在一家开发定制客户端/服务器软件的公司工作。最初的通信代码犯了这个常见的错误。但是,它们都在具有高端硬件的专用网络上,因此根本问题很少发生。当它发生时,运营商只会将其归结为“那个有问题的 Windows 操作系统”或“另一个网络故障”并重新启动。我在这家公司的一项任务是改变沟通方式以包含更多信息;当然,这导致问题经常出现,并且必须更改整个应用程序协议才能解决它。真正令人惊奇的是,这个软件已经在无数的 24x7 自动化系统中使用了 20 年;它从根本上被破坏了,没有人注意到。
那么我怎么能发送类似 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 哪种编码更好?