我创建了一个简单的基于TCP的服务器,并有这个ClientHandle脚本。这个问题有点复杂。
public class ClientHandle
{
public static event Action OnAddedDevice;
public static void Welcome(Packet packet)
{
string msg = packet.ReadString();
int myId = packet.ReadInt();
Client.instance.myId = myId;
ClientSend.WeclomeReceived();
}
public static void AddDevice(Packet packet)
{
int myId = packet.ReadInt();
OnAddedDevice?.Invoke();
}
}
并且在启动WPF时订阅OnAddedDevice事件
public NetLogic(MainWindow mainWindow)
{
_mainWindow = mainWindow;
ClientHandle.OnAddedDevice += TestA;
StartServer();
Client client = new Client();
client.ConnectToServer();
}
我的客户类
public class Client
{
public static Client instance;
public static int dataBufferSize = 4096;
public string ip = "127.0.0.1";
public int port = 26950;
public int myId = 0;
public TCP tcp;
private delegate void PacketHandler(Packet _packet);
private static Dictionary<int, PacketHandler> packetHandlers;
public Client()
{
instance = this;
tcp = new TCP();
}
public void ConnectToServer()
{
InitializeClientData();
tcp.Connect();
}
public class TCP
{
public TcpClient socket;
private NetworkStream stream;
private Packet receivedData;
private byte[] receiveBuffer;
public void Connect()
{
socket = new TcpClient
{
ReceiveBufferSize = dataBufferSize,
SendBufferSize = dataBufferSize
};
receiveBuffer = new byte[dataBufferSize];
socket.BeginConnect(instance.ip, instance.port, ConnectCallback, socket);
}
private void ConnectCallback(IAsyncResult _result)
{
socket.EndConnect(_result);
if (!socket.Connected)
{
return;
}
stream = socket.GetStream();
receivedData = new Packet();
stream.BeginRead(receiveBuffer, 0, dataBufferSize, ReceiveCallback, null);
}
public void SendData(Packet _packet)
{
try
{
if (socket != null)
{
stream.BeginWrite(_packet.ToArray(), 0, _packet.Length(), null, null);
}
}
catch (Exception exception)
{
Console.WriteLine($"Error sending data to server via TCP: {exception}");
}
}
private void ReceiveCallback(IAsyncResult _result)
{
try
{
int _byteLength = stream.EndRead(_result);
if (_byteLength <= 0)
{
// TODO: disconnect
return;
}
byte[] _data = new byte[_byteLength];
Array.Copy(receiveBuffer, _data, _byteLength);
receivedData.Reset(HandleData(_data));
stream.BeginRead(receiveBuffer, 0, dataBufferSize, ReceiveCallback, null);
}
catch
{
// TODO: disconnect
}
}
private bool HandleData(byte[] _data)
{
int _packetLength = 0;
receivedData.SetBytes(_data);
if (receivedData.UnreadLength() >= 4)
{
_packetLength = receivedData.ReadInt();
if (_packetLength <= 0)
{
return true;
}
}
while (_packetLength > 0 && _packetLength <= receivedData.UnreadLength())
{
byte[] _packetBytes = receivedData.ReadBytes(_packetLength);
ThreadManager.ExecuteOnMainThread(() =>
{
using (Packet _packet = new Packet(_packetBytes))
{
int _packetId = _packet.ReadInt();
packetHandlers[_packetId](_packet);
}
});
_packetLength = 0;
if (receivedData.UnreadLength() >= 4)
{
_packetLength = receivedData.ReadInt();
if (_packetLength <= 0)
{
return true;
}
}
}
if (_packetLength <= 1)
{
return true;
}
return false;
}
}
private void InitializeClientData()
{
packetHandlers = new Dictionary<int, PacketHandler>()
{
{ (int)ServerPackets.welcome, ClientHandle.Welcome },
{ (int)ServerPackets.AddDevice, ClientHandle.AddDevice },
};
}
}
测试A在mainWindow类中有简单的方法调用
public void TestA()
{
var mainWindow = Application.Current.Windows.OfType<MainWindow>().FirstOrDefault();
mainWindow.GoToPage();
}
并在服务器启动后10秒内调用AddDevice方法。所以当我调用这个方法时,WPF崩溃,我得到了这些错误enter image description here
非常感谢你的帮助。我将很乐意分享其他需要的信息,以更好地了解问题。
我试着直接调用方法并创建所有的示例,我更改了包信息,所以我只是不知道还有什么可以帮助。
1条答案
按热度按时间uelo1irk1#
其实我解决了一个问题我从新线程调用主窗口中的方法。所以我就用了
System. out. println(new Action(MyMethodInMainWindow));