C# C语言中基于TCP的面向对象通信#
我正在开发一个简单的应用程序,它将通过TCP从硬件接收数据。 我在互联网上搜索了一些如何开发一个程序来接收TCP数据,但没有找到任何我满意的东西。它要么是对如何在C#中使用TCP的非常简化的描述,要么是对高级框架的描述 我想要一个简单的最佳实践,说明如何以良好的面向对象方式组织程序的通信部分。有什么建议吗 理想情况下,我希望通过TCP发送的不同结构存储在程序的相应结构中 发送内容的结构:C# C语言中基于TCP的面向对象通信#,c#,oop,design-patterns,tcp,C#,Oop,Design Patterns,Tcp,我正在开发一个简单的应用程序,它将通过TCP从硬件接收数据。 我在互联网上搜索了一些如何开发一个程序来接收TCP数据,但没有找到任何我满意的东西。它要么是对如何在C#中使用TCP的非常简化的描述,要么是对高级框架的描述 我想要一个简单的最佳实践,说明如何以良好的面向对象方式组织程序的通信部分。有什么建议吗 理想情况下,我希望通过TCP发送的不同结构存储在程序的相应结构中 发送内容的结构: Head { Int16 Mode; Time Start_time //(Unix
Head
{
Int16 Mode;
Time Start_time //(Unix time)
Int16 Number of records
}
for each record if mode == 1
char[20] Name_of_record
for each record
float Value_of_record //(hardware-specific float)
Int16 Flag_of_record
Foot
{
Time Stop_time //(Unix time)
}
每分钟发送一次。
没有开销。它只发送所有变量的值,不再发送更多
编辑
我对服务器没有任何控制权 通常步骤相同: 1) 从tcp流读取数据并将其存储在缓冲区(通常是字节数组)中 2) 持续检查缓冲区(每次更新时),以确定是否已到达完整的数据包 3) 解析缓冲区并将数据包提取到所需的OO对象 4) 将对象添加到队列以进一步处理,或调用后台线程以使用数据包对象 通过输出流发送数据的顺序几乎是相反的 处理缓冲区时,事情会变得复杂/嘈杂/痛苦。您需要处理二进制数据,以确定一个数据包何时结束,另一个数据包何时开始。当然,这与您正在通信的设备的协议有关,如果它发送固定长度的数据包或开始/停止字节等。。。 目前还没有标准的解决方案,因为您要编写的代码取决于设备发送的数据 编辑:您用一个示例代码更新了您的问题,但这与记录的结构无关,这部分内容编写起来简单而冗长(如果您的结构有一个
int
字段,您可以从缓冲区读取4个字节,然后使用位转换器
类将字节转换为int)。您需要阅读硬件手册以检查它发送数据的格式(同样,开始/停止字节、固定长度等)
这是非常抽象的,因为它针对每种情况,没有“烘焙解决方案”。此外,您似乎不了解streams/tcp连接/二进制数据包是如何工作的,是什么让您认为这是tcp连接的问题,但事实并非如此。Tcp连接只是通过网络发送的字节流,您可以使用相同的模式从磁盘上的文件或串行端口读取二进制数据 我们可以使用异步通信接收TCP消息 初始化服务器套接字并尝试连接: 成功连接时: 处理收到的消息:
IMHO,最广泛使用的方法是,首先,您使用哪些硬件进行通信。有几个设备,它们都有自己的API,这些API用于与它们通信,否则你需要编写一些代码,以便从特定端口获取数据。硬件非常奇怪。但沟通是非常直接的。它只发送所有变量的值而不会产生开销CodeProject中有一篇文章称为“C#中的完整TCP服务器/客户端通信和RMI框架”,实现和使用都是。在所谓的“如何编写基于Tcp/Ip的可伸缩服务器”中还有一个很好的问题,即。这些链接对您的问题没有确切的答案,但它们在您的情况下可能很有用。但这要求客户端和服务器都使用此框架?我无法控制与之通信的硬件。协议已经定义。
// Specify the size according to your need.
private byte[] bytData = new byte[1024 * 50000];
private Socket oServerSocket;
private void WindowLoaded(object sender, RoutedEventArgs e)
{
try
{
// We are using TCP sockets
this.oServerSocket = new Socket(
addressFamily: AddressFamily.InterNetwork,
socketType: SocketType.Stream,
protocolType: ProtocolType.Tcp);
// Assign the any IP of the hardware and listen on port number which the hardware is sending(here it's 5656)
var oIPEndPoint = new IPEndPoint(address: IPAddress.Any, port: 5656);
// Bind and listen on the given address
this.oServerSocket.Bind(localEP: oIPEndPoint);
this.oServerSocket.Listen(backlog: 4);
// Accept the incoming clients
this.oServerSocket.BeginAccept(this.OnAccept, null);
this.oLogger.WriteLog("Server started");
}
catch (Exception ex)
{
// Handle Exception
}
}
private void OnAccept(IAsyncResult ar)
{
try
{
var oClientSocket = this.oServerSocket.EndAccept(asyncResult: ar);
// Start listening for more clients
this.oServerSocket.BeginAccept(callback: this.OnAccept, state: null);
// Once the client connects then start receiving the commands from her
oClientSocket.BeginReceive(
buffer: this.bytData,
offset: 0,
size: this.bytData.Length,
socketFlags: SocketFlags.None,
callback: this.OnReceive,
state: oClientSocket);
}
catch (Exception ex)
{
// Handle Exception
}
}
private void OnReceive(IAsyncResult ar)
{
try
{
var oClientSocket = (Socket)ar.AsyncState;
oClientSocket.EndReceive(asyncResult: ar);
/* Process the data here
BitConverter.ToInt32(value: this.bytData, startIndex: 0);
string SomeString= Encoding.ASCII.GetString(bytes: this.bytData, index: 8, count: 5);
*/
// Specify the size according to your need.
this.bytData = null;
this.bytData = new byte[1024 * 50000];
oClientSocket.BeginReceive(
buffer: this.bytData,
offset: 0,
size: this.bytData.Length,
socketFlags: SocketFlags.None,
callback: this.OnReceive,
state: oClientSocket);
}
catch (Exception ex)
{
// Handle Exception
}
}