在另一个线程中管理标准输入/输出?
基本概要是...
1) 我的应用程序启动一个 Java 进程并管理它。
2) 我在另一个线程中有一个 TCP 服务器,用户可以连接到该服务器并发出 Java 进程可以理解的命令。
3) 传递命令不是问题是streamWriter.WriteLine(cmd);但事实证明,得到回应是很困难的。
通过 RedirectStandardError 进入的下一行(由于某种原因它使用它而不是 Output)应该是回复,但我无法弄清楚如何在我的 TCP 服务器线程中访问它。
这就是我的 TCP 服务器功能,需要获取回复并将其打印出来。我该怎么做呢?
static void AcceptClient(IAsyncResult ar)
{
TcpListener rconListener = ar.AsyncState as TcpListener;
TcpClient rconClient = rconListener.EndAcceptTcpClient(ar);
Console.WriteLine("New client: " + rconClient.Client.RemoteEndPoint.ToString());
NetworkStream ns = rconClient.GetStream();
// Loop while client is Connected
while (rconClient.Connected)
{
byte[] buff = new byte[4096];
List<byte> msg = new List<byte>();
int total = 0;
while (true)
{
int read = ns.Read(buff, 0, buff.Length);
if (read <= 0)
break;
msg.AddRange(buff);
total += read;
if (read < buff.Length)
break;
}
if (msg.Count <= 0)
{
Console.WriteLine("Lost connection: " + rconClient.Client.RemoteEndPoint.ToString());
rconClient.Close();
break;
}
int len = BitConverter.ToInt32(msg.ToArray(), 0);
int seq = BitConverter.ToInt32(msg.ToArray(), 4);
PacketType packetType = (PacketType)BitConverter.ToInt32(msg.ToArray(), 8);
List<byte> response = new List<byte>();
// RCON Execute Command
if (packetType == PacketType.ServerData_ExecCommand_AuthResponse)
{
string srvcmd = ReadString(msg.ToArray(), 12);
Console.WriteLine("RCON: " + srvcmd);
response.AddRange(BitConverter.GetBytes((int)seq));
response.AddRange(BitConverter.GetBytes((int)PacketType.ServerData_ResponseValue));
string[] cmdargs = srvcmd.Split(new char[] { ' ' });
if (cmdargs[0] == "rcon_password")
{
ServerSettings.RCONPassword = cmdargs[1];
response.AddRange(Encoding.ASCII.GetBytes("RCON Password succesfully changed to " + cmdargs[1]));
}
else if (cmdargs[0] == "date")
{
response.AddRange(Encoding.ASCII.GetBytes(DateTime.Now.ToString()));
}
else
{
Program.SendRCONCmd(cmdargs[0]);
}
response.AddRange(new byte[] { 0x20, 0x0a }); //LF
response.Add(0x0);
response.Add(0x0);
response.InsertRange(0, BitConverter.GetBytes((response.Count)));
ns.Write(response.ToArray(), 0, response.Count);
}
}
}
The basic rundown is...
1) My application starts a Java process and manages it.
2) I have a TCP Server in another thread that users can connect to and issue commands that the Java process understands.
3) Passing the commands is not a problem is streamWriter.WriteLine(cmd); but getting the response is proving to be difficult.
The next line that comes in through RedirectStandardError (it uses this instead of Output for some reason) should be the reply, but I am having trouble figuring out how to access that in my TCP Server's thread.
This is what my TCP Server's function looks like that needs to get the reply and print it out. How can I go about doing this?
static void AcceptClient(IAsyncResult ar)
{
TcpListener rconListener = ar.AsyncState as TcpListener;
TcpClient rconClient = rconListener.EndAcceptTcpClient(ar);
Console.WriteLine("New client: " + rconClient.Client.RemoteEndPoint.ToString());
NetworkStream ns = rconClient.GetStream();
// Loop while client is Connected
while (rconClient.Connected)
{
byte[] buff = new byte[4096];
List<byte> msg = new List<byte>();
int total = 0;
while (true)
{
int read = ns.Read(buff, 0, buff.Length);
if (read <= 0)
break;
msg.AddRange(buff);
total += read;
if (read < buff.Length)
break;
}
if (msg.Count <= 0)
{
Console.WriteLine("Lost connection: " + rconClient.Client.RemoteEndPoint.ToString());
rconClient.Close();
break;
}
int len = BitConverter.ToInt32(msg.ToArray(), 0);
int seq = BitConverter.ToInt32(msg.ToArray(), 4);
PacketType packetType = (PacketType)BitConverter.ToInt32(msg.ToArray(), 8);
List<byte> response = new List<byte>();
// RCON Execute Command
if (packetType == PacketType.ServerData_ExecCommand_AuthResponse)
{
string srvcmd = ReadString(msg.ToArray(), 12);
Console.WriteLine("RCON: " + srvcmd);
response.AddRange(BitConverter.GetBytes((int)seq));
response.AddRange(BitConverter.GetBytes((int)PacketType.ServerData_ResponseValue));
string[] cmdargs = srvcmd.Split(new char[] { ' ' });
if (cmdargs[0] == "rcon_password")
{
ServerSettings.RCONPassword = cmdargs[1];
response.AddRange(Encoding.ASCII.GetBytes("RCON Password succesfully changed to " + cmdargs[1]));
}
else if (cmdargs[0] == "date")
{
response.AddRange(Encoding.ASCII.GetBytes(DateTime.Now.ToString()));
}
else
{
Program.SendRCONCmd(cmdargs[0]);
}
response.AddRange(new byte[] { 0x20, 0x0a }); //LF
response.Add(0x0);
response.Add(0x0);
response.InsertRange(0, BitConverter.GetBytes((response.Count)));
ns.Write(response.ToArray(), 0, response.Count);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你检查过SDK文档吗?
Process.StandardError 属性
获取用于读取应用程序错误输出的流。
have you checked the SDK documentation?
Process.StandardError Property
Gets a stream used to read the error output of the application.