对应用程序级协议进行编程的方法?

| 我正在用C#做一些简单的套接字编程。我试图通过从客户端控制台读取用户名和密码,将凭据发送到服务器以及从服务器返回身份验证状态来对用户进行身份验证。基本的东西。我的问题是,如何确保数据采用服务器和客户端都期望的格式? 例如,这是我在客户端上读取用户凭据的方式:
                Console.WriteLine(\"Enter username: \");
                string username = Console.ReadLine();
                Console.WriteLine(\"Enter plassword: \");
                string password = Console.ReadLine();

                StreamWriter clientSocketWriter = new StreamWriter(new NetworkStream(clientSocket));
                clientSocketWriter.WriteLine(username + \":\" + password);
                clientSocketWriter.Flush();
在这里,我在客户端用冒号(或其他符号)来分隔用户名和密码。在服务器上,我只是使用\“:\”作为标记来拆分字符串。这行得通,但似乎……不安全。客户端和服务器之间是否应该共享某种定界符标记,这样我就不必像这样硬编码它了? 服务器响应与此类似。如果身份验证成功,如何以客户端期望的格式发送回响应?我是否只需发送一个\“ SUCCESS \”或\“ AuthSuccessful = True / False \”字符串?我如何确保客户端知道服务器发送数据的格式(不仅仅是将其硬编码到客户端中)? 我想我要问的是如何设计和实现应用程序级协议。我意识到它对您的应用程序来说是唯一的,但是程序员通常使用的典型方法是什么?此外,如何保持格式一致?我也非常感谢一些与此文章相关的链接。
已邀请:
而不是重新发明轮子。为什么不编写XML模式并发送和接收XML“文件”呢? 您的消息肯定会更长,但是如今使用千兆以太网和ADSL几乎不再重要。您所获得的是一个协议,其中所有字符集,复杂的数据结构问题都已解决,此外,还有令人尴尬的工具和库可供选择,以支持和简化您的开发。
基本上,您正在寻找一种标准。 “关于标准的伟大之处在于,有太多选择可供选择”。选择一个并继续使用它,比滚动自己的要容易得多。对于这种特殊情况,可以考虑使用Apache \“ basic \”身份验证,该身份验证将用户名和密码连接起来并对其进行base64编码。
我使用了两种主要方法。 首先是基于ASCII的协议。 基于Ascii的协议通常基于一组文本命令,这些命令在某些已定义的定界符(例如回车符,分号,xml或json)上终止。如果您的协议是基于命令的协议,并且没有来回传输大量数据,那么这是最好的方法。
FIND\\r
DO_SOMETHING\\r
它具有基于文本的优点,因此易于阅读和理解。 缺点(可能不是问题,但可能是问题)是从客户端和服务器来回传输的字节数可能未知。因此,如果您需要确切地知道正在发送和接收多少字节,则可能不是您想要的协议类型。 协议的另一种类型是基于二进制的,并在标头中发送固定大小的消息。这样做的好处是,可以准确地知道预期客户端将接收多少数据。它还可以根据发送的内容来节省带宽。尽管ascii也可以节省您的空间,但这取决于您的应用程序要求。基于二进制的协议的缺点是仅通过查看它就很难理解……要求您不断查看文档。 在实践中,我倾向于将两种策略混入根据应用程序要求定义的协议中。
我极力建议尽可能使用纯ASCII文本。 它使错误更易于检测和修复。 一些常见的机器可读的ASCII文本协议(大致按复杂程度排序): 网串 制表符分隔表 逗号分隔值(CSV)(同时包含逗号和双引号的字符串很难正确处理) INI文件格式 属性列表格式 JSON格式 YAML不是标记语言 XML格式 世界已经足够复杂了,因此我尝试使用最不复杂的协议。 将两个用户生成的字符串从一台机器发送到另一台机器-netstrings是我的列表中最简单的协议,适用于该协议,因此我会选择netstrings。 (即使用户键入一些冒号,分号,双引号或制表符,网络字符串也能正常工作,这与其他会阻塞某些常用字符的格式不同)。 我同意,如果存在某种在单个共享文件中描述协议的方式,这样服务器和客户端都可以以某种方式“ #include \”或以其他方式使用该协议,那将是很好的。 然后,当我修复协议中的错误时,我可以将其修复在一个位置,重新编译服务器和客户端,然后事情就可以了-而不是在两端挖掘一堆硬接线常量。 类似于编写良好的C代码和C ++代码在头文件中使用函数原型的方式一样,以便一侧调用该函数的代码以及另一侧调用该函数本身的代码可以按双方期望的方式传递参数。 告诉我你是否发现类似的东西,好吗?

要回复问题请先登录注册