有没有一种流推荐用于多线程通信而不丢失数据?
Is there a type of stream that is recommended for multithreading communication without losing data?
我有一个连接 c# (unity) 和 python 的客户端服务器架构。
我需要在 c# 上启动多个线程(多个连接),这些线程将接收一些将从 python 服务器反序列化的数据。
client(c# unity3d) -> c# 中的 6 个线程将从 6 个进程接收数据,这些进程将提供来自 python 的数据,这些数据将被反序列化。
经过一些调试后,我设法看到包以良好的方式从 python 服务器发送。
但是在 c# 上,不同线程上的包要么数据太少,要么数据太多。
我的假设是来自不同线程的套接字在接收数据时发生干扰。
连接器的 C# 代码
public class Connector
{
public string ip = "127.0.0.1";
int bytesRead;
IPAddress ipAddress;
IPHostEntry ipHostInfo;
Socket sender;
int bytesRec;
[SerializeField]
private int dataOut;
public Connector() { }
public void establishConnection(int port)
{
ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
ipAddress = ipHostInfo.AddressList[0];
sender = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
sender.Connect(ip,port);
}
public void Send(byte[] input) {
int bytesSent = sender.Send(input);
}
public byte[] Receive(int index) {
byte[] bytesToRead = new byte[1024 * 1024 * 60];
Array.Clear(bytesToRead, 0, bytesToRead.Length);
try
{
bytesRec = sender.Receive(bytesToRead);
Array.Resize(ref bytesToRead, bytesRec);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
if (bytesRec != 0)
{
return bytesToRead;
}
else
{
return null;
}
}
}
在 main 中,我像这样启动 5 个线程:
for (int x = 1; x <= 4; x++)
{
new ThreadComponent(x, this, featureMapCreator).init();
}
线程组件初始化连接并执行接收部分
Connector socketConnector = new Connector();
socketConnector.establishConnection(60000 + index); // index are from 1 to 4
while (true)
{
doLogicGetData(socketConnector);
}
In doLogicGetData the receive is called
byte[] z = socketConnector.Receive(index);
我也尝试过使用带网络流的 TcpClient,但结果是一样的。
我正在寻找的是 Stream/Socket,它适合在按顺序读取所有数据的多线程环境中在本地计算机上进行通信。目前这个实现并没有一直提供所有数据。
我建议您为六 (6) 个进程线程分配一个唯一的端口号。这应该可以防止“不同的线程在接收数据时发生干扰”。
此外,您可能无法一次接收到所有传输的数据。数据传输可以分成多个数据包,可能需要多次获取才能完成单个传输数据流。每次数据传输都应该有某种方式来标记传输结束,以便get循环可以告诉何时停止获取数据以处理传输。
我有一个连接 c# (unity) 和 python 的客户端服务器架构。 我需要在 c# 上启动多个线程(多个连接),这些线程将接收一些将从 python 服务器反序列化的数据。
client(c# unity3d) -> c# 中的 6 个线程将从 6 个进程接收数据,这些进程将提供来自 python 的数据,这些数据将被反序列化。
经过一些调试后,我设法看到包以良好的方式从 python 服务器发送。
但是在 c# 上,不同线程上的包要么数据太少,要么数据太多。 我的假设是来自不同线程的套接字在接收数据时发生干扰。
连接器的 C# 代码
public class Connector
{
public string ip = "127.0.0.1";
int bytesRead;
IPAddress ipAddress;
IPHostEntry ipHostInfo;
Socket sender;
int bytesRec;
[SerializeField]
private int dataOut;
public Connector() { }
public void establishConnection(int port)
{
ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
ipAddress = ipHostInfo.AddressList[0];
sender = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
sender.Connect(ip,port);
}
public void Send(byte[] input) {
int bytesSent = sender.Send(input);
}
public byte[] Receive(int index) {
byte[] bytesToRead = new byte[1024 * 1024 * 60];
Array.Clear(bytesToRead, 0, bytesToRead.Length);
try
{
bytesRec = sender.Receive(bytesToRead);
Array.Resize(ref bytesToRead, bytesRec);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
if (bytesRec != 0)
{
return bytesToRead;
}
else
{
return null;
}
}
}
在 main 中,我像这样启动 5 个线程:
for (int x = 1; x <= 4; x++)
{
new ThreadComponent(x, this, featureMapCreator).init();
}
线程组件初始化连接并执行接收部分
Connector socketConnector = new Connector();
socketConnector.establishConnection(60000 + index); // index are from 1 to 4
while (true)
{
doLogicGetData(socketConnector);
}
In doLogicGetData the receive is called
byte[] z = socketConnector.Receive(index);
我也尝试过使用带网络流的 TcpClient,但结果是一样的。
我正在寻找的是 Stream/Socket,它适合在按顺序读取所有数据的多线程环境中在本地计算机上进行通信。目前这个实现并没有一直提供所有数据。
我建议您为六 (6) 个进程线程分配一个唯一的端口号。这应该可以防止“不同的线程在接收数据时发生干扰”。
此外,您可能无法一次接收到所有传输的数据。数据传输可以分成多个数据包,可能需要多次获取才能完成单个传输数据流。每次数据传输都应该有某种方式来标记传输结束,以便get循环可以告诉何时停止获取数据以处理传输。