使用套接字与客户端和服务器通信

本文关键字:服务器 通信 客户端 套接字 | 更新日期: 2023-09-27 18:03:49

所以我已经写了代码,以便我可以与服务器和客户端通信。

  • 第一个问题是服务器如何识别它与实际客户端通信,而不是使用端口的其他人,我听说浏览器使用SHA哈希与服务器进行验证。
  • 第二个问题是关于在变量中发送和接收数据的最佳方式,以及识别哪个是哪个,因为当前分割数据的方法似乎不是很优雅。

服务器端接收和发送数据的代码:

NetworkStream NetStream1 = TCPSocket.GetStream();                       
NetStream.Read(Buffer, 0, Buffer.Length);
ReceivedData = System.Text.Encoding.ASCII.GetString(Buffer);
string[] splitter = ReceivedData.Split('-');
Variable1 = splitter[0];
Variable2 = splitter[1];
//send response
SendBuffer = Encoding.ASCII.GetBytes(ResultINT1+"-"+ResultINT2);
NetStream.Write(SendBuffer, 0, SendBuffer.Length);
NetStream.Flush();

客户端代码发送和接收

NetworkStream SendStream = ClientSocket.GetStream();
byte[] SendBuffer = System.Text.Encoding.ASCII.GetBytes(V1+"-"+V2);
SendStream.Write(SendBuffer, 0, SendBuffer.Length);
SendStream.Flush();
//response
SendStream.Read(RecieveBuffer, 0, RecieveBuffer.Length);
string ResultString = System.Text.Encoding.ASCII.GetString(RecieveBuffer);
string[] splitted = ResultString.Split('-');
int R1 = Convert.ToInt32(splitted[0]);
int R2 = Convert.ToInt16(splitted[1]);

使用套接字与客户端和服务器通信

  1. 提供一些认证机制
  2. 使用一些序列化器

您的第一个问题涉及身份验证,这是一个巨大的主题,有许多可能的实现,虽然我不确定你的意思是"其他人谁正在使用端口"。您的服务器应该始终在相同的端口上-这是客户端识别服务的方式。

关于你的第二个问题,有很多可能性,但我建议初学者最简单的是使用XmlSerializer和一个简单的消息信封。

  1. 创建一个XmlSerializable类,要么使用简单的公共属性,要么用XmlElementAttribute, XmlRootAttribute等装饰。
  2. 序列化到内存流
  3. 从封装在信封中的内存流中写入字节(见后面)
  4. 接收完整的信封成字节数组。
  5. 从字节数组
  6. 构造MemoryStream
  7. 使用XmlSerializer重建原始对象的副本

信封很重要。最简单的就是序列化对象的二进制长度。大多数协议通常会将其扩展为CRC以处理可能的损坏,但由于以太网使用强CRC而TCP是可靠的传输(尽管使用弱CRC),这通常是过度的。初学者忽略的关键点是TCP是一个流协议,而不是基于消息的协议,因此完全有可能发送方进行一次1000字节的写入,而接收方则将其作为许多较小的块接收。这就是为什么您需要某种方法来检测消息的结束,例如使用长度,以及为什么接收方需要累积接收到的块,直到接收到完整的消息(可能是下一条消息的一部分)并可以反序列化。

这可能看起来很复杂,但不幸的是,在TCP级别,没有比这更简单的了:(

第一个问题是服务器如何识别它与实际客户端通信,而不是使用端口的其他人,我听说浏览器使用SHA哈希与服务器进行验证。

服务器可以通过IP地址识别不同的客户端。参见StreamReader.ReadToEnd

第二个问题是关于在变量中发送和接收数据的最佳方式,以及识别哪个是哪个,因为当前分割数据的方法似乎不是很优雅。

这取决于你的协议体系结构,但是在网络上交换值的一种可移植的方式是将它们保存为文本格式(这样就没有端序,类型大小等问题)。

说,要小心你的变量分隔符:'-'可能很难与负数一起使用,' '';'更常见。

您可能想要定义某种通信协议—基于文本的协议将是最直接的开始—然后您可以在单独的行上读取和写入每个"命令"。

首先,会有一个"握手",客户端会发送一些类似"HELLO my-awesome-protocol-v1'n"的东西,服务器也会做出类似的响应。这样你就可以确定对方是一个理解协议的客户端,或者你可以关闭一个不实现协议的连接。

然后可能有一些方式发送变量的值与命令,如"VAR variableName 123.45'n"。你可以阅读https://en.wikipedia.org/wiki/Text-based_protocol和http://www.ncftp.com/libncftp/doc/ftp_overview.html获取灵感。