朝、私はTCPサーバーとTCPクライアントを持っています。サーバーのコードは次のとおりです。
public static class Server
{
private static IPEndPoint endPoint;
private static TcpListener tcpServer;
private static List<Client> clients;
private static Thread threadListen;
private static ASCIIEncoding encoding;
public static void Initialize(IPAddress allowedIPAddress, int port)
{
endPoint = new IPEndPoint(allowedIPAddress, port);
tcpServer = new TcpListener(endPoint);
clients = new List<Client>();
threadListen = new Thread(new ThreadStart(Listen));
encoding = new ASCIIEncoding();
}
public static void Start()
{
threadListen.Start();
}
public static byte[] PacketToArray(Packet packet)
{
IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
formatter.Serialize(stream, packet);
byte[] packetArray = stream.GetBuffer();
stream.Close();
return packetArray;
}
public static Packet ArrayToPacket(byte[] array)
{
IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream(array);
Packet packet = new Packet();
packet = (Packet) formatter.Deserialize(stream);
stream.Close();
return packet;
}
public static void Send(Client target, Packet packet)
{
byte[] packetArray = PacketToArray(packet);
target.networkStream.Write(packetArray, 0, packetArray.Length);
target.networkStream.Flush();
OnSend(packet);
}
private static void Listen()
{
tcpServer.Start();
while (true)
{
try
{
Client client = new Client();
client.tcpClient = tcpServer.AcceptTcpClient();
client.networkStream = client.tcpClient.GetStream();
client.thread = new Thread(new ParameterizedThreadStart(HandleCommunication));
clients.Add(client);
client.thread.Start(client);
OnJoin(client);
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
break;
}
}
}
private static void HandleCommunication(object client)
{
Client handleClient = (Client) client;
byte[] messageBuffer = new byte[4096];
int bytesRead = 0;
while (true)
{
bytesRead = 0;
try
{
bytesRead = handleClient.networkStream.Read(messageBuffer, 0, messageBuffer.Length);
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
break;
}
if (bytesRead == 0)
{
clients.Remove(handleClient);
OnLeave(handleClient);
break;
}
Packet packet = ArrayToPacket(messageBuffer);
OnReceive(packet);
}
}
private static void OnStart()
{
Console.WriteLine("Server started on port .");
}
private static void OnJoin(Client client)
{
Console.WriteLine("Client [ID] connected.");
Send(client, PacketGenerator.Generate(OpCodes.opHandshake, null));
}
private static void OnLeave(Client client)
{
Console.WriteLine("Client [ID] disconnected.");
}
private static void OnSend(Packet packet)
{
Console.WriteLine("Server: " + packet.opcode.ToString() + " | " + packet.message);
}
private static void OnReceive(Packet packet)
{
Console.WriteLine("Client [ID]: " + packet.opcode.ToString() + " | " + packet.message);
}
public struct Client
{
public TcpClient tcpClient;
public NetworkStream networkStream;
public Thread thread;
}
}
そして、これがクライアントのコードです:
[Serializable]
public struct Packet
{
public int opcode;
public string message;
}
public static class Client
{
private static IPEndPoint endPoint;
private static TcpClient tcpClient;
private static NetworkStream networkStream;
private static Thread threadCommunication;
private static ASCIIEncoding encoding;
public static void Initialize(string ipAddress, int port)
{
endPoint = new IPEndPoint(IPAddress.Parse(ipAddress), port);
tcpClient = new TcpClient();
networkStream = null;
threadCommunication = new Thread(new ThreadStart(HandleCommunication));
encoding = new ASCIIEncoding();
}
public static void Connect()
{
tcpClient.Connect(endPoint);
threadCommunication.Start();
Console.WriteLine("Connected to server.");
networkStream = tcpClient.GetStream();
}
public static byte[] PacketToArray(Packet packet)
{
IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
formatter.Serialize(stream, packet);
byte[] packetArray = stream.GetBuffer();
stream.Close();
return packetArray;
}
public static Packet ArrayToPacket(byte[] array)
{
IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream(array);
Packet packet = new Packet();
packet = (Packet)formatter.Deserialize(stream);
stream.Close();
return packet;
}
public static void Send(Packet packet)
{
byte[] packetArray = PacketToArray(packet);
networkStream.Write(packetArray, 0, packetArray.Length);
networkStream.Flush();
OnSend(packet);
}
private static void HandleCommunication()
{
byte[] messageBuffer = new byte[4096];
int bytesRead = 0;
while (true)
{
bytesRead = 0;
try
{
bytesRead = networkStream.Read(messageBuffer, 0, messageBuffer.Length);
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
break;
}
if (bytesRead == 0)
{
Console.WriteLine("Connection closed.");
break;
}
Packet packet = ArrayToPacket(messageBuffer);
OnReceive(packet);
}
}
private static void OnSend(Packet packet)
{
Console.WriteLine("Client [ID]: " + packet.opcode.ToString() + " | " + packet.message);
}
private static void OnReceive(Packet packet)
{
Console.WriteLine("Server: " + packet.opcode.ToString() + " | " + packet.message);
switch (packet.opcode)
{
case OpCodes.opHandshake:
Send(PacketGenerator.Generate(OpCodes.opHandshake, null));
break;
}
}
}
しかし、サーバーからクライアントにパケットを送信しているとき(ハンドシェイク)、クライアントは「packet =(Packet)formatter.Deserialize(stream);」の「ArrayToPacket」関数で例外を取得します。正確なメッセージは次のとおりです。アセンブリ"ComDee、Version = 1.0.0.0、Culture = neutral、PublicKeyToken=null"が見つかりませんでした。(ComDeeは、サーバーが実行されるアセンブリです)。
なんで?クライアントのパケット構造は、サーバーの構造と同じです。
アップデート
ServerクラスとClientクラスを編集し、protobuf-netを使用しました。ただし、Client-Classの「OnReceive」は呼び出されません。問題はどこだ?サーバークラス:
[ProtoContract]
public struct Packet
{
[ProtoMember(1)] public int opcode;
[ProtoMember(2)] public string message;
}
public static class Server
{
private static IPEndPoint endPoint;
private static TcpListener tcpServer;
private static List<Client> clients;
private static Thread threadListen;
private static ASCIIEncoding encoding;
public static void Initialize(IPAddress allowedIPAddress, int port)
{
endPoint = new IPEndPoint(allowedIPAddress, port);
tcpServer = new TcpListener(endPoint);
clients = new List<Client>();
threadListen = new Thread(new ThreadStart(Listen));
encoding = new ASCIIEncoding();
}
public static void Start()
{
threadListen.Start();
}
public static byte[] PacketToArray(Packet packet)
{
IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
Serializer.Serialize<Packet>(stream, packet);
byte[] packetArray = stream.GetBuffer();
stream.Close();
return packetArray;
}
public static Packet ArrayToPacket(byte[] array)
{
IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream(array);
Packet packet = new Packet();
packet = Serializer.Deserialize<Packet>(stream);
stream.Close();
return packet;
}
public static void Send(Client target, Packet packet)
{
byte[] packetArray = PacketToArray(packet);
target.networkStream.Write(packetArray, 0, packetArray.Length);
target.networkStream.Flush();
OnSend(packet);
}
private static void Listen()
{
tcpServer.Start();
OnStart();
while (true)
{
try
{
Client client = new Client();
client.tcpClient = tcpServer.AcceptTcpClient();
client.networkStream = client.tcpClient.GetStream();
client.thread = new Thread(new ParameterizedThreadStart(HandleCommunication));
clients.Add(client);
client.thread.Start(client);
OnJoin(client);
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
break;
}
}
}
private static void HandleCommunication(object client)
{
Client handleClient = (Client) client;
byte[] messageBuffer = new byte[4096];
int bytesRead = 0;
while (true)
{
bytesRead = 0;
try
{
bytesRead = handleClient.networkStream.Read(messageBuffer, 0, messageBuffer.Length);
}
catch
{
clients.Remove(handleClient);
OnLeave(handleClient);
break;
}
if (bytesRead == 0)
{
Packet packet = ArrayToPacket(messageBuffer);
OnReceive(packet);
}
}
}
private static void OnStart()
{
Console.WriteLine("Server started.");
}
private static void OnJoin(Client client)
{
Console.WriteLine("Client [ID] connected.");
Send(client, PacketGenerator.Generate(OpCodes.opHandshake, null));
}
private static void OnLeave(Client client)
{
Console.WriteLine("Client [ID] disconnected.");
}
private static void OnSend(Packet packet)
{
Console.WriteLine("Server: " + packet.opcode.ToString() + " | " + packet.message);
}
private static void OnReceive(Packet packet)
{
Console.WriteLine("Client [ID]: " + packet.opcode.ToString() + " | " + packet.message);
}
public struct Client
{
public TcpClient tcpClient;
public NetworkStream networkStream;
public Thread thread;
}
}
そして、これがクライアントクラスです。
[ProtoContract]
public struct Packet
{
[ProtoMember(1)]
public int opcode;
[ProtoMember(2)]
public string message;
}
public static class Client
{
private static IPEndPoint endPoint;
private static TcpClient tcpClient;
private static NetworkStream networkStream;
private static Thread threadCommunication;
private static ASCIIEncoding encoding;
public static void Initialize(string ipAddress, int port)
{
endPoint = new IPEndPoint(IPAddress.Parse(ipAddress), port);
tcpClient = new TcpClient();
networkStream = null;
threadCommunication = new Thread(new ThreadStart(HandleCommunication));
encoding = new ASCIIEncoding();
}
public static void Connect()
{
tcpClient.Connect(endPoint);
threadCommunication.Start();
Console.WriteLine("Connected to server.");
networkStream = tcpClient.GetStream();
}
public static byte[] PacketToArray(Packet packet)
{
IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
Serializer.Serialize<Packet>(stream, packet);
byte[] packetArray = stream.GetBuffer();
stream.Close();
return packetArray;
}
public static Packet ArrayToPacket(byte[] array)
{
IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream(array);
Packet packet = new Packet();
packet = Serializer.Deserialize<Packet>(stream);
stream.Close();
return packet;
}
public static void Send(Packet packet)
{
byte[] packetArray = PacketToArray(packet);
networkStream.Write(packetArray, 0, packetArray.Length);
networkStream.Flush();
OnSend(packet);
}
private static void HandleCommunication()
{
byte[] messageBuffer = new byte[4096];
int bytesRead = 0;
while (true)
{
bytesRead = 0;
try
{
bytesRead = networkStream.Read(messageBuffer, 0, messageBuffer.Length);
}
catch
{
Console.WriteLine("Connection closed.");
break;
}
if (bytesRead == 0)
{
Packet packet = ArrayToPacket(messageBuffer);
OnReceive(packet);
}
}
}
private static void OnSend(Packet packet)
{
Console.WriteLine("Client [ID]: " + packet.opcode.ToString() + " | " + packet.message);
}
private static void OnReceive(Packet packet)
{
Console.WriteLine("Server: " + packet.opcode.ToString() + " | " + packet.message);
switch (packet.opcode)
{
case OpCodes.opHandshake:
Send(PacketGenerator.Generate(OpCodes.opHandshake, null));
break;
}
}
}