私はTCPサーバーを実装するための小さなアプリケーションを書いていましたが、C#.NETの初心者としてチュートリアルに従ったばかりです。その認可部分はうまくいきますが、チュートリアルを厳密に続行するために、認可が行われた後、tcpClient.Close()との接続が切断されます。.NET TCPサーバー接続の切断
もっと多くのパケットを待ち受けるためにこのコードを調整する必要がありますか?ほとんどのサーバーはX分後に接続を切断すると思うが、私はこのタイプのものにはまだ慣れていない。
// Starts the TCP RCON Server
public void StartServer()
{
Console.WriteLine("RCON Server starting on Port: {0}", serverPort);
this.tcpListener = new TcpListener(IPAddress.Any, serverPort);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
Console.WriteLine("RCON Server has been Started.");
}
// Listen for Client Connections
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
// blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
// Create a thread for client communication
Thread clientThread = new Thread(new ParameterizedThreadStart(ReadClientPacket));
clientThread.Start(client);
}
}
private void ReadClientPacket(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
bool terminate = false;
while (!terminate)
{
try
{
int packetsize;
// Create a new Packet Object and fill out the data from the incoming TCP Packets
RCONPacket packet = new RCONPacket();
using (BinaryReader reader = new BinaryReader(clientStream))
{
// First Int32 is Packet Size
packetsize = reader.ReadInt32();
packet.RequestId = reader.ReadInt32();
packet.RconDataReceived = (RCONPacket.RCONDATA_rec)reader.ReadInt32();
Console.WriteLine("Packet Size: {0} RequestID: {1} ServerData: {2}", packetsize, packet.RequestId, packet.RconDataReceived);
// Read first and second String in the Packet (UTF8 Null Terminated)
packet.String1 = ReadBytesString(reader);
packet.String2 = ReadBytesString(reader);
Console.WriteLine("String1: {0} String2: {1}", packet.String1, packet.String2);
switch (packet.RconDataReceived)
{
case RCONPacket.RCONDATA_rec.SERVERDATA_AUTH:
{
if (packet.String1 == "testpass")
{
Console.WriteLine("Password is Valid");
ReplyAuthRequest(packet.RequestId, tcpClient, packet.String1); // Junk Packet
ReplyAuthRequest(packet.RequestId, tcpClient, packet.String1);
}
else
{
Console.WriteLine("Password is Invalid");
ReplyAuthRequest(BAD_PASSWORD, tcpClient, packet.String1); // Junk Packet
ReplyAuthRequest(BAD_PASSWORD, tcpClient, packet.String1);
terminate = true;
}
break;
}
case RCONPacket.RCONDATA_rec.SERVERDATA_EXECCOMMAND:
{
Console.WriteLine("RCON Command Packet Received");
ReplyExecCommand(packet.RequestId, tcpClient);
break;
}
default:
{
break;
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
terminate = true;
}
}
tcpClient.Close();
}
それは理にかなっていますが、基本的に私が休憩でやっていることではありません。ただそれをもっと読みやすくすることを除けば?私はあなたが私がやっていることのより良い考えを得るかもしれないようにコードを更新しました。私はこのプロトコルhttp://developer.valvesoftware.com/wiki/Source_RCON_Protocolをサーバとして実装しようとしています。私が問題に直面しているのは、たとえその休憩を取り除いても、最初のパケットの後にReadClientPacket()を停止していましたが、今度は「ストリームが読み込めませんでした」というエラーメッセージが表示されました。 –
btw、私はあなたの答えをすぐにマークします。ちょっと開いたままにして、私が先に進みこの問題を解決できるかどうかを見たいと思っていました。良い答えをありがとう! –
私はちょうどそれを考え出したと思う。私はちょうどwhileループとtcpClient.Close()を削除する必要がありますか?それは次のパケットが受信されたときに関数全体が再び呼び出されるようにするでしょうか? –