Benutzer mit den meisten Antworten
Tcp Server mit multiplen Clienten

Frage
-
Hi,
ich habe mir hier einen Tcp Server zusammen gebastelt.. bin noch relativ unerfahren in dem Gebiet und wollte fragen, ob (oder besser wie..) es möglich ist, das der Server auch mehrere Clients haben kann. Oder im besten Fall beliebig viele. Über ein Codebeispiel oder sogar eine Verbesserung würde ich mich sehr freuen.
Im Moment empfängt der Server die CPU-Last von einem Client, was dann in dem Label lblReceivedData ausgegeben wird.namespace Server
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
this.Size = Properties.Settings.Default.Size;
this.Location = Properties.Settings.Default.Location;
this.WindowState = Properties.Settings.Default.WindowState;
}
private void btnStartServer_Click(object sender, EventArgs e)
{
try
{
Thread obj_thread = new Thread(StartServer);
obj_thread.Start();
MessageBox.Show("Server erfolgreich gestartet", "Erfolgreich", MessageBoxButtons.OK, MessageBoxIcon.Information);
btnStartServer.Text = "running...";
btnStartServer.Enabled = false;
}
catch (Exception x)
{
MessageBox.Show(x.Message, "Error", MessageBoxButtons.OK);
}
}
TcpListener obj_server = new TcpListener(IPAddress.Any, 6868);
public void StartServer()
{
obj_server.Start();
while (true)
{
TcpClient tc = obj_server.AcceptTcpClient();
NetworkStream ns = tc.GetStream();
if (ns.ReadByte() == 2)
{
byte[] receive_data = ReadStream(ns);
lblReceivedData.Invoke((MethodInvoker)(() => lblReceivedData.Text = Encoding.UTF8.GetString(receive_data)));
}
}
}
public byte[] ReadStream(NetworkStream ns)
{
byte[] data_buff = null;
int b = 0;
String buff_length = "";
while ((b = ns.ReadByte()) != 4)
{
buff_length += (char)b;
}
int data_length = Convert.ToInt32(buff_length);
data_buff = new byte[data_length];
int byte_read = 0;
int byte_offset = 0;
while (byte_offset < data_length)
{
byte_read = ns.Read(data_buff, byte_offset, data_length + byte_offset);
byte_offset += byte_read;
}
return data_buff;
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
Properties.Settings.Default.WindowState = this.WindowState;
Properties.Settings.Default.Size = this.Size;
Properties.Settings.Default.Location = this.Location;
Properties.Settings.Default.Save();
}
}
}
Antworten
-
Hi,
Dein Code arbeitet synchron bezüglich Einlesen der Daten. Nach dem AcceptTcpClient wird der nächste Client erst verarbeitet, wenn in der Schleife alle Bytes mit ReadStream eingelesen wurden. Erst danach wird der nächste Client verarbeitet.Wenn Du das Lesen der Daten asynchron ausführst, dann kann in der Schleife sofort mit dem nächsten AcceptTcpClient fortgesetzt werden. Die asynchrone Ausführung ist in einer neuen Thread-Instanz (für jede Anfrage eines Clients) zu organisieren. Wichtig dabei ist, wie das Ende des Lesens der Bytes "signalisiert" wird. Das kann beispielsweise eine Ereignismethode sein, wenn das Lesen in einer separaten Instanz gekapselt und diese Methode das Ereignis von dieser Instanz abonniert.
--
Viele Grüsse
Peter Fleischer (ehem. MVP für Developer Technologies)
Meine Homepage mit Tipps und Tricks- Als Antwort vorgeschlagen Ivan DragovMicrosoft contingent staff, Moderator Freitag, 18. Januar 2019 06:34
- Als Antwort markiert Ivan DragovMicrosoft contingent staff, Moderator Montag, 28. Januar 2019 08:13
-
Hi,
es ist bestimmt übersichtlicher, das Lesen in einer separaten Klasse zu kapseln und damit auch Ereignisse zu nutzen (z.B. nachdem alle Bytes gelesen wurden).Alles in einer Klasse zu halten, ist möglich. Anstelle einer Ereignissteuerung sind dabei Methodenaufrufe zum Ende des Lesens der Bytes möglich. Mir wäre das aber zu unübersichtlich.
--
Viele Grüsse
Peter Fleischer (ehem. MVP für Developer Technologies)
Meine Homepage mit Tipps und Tricks- Als Antwort vorgeschlagen Ivan DragovMicrosoft contingent staff, Moderator Freitag, 18. Januar 2019 06:34
- Als Antwort markiert Ivan DragovMicrosoft contingent staff, Moderator Montag, 28. Januar 2019 08:13
Alle Antworten
-
Hi,
Dein Code arbeitet synchron bezüglich Einlesen der Daten. Nach dem AcceptTcpClient wird der nächste Client erst verarbeitet, wenn in der Schleife alle Bytes mit ReadStream eingelesen wurden. Erst danach wird der nächste Client verarbeitet.Wenn Du das Lesen der Daten asynchron ausführst, dann kann in der Schleife sofort mit dem nächsten AcceptTcpClient fortgesetzt werden. Die asynchrone Ausführung ist in einer neuen Thread-Instanz (für jede Anfrage eines Clients) zu organisieren. Wichtig dabei ist, wie das Ende des Lesens der Bytes "signalisiert" wird. Das kann beispielsweise eine Ereignismethode sein, wenn das Lesen in einer separaten Instanz gekapselt und diese Methode das Ereignis von dieser Instanz abonniert.
--
Viele Grüsse
Peter Fleischer (ehem. MVP für Developer Technologies)
Meine Homepage mit Tipps und Tricks- Als Antwort vorgeschlagen Ivan DragovMicrosoft contingent staff, Moderator Freitag, 18. Januar 2019 06:34
- Als Antwort markiert Ivan DragovMicrosoft contingent staff, Moderator Montag, 28. Januar 2019 08:13
-
Hallo Peter,
vielen Dank für die Antwort! Das ist alles sehr einleuchtend, bis auf den letzten Satz. Meinst du damit, das ich das Lesen in eine eigene Klasse schreiben soll welche dann bei Ereignis "x" ausgelöst wird?
Danke nochmal und liebe Grüße
-
Hi,
es ist bestimmt übersichtlicher, das Lesen in einer separaten Klasse zu kapseln und damit auch Ereignisse zu nutzen (z.B. nachdem alle Bytes gelesen wurden).Alles in einer Klasse zu halten, ist möglich. Anstelle einer Ereignissteuerung sind dabei Methodenaufrufe zum Ende des Lesens der Bytes möglich. Mir wäre das aber zu unübersichtlich.
--
Viele Grüsse
Peter Fleischer (ehem. MVP für Developer Technologies)
Meine Homepage mit Tipps und Tricks- Als Antwort vorgeschlagen Ivan DragovMicrosoft contingent staff, Moderator Freitag, 18. Januar 2019 06:34
- Als Antwort markiert Ivan DragovMicrosoft contingent staff, Moderator Montag, 28. Januar 2019 08:13