ちょっと、カスタムバイナリプロトコルを使用してパケットを分離する問題があります。 現在、サーバー側のコードは次のようになっています。バイナリプロトコルによるTCPフレーミング
public void HandleConnection(object state)
{
TcpClient client = threadListener.AcceptTcpClient();
NetworkStream stream = client.GetStream();
byte[] data = new byte[4096];
while (true)
{
int recvCount = stream.Read(data, 0, data.Length);
if (recvCount == 0) break;
LogManager.Debug(Utility.ToHexDump(data, 0, recvCount));
//processPacket(new MemoryStream(data, 0, recvCount));
}
LogManager.Debug("Client disconnected");
client.Close();
Dispose();
}
私はパケットのヘキサ・ダンプを見てきましたが、パケット全体がワンショットで表示されることがあります。すべて20バイトとしましょう。それがフラグメント化されている場合、このデータをprocessPacket()メソッドに正しく渡すために、このデータをバッファリングする必要があります。私は(ushort)contentLengthのようなものをヘッダーに追加するだけで、1バイトのopcodeヘッダーのみを使用しようとしていますか?私は可能な限り軽量プロトコルを作ろうとしており、このシステムは非常に大きなパケット(< 128バイト)を送信しません。
私がテストしているクライアントサイドコードは次のとおりです。それはそれをめちゃくちゃに何もすることができれば
public void auth(string user, string password)
{
using (TcpClient client = new TcpClient())
{
client.Connect(IPAddress.Parse("127.0.0.1"), 9032);
NetworkStream networkStream = client.GetStream();
using (BinaryWriter writer = new BinaryWriter(networkStream))
{
writer.Write((byte)0); //opcode
writer.Write(user.ToUpper());
writer.Write(password.ToUpper());
writer.Write(SanitizationMgr.Verify()); //App hash
writer.Write(Program.Seed);
}
}
}
は私はわからない、とバイナリプロトコルは、C#が関与している、特にWeb上で多くの情報を、持っていないようです。コメントは参考になります。 =)
解決済みこれが正しいかどうかはわかりませんが、ハンドラに必要なものだけを与えるようです。
public void HandleConnection(object state)
{
TcpClient client = threadListener.AcceptTcpClient();
NetworkStream stream = client.GetStream();
byte[] data = new byte[1024];
uint contentLength = 0;
var packet = new MemoryStream();
while (true)
{
int recvCount = stream.Read(data, 0, data.Length);
if (recvCount == 0) break;
if (contentLength == 0 && recvCount < headerSize)
{
LogManager.Error("Got incomplete header!");
Dispose();
}
if(contentLength == 0) //Get the payload length
contentLength = BitConverter.ToUInt16(data, 1);
packet.Write(data, (int) packet.Position, recvCount); //Buffer the data we got into our MemStream
if (packet.Length < contentLength + headerSize) //if it's not enough, continue trying to read
continue;
//We have a full packet, pass it on
//LogManager.Debug(Utility.ToHexDump(packet));
processPacket(packet);
//reset for next packet
contentLength = 0;
packet = new MemoryStream();
}
LogManager.Debug("Client disconnected");
client.Close();
Dispose();
}
うーん、 contentLengthをヘッダーに追加します。ありがとうございます。私はprocessPacket()でバイナリリーダーを使用していますが、明らかに、部分的なパケットしか渡されていないときには恐ろしいことに失敗しています。 – Endian
@Endian:パケットの代わりにネットワークストリームを渡すのはなぜですか? –
@Jon:私のbinaryReaderがバッファアンダーランを取得せずに読むことができるチャンクという意味で、パケットをもっとたくさん。私は元の投稿を編集しました。あなたの提案とそれがうまくいっているように見えるので、助けてくれてありがとうございます。 :) – Endian