2016-08-25 47 views
0

所以我编写了代码,以便我可以与服务器和客户端进行通信。使用套接字与客户端和服务器进行通信

  • 第一个问题是服务器如何识别它与实际客户端通信,而不是其他人使用该端口,我听说浏览器使用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]); 
+0

你的代码是坏了,你不知道有多少字节被放置在'ReceiveBuffer' (你忽略了来自'Read'的返回值,它会告诉你),所以把整个缓冲区转换成一个字符串是不安全的。不能保证在一端调用Write和调用Read对象相匹配, –

回答

1

你的第一个问题涉及认证,这是一个很大的主题,并有许多可能的实现,尽管我不确定你的意思是“别人谁使用该端口”。您的服务器应始终位于同一端口 - 客户端如何识别服务。

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

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

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

这可能看起来复杂,但不幸的是,在TCP层,它不会比任何:(简单

+0

中说明,这很有道理。我尝试发送文件流,但与使用http相比,它速度较慢且不可靠 –

2
  1. 提供一些认证机制
  2. 使用一些串行器。
+0

嗯,我假设你在谈论对象序列化,现在我正在研究它,还可以指向我的一些认证方法,这些方法可以用于我的模型吗? –

+0

你可以做一些天真的事情,比如期望预定义客户端的令牌(如果没有确定关闭通信)或者做像th这样的高级事物可以在http://www.codeproject.com/Articles/14155/An-Asynchronous-Socket-Server-and-Client – sam

0

的第一个问题是,服务器如何确定它与实际的客户沟通,而不是别人谁在使用的端口,我听说浏览器验证使用SHA哈希服务器。

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

第二个问题是关于对变量的发送和接收数据的最佳方式,并且还确定哪个是哪个,因为分割数据电流的方法似乎并不很优雅。

它取决于你的协议体系结构,但在网络上交换值的便携方式是保持文本格式(这种方式没有字节顺序,字体大小等问题)。

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

0

您可能想要定义某种通信协议 - 基于文本的协议最简单,首先,您可以在单独的一行上读写每个“命令”。

首先,会出现一个“握手”,客户端会发送类似“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以获取灵感。

相关问题