Moin,
Ich habe ein Problem was ich nicht so ganz verstehe
Es sieht folgendermaßen aus:
Server -> startet
Server -> startet ein Minecraft Server und fängt den output ab
Server -> sendet den abgefangenen output zu allen verbundenen Clients
Client -> Verbindet sich zum Server
Server -> Meldet Client Connected
Client -> Soll solange daten gesendet werden diese auslesen und anzeigen so das ich eine Kopie der Server Konsole habe. Klappt aber nicht ganz entweder kann ich nur 1x auslesen oder garnicht.
Server:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Diagnostics;
namespace MinecraftServerManager.TCPIP
{
/*************************************************
*************************************************
***************Coded by 3r0rXx********************
*************************************************
*************************************************
*/
public class Server : IServer
{
public IPAddress Ip { get; private set; }
public int Port { get; private set; }
public int Xmx { get; private set; }
public int Xms { get; private set; }
public string ServerPath { get; set; }
public string MCOutput { get; private set; }
public List<Client> Connection = new List<Client>();
private TcpListener tcpServer;
public NetworkStream tcpStream;
public void Init(string _ip, int _port, int _Xmx = 2048, int _Xms = 512, string _serverPath = "craftbukkit-1.5.2-R1.0.jar")
{
if (_ip == "")
{
Ip = IPAddress.Any;
}
else
{
Ip = IPAddress.Parse(_ip);
}
Port = _port;
tcpServer = new TcpListener(Ip, Port);
Xmx = _Xmx;
Xms = _Xms;
ServerPath = _serverPath;
#region startMc
Process Server = new Process();
ProcessStartInfo ServerStartInfo = new ProcessStartInfo(@"C:\Program Files\Java\jre1.8.0_20\bin\java.exe");
ServerStartInfo.Arguments = "-Xmx" + Xmx + "M -Xms" + Xms + "M -jar " + ServerPath;
ServerStartInfo.CreateNoWindow = true;
ServerStartInfo.RedirectStandardOutput = true;
ServerStartInfo.RedirectStandardInput = true;
ServerStartInfo.RedirectStandardError = true;
ServerStartInfo.UseShellExecute = false;
Server.StartInfo = ServerStartInfo;
Server.ErrorDataReceived += Server_Error;
Server.OutputDataReceived += Server_Output;
Server.Start();
Server.BeginErrorReadLine();
Server.BeginOutputReadLine();
//Server.WaitForExit();
#endregion
}
private void Server_Error(object sender, DataReceivedEventArgs e)
{
if (e.Data == ">")
{
}
else
{
MCOutput = e.Data;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(e.Data);
}
}
private void Server_Output(object sender, DataReceivedEventArgs e)
{
if (e.Data == ">")
{
}
else
{
MCOutput = e.Data;
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine(e.Data);
}
}
public void Run()
{
tcpServer.Start();
new Thread(new ThreadStart(Receive)).Start();
}
public void Receive()
{
Console.WriteLine("Server started...");
while (true)
{
TcpClient tmp = tcpServer.AcceptTcpClient();
tcpStream = tmp.GetStream();
Client connection = new Client();
connection.nStream = tcpStream;
connection.sReader = new StreamReader(tcpStream);
connection.sWriter = new StreamWriter(tcpStream);
Connection.Add(connection);
Console.WriteLine("Client has connected!");
Send();
}
}
public void Send()
{
foreach (var connections in Connection)
{
try
{
connections.sWriter.Write(MCOutput);
connections.sWriter.Flush();
}
catch
{
Connection.Remove(connections);
}
}
}
}
}
Client:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using ServerData;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Diagnostics;
namespace Client
{
class Program
{
const int PORT_NO = 8000;
const string SERVER_IP = "127.0.0.1";
static void Main(string[] args)
{
TcpClient client = new TcpClient(SERVER_IP, PORT_NO);
NetworkStream nwStream = client.GetStream();
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
while (client.Connected)
{
bytes = nwStream.Read(buffer, 0, buffer.Length);
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
Console.WriteLine(messageData.ToString());
}
}
}
}
Hier ist das Problem was ich nicht verstehe
A: Lese ich den Stream mit diesen Code aus erhalte ich nur 1x mal die ausgabe.
Lese ich ihn aber mit einen StreamReader aus erhalte ich garnichts
B: Warum hält die schleife sozusagen bevor sie das 2x Console.WriteLine erreicht und überspringt dies?
C: Wie kann ich den Stream denn jetzt dauerhaft auslesen?
Du rufst nur an einer Stelle im Server Send auf.
Du solltest einen eigenen Thread machen, der empfangene Daten an alle verbundenden Clients schickt.
Am einfachsten hast Du die Clients dazu in einer ConcurrentBag<T>. Wenn dann der Server von Minecraft liest, rufst Du dort Send auf.
Entweder bin ich zu doof dafür oder es bringt nichts denn ich erhalte immernoch keine Informationen am Client....
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Danke Euch habs problem soweit gelöst nur hab ein weiteres Problem
undzwar ich verbinde mich empfange die Daten und schliessen dann den Client
alles kein Problem
dann versuche ich mich nochmal mit dem Client zu verbinden und der Server schmiert ab mit
Fehlermeldung:
"An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dllAdditional information: Collection was modified; enumeration operation may not execute."
In folgender Zeile:
[COLOR]foreach (var connections in Connection)
[/color]
{
try
{
connections.sWriter.WriteLine(MCOutput);
connections.sWriter.Flush();
}
catch
{
Connection.Remove(connections);
Console.WriteLine("Client remove");
}
}
Der Rot makierte Satz löst den fehler aus
Im Server kommt erst die Meldung das der neue Client sich verbunden hat
und danach das der alte Client gelöscht wurde
Wie kann ich jetzt verhindern das der Server desswegen abschmiert?
Remove innerhalb foreach ist nict erlaubt.
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Ohh okay und wie entferne ich dann die Clients die nicht mehr verbunden sind?
Das sind absolute Grundlagen -> Liste duplizieren.
Beachte [Hinweis] Wie poste ich richtig? 1.1.1
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code