Hi!
Nein, das ist nicht möglich, da dies der Idee des Webservice widerspricht.
Warum möchtest du ein Event an den Client schicken? Ich denke, du hast da einen Designfehler 😉
Lg
Hi!
Du hast Probleme beim Schreiben des Unit-Tests, da du im Interface INodeService zwei verschiende Zuständigkeiten vereinst:
1.Instanzierung von INode-Objekten
1.Herstellen einer Eltern-Kind-Beziehung
Es wäre sinnvoll, die erste Zuständigkeit zu separieren und in eine Factory auszulagern (z.B. INodeFactory). Damit kannst du die Instanzierung kontrollieren/ausmocken und den Unit-Test so schreiben, wie du möchtest.
public interface INodeFactory()
{
INode CreateNode();
}
public interface INodeService()
{
INode AppendNewChild(INode parent);
}
public class NodeService : INodeService
{
private readonly INodeFactory _factory;
public NodeService(INodeFactory factory)
{
_factory = factory;
}
public void AddNewChild(INode parent)
{
var child = _factory.CreateNode();
parent.Children.Add(child);
return child;
}
}
Hier noch ein paar Anmerkungen:*Obwohl Rhino.Mocks tolle Möglichkeiten bietet, sollte man darauf achten, dass man es nicht zu oft verwendet. Es passiert leicht, dass die Verwendung von Rhino.Mocks entartet und anstatt dass man einen echten Mock implementiert, erreicht man dies durch die Expectations. Dies hat zur Folge, dass man nur sehr schwer die Testfälle separat betrachten kann, denn fast immer braucht man alle Expectations in jedem Test (klares Anzeichen für die Implementierung eines einfachen Mocks) bzw. es entsteht ein Test, der alles testet.
*Wenn man DDD (Domain Driven Design) betreibt, so würde es nahe liegen, die Aufgabe, ein Kind einem Elternteil zuzweisen, in das INode-Interface aufzunehmen. Ein klares Anzeichen hierfür ist die direkte Modifikation der Children-Collection.
Es sollte vermieden werden, die Objekte in zwei große Gruppen zu gliedern (Daten-Objekte wie INode, die nichts anderes tun, als Zustand darzustellen und Service-Objekte, die jegliche Business-Logik, dafür aber keinen Zustand enthalten). In diesem Fall ist klar, dass die Aufgabe, ein Kind aufzunehmen, klar beim Elternteil liegt. Für Fälle, wo die Zuständigkeit nicht klar sein sollte, können sogenannte Domain-Services eingesetzt werden. Diese bilden aber Grenzfälle und sollten nicht der Standard sein.
*Die Methode CreateChildNodeFor verstößt gegen das Prinzip der Command-Query-Separation bzw. des Single-Responsibility-Prinzips. Die Methode fügt ein neues Child hinzu (Command) UND gibt das neue Child zurück (Query). Die Tatsache, dass die Methode zwei Aufgaben erfüllt, bestätigt, dass gegen das Single-Responsibility-Prinzip verstoßen wird.
Meine Ideal-Lösung (Implementierungen überlasse ich mal dir).
public interface INode
{
// Es ist fraglich, ob INode seine Kinder öffentlich überhaupt zeigen muss.
// Extreme Verfolger von DDD streben an, keinen Zustand öffentlich preiszugeben.
IEnumerable<INode> Children { get; }
void AppendChild(INode child);
// Sollte umbedingt das neu erzeugte Kind benötigt werden, könnte man statt der
// Children-Enumeration folgende Methode implementieren.
INode GetNewestChild();
}
public interface INodeFactory
{
INode CreateNode();
}
// Die Aufgabe, ein neues Kind einem Elternteil hinzuzufügen, kann durchaus ein einem
// Domain-Service passieren. Es ist nicht Aufgabe von INode, ein Kind zu erzeugen, noch
// ist es die Aufgabe der INodeFactory, einer INode ein Kind hinzuzufügen.
public interface INodeService
{
// Wie die Methode an die INodeFactory herankommt, kann über mehrere Wege erfolgen:
// 1. Dependency-Injection über den Konstruktor (näheres siehe Inversion of Control-Container)
// 2. Als zusätzliches Argument der Methode.
void AppendNewChildToParent(INode parent);
}
Lg Oliver Hanappi
Ich erhalte einen Intpointer, der nun selbst laut Marshal.SizeOf(hordePointer) wieder aus 4 Intpointern besteht.
Wie kommst du darauf, dass der Pointer aus 4 anderen Pointern besteht? Welchen Wert gibt die Funktion zurück?
Meiner Meinung nach zeigt der Pointer auf den ersten der 16 Float-Werte.
Hallo!
Lass die Methode einen Nullable zurückliefern, also Point? anstatt Point 😉
Lg
Hi du!
Danke für den Tipp 😉 Also ich hatte zwar gehofft, dass ich eine Lösung finde, ohne dass ich den Kernteil der Serialisierung selber implementieren muss, aber macht nichts ^^
Da hab ich auch gleich eine Frage: Kennt ihr ein gutes Tutorial zu XML in .NET? Bin nämlich gerade draufgekommen, dass ich nicht so 100% zurecht komme mit dem XmlReader, er wirft mir andauern Exceptions und außerdem hab ich mich noch nicht wirklich mit XML in .NET auseinandergesetzt und das ist meiner Meinung nach eine gute Gelegenheit!
Lg oli
Hallo!
Ich möchte eine hierarchische Objektstruktur (composite pattern) mit dem XmlSerializer speichern, allerdings wirft dieser bereits bei seiner Instanzierung eine StackOverflowException.
Das Problem konnte ich mittlerweile darauf zurückführen, dass meine Klasse von ICollection<> erbt. Hier mein Code:
public class MyClass : ICollection<MyClass>
{
// Quellcode
}
Habt ihr Ideen, wie ich das Problem lösen kann? Würde der Typenparameter von ICollection nicht MyClass sein, so würde es funktionieren.
Lg oli
Hi!
Ich weiß zwar nicht genau, wofür du das brauchst, aber du kannst z.B. alle Typen der aktuellen Assembly laden (wenn dein Projekt nur aus einer Assembly besteht), um die hardgecodeten If-Abfragen zu vermeiden.
public static PropertyInfo[] GetForeignProperties(object obj)
{
List<PropertyInfo> properties = new List<PropertyInfo>();
Assembly currentAssembly = Assembly.GetExecutingAssembly();
Type[] ownTypes = currentAssembly.GetTypes();
foreach (PropertyInfo pi in obj.GetType().GetProperties())
{
if (!ownTypes.Contains(pi.PropertyType))
properties.Add(pi);
}
return properties.ToArray();
}
Lg oli
Hi!
... versuch mal portnummern über 20000 zu nehmen...
Ich möchte hier nur mal kurz einwerfen, dass man laut IANA Portnummern ab 49152 nehmen darf, da diese als dynamisch bzw. privat deklariert sind.
Unter anderem in diesem Artikel auf Wikipedia nachzulesen.
Lg oli
Hi!
Ich verwende die Postbuildereignisse in meinen Microsoft Visual C# 2008 Express Editions-Projekten, um sowohl die erzeugte Assembly als auch ihre zugehörige XML-Dokumentationsdatei in ein anderes Verzeichnis zu kopieren. Allerdings werden die Befehle zu früh ausgeführt, da zu diesem Zeitpunkt die XML-Dokumentationsdatei noch nicht erzeugt worden ist.
Wie kann ich das Problem lösen?
Lg oli
Hi!
Danke schon mal für die Links! Werde sie mir mal ansehen 🙂
@zero_x: Naja, ich hätte geplant, Visual C++ Express zu verwenden 😉
Mfg oli
Hallo!
Ich programmiere schon seit einiger Zeit C# und kenne mich auch wunderbar damit aus, allerdings möchte ich mir nun auch C++ beibringen, denn hin und wieder brauche ich native Anwendungen.
Früher habe ich mit Delphi programmiert und kenne mich auch recht gut mit der Win32 API aus, nur leider weiß ich nicht so genau, wo ich anfangen soll.
Habt ihr für mich Links zu guten Einstiegstutorials oder sonst gute Ratschläge? Ich möchte noch dazu sagen, dass ich auf den Kauf von Büchern gerne verzichten würde. Habe Visual C++ 2008 Express Edition, also macht es auch nichts, wenn sich die Einführungen auf diese IDE beziehen.
mfg oli
Hab jetzt den ErrorProvider genommen. Danke vielmals 😉
Danke sehr, hat super funktioniert! Und von der schnellen Antwort bin ich wirklich begeistert 🙂
Das mit der TextBox.Text-Eigenschaft ändern war nur ein Test 😉
Da hätte ich noch eine kleine Frage am Rande: wenn die Property des Objekts gesetzt wird, kann es passieren, dass eine Exception geworfen wird. Gibt es eine Möglichkeit, diese dem Benutzer anzuzeigen? Denn bis jetzt ist es so, dass er solange die TextBox nicht verlassen kann, bis der Wert gültig ist bzw. keine Exception geworfen wird.
Hallo!
Ich habe ein Objekt, das über mehrere String-Eigenschaften verfügt. Nun hätte ich gerne, dass gewisse Textboxen an diese Strings gebunden werden. Hierzu habe ich gemäß eines anderen Themas eine BindingSource erstellt und mein Objekt angegeben.
Nun erzeuge ich eine Instanz des gewissen Objekts und weise es der DataSource-Eigenschaft der BindingSource zu. Wenn ich nun eine Eigenschaft (im Quellcode) ändere, so wird die entsprechende TextBox leider nicht aktualisiert. Setze ich die Text-Eigenschaft der TextBox im Quellcode manuell, so wird diese Änderung auch nicht auf das Objekt übertragen. Einzig und allein, wenn ich direkt in meinem Formular als Benutzer etwas eingebe, wird diese Änderung auch auf das Objekt übertragen.
Was muss ich tun, damit es so funktioniert, wie ich gerne hätte?
Lg oli
Hallo!
Ich habe vor kurzem das SP1 für Visual C# 2008 Express installiert und somit auch das SP1 des .NET Frameworks 3.5. Auf einmal sind die Hilfetexte (die, die direkt in der IDE angezeigt werden, wenn man z.B. per Code Completion durch die Methodenliste scrollt) auf Englisch! Kann mir jemand sagen, wo ich die Sprache wieder auf Deutsch zurücksetzen kann? (Hab auch das deutsche Language Pack installiert).
Lg oli
Deine Logger-Klasse muss nur dafür sorgen, das in regelmäßigen abständen Flush() aufgerufen wird, da der Inhalt zwischengespeichert wird.
Okay, danke, dann werde ich das am besten tun 😉
Gibt es eine Möglichkeit, um herauszufinden, wieviele eigene Threads im aktuellen Process noch laufen? Wenn der Logger einen eigenen Thread hätte, dann könnte man prüfen, ob das der einzige ist und dann Flushen und schließen.
das ist mir vollkommend klar.
ich empfehle den singleton aus anderen gründen.
Dürfen wir auch wissen, was diese Gründe sind?
Lg oli
Hallo!
Ich habe eine statische Loggerklasse entwickelt, die im statischen Destruktor automatisch einen FileStream erzeugt für das Logfile. Mit den entsprechenden statischen Methoden kann ich meine Logeinträge schreiben. Ein Problem, das ich allerdigns habe, ist das Schließen des Streams, was am besten in einer Art "statischen Destruktor" ausgeführt werden sollte.
Meine Anwendung besteht aus vielen Threads, darum kann ich nicht einfach am "Ende des Programms" eine Close-Methode aufrufen.
Habt ihr Ideen, wie ich das Problem lösen kann?
Lg oli
Hallo!
Ich habe die Visual C# 2008 Express Edition auf einem Computer installiert, der in einem kleinen Netzwerk, welches nicht mit dem Internet verbunden ist, hängt. Heute ist der Fehler aufgetreten, dass die IDE nach dem Laden des Projekts und nach dem Beenden des Debuggens für mehrere Sekunden einfriert. Dieser Fehler ist leider reproduzierbar. Sobald ich die Netzwerkverbindung deaktiviere, tritt dieses Fehlverhalten nicht mehr auf.
Hat jemand eine Idee, warum das passiert und wie ich das ändern kann?
Schon mal danke im Voraus,
Lg oli
[edit] Genauere Betrachtung hat ergeben, dass bei besagten Momenten ein Udp-Socket geöffnet wird (der Port ist beliebig gewählt und > 50.000) und erst wenn dieser geschlossen wird, reagiert die Anwendung wieder.
Hallo!
Ich versuche gerade zwei Threads zu synchronisieren, allerdings will mir das nicht so recht gelingen. Ich habe mir folgendes zu meinem Problem überlegt:
Ich habe einen Thread, in dem eine Netzwerkverbindung verarbeitet wird. Nun bekommt dieser Thread von verschiedenen anderen Threads Pakete, die er abschicken soll. Auf diese Pakete kommt eine Antwort zurück, die dem auftraggebenden Thread, der in der Zwischenzeit schläft, mitgeteilt werden sollte.
Nun dachte ich mir, ich verwende die System.Threading.Monitor-Klasse, mit der ich Objekte sperren kann. Ich dachte mir, dass ich im auftraggebenden Thread ein Objekt erzeuge, welches später auch das Antwortpaket enthalten wird. Nun sage ich dem Monitor, dass er dieses Objekt für den Verbindungsthread exklusiv sperren soll, bis in diesem das Antwortpaket angekommen und zugewiesen ist; dann wird die Sperre wieder aufgehoben. Währenddessen soll der andere Thread darauf warten, dass er Objekt verwenden kann.
Wie löse ich diese Problemstellung am besten?
mfg oli
Ich habe inzwischen das weiter oben genannte Buch gekauft und bin bis jetzt recht zufrieden damit, wenn ich fertig bin, werde ich hier eine Bewertung für zukünftige Thread-Leser schreiben 😉
Trotzdem danke für den Tipp!
Lg oli
Na ich werde es mir mal überlegen, allerdings hab ich schon bei einigen Tutorials für XNA 1.1 feststellen müssen, dass sie nicht mehr für XNA 2.0 gülitg sind bzw. die Methoden entweder anders heißen oder in der Form gar nicht mehr exisitieren (was wesentlich problematischer ist).
Hi!
Ich weiß nicht, ob ihr mir hier so gut weiterhelfen könnt, aber ich frage halt trotzdem einfach mal 😉
Also meine Schule ist bald aus und ich möchte mich in der Zeit danach mit XNA beschäftigen, darum suche ich ein gutes XNA 2.0 Buch (kann auch in Englisch sein), welches die wichtigsten Felder der Spieleentwicklung abdeckt. Es muss nicht überall ins kleinste Detail gehen, was wahrscheinlich auch nicht möglich ist, aber dennoch einen halbwegs guten Überblick (mit Erklärungen!) über verschiedene Aspekte bieten.
Habt ihr Empfehlungen für mich?
Lg oli
Mir ist schon klar, dass Socket.Accept() eine blockierende Methode ist und ich einen extra Thread dafür verwenden sollte (bzw. muss) und das tue ich auch.
Was ich jedoch erreichen möchte:
while (active)
{
if (pending)
{
Socket client = socket.Accept();
}
else
{
Thread.Sleep(sleepTime);
}
}
socket.Close();
damit ich durch setzen der Variable active auf false den Vorgang sanft beenden kann und keine ThreadAbortException auslösen muss.
Inzwischen habe ich aber folgende Lösung bzw. Workaround:
private bool accept(Socket server, out Socket client)
{
try
{
server.Blocking = false; // nur einmal aufgerufen woanders im Code
client = server.Accept();
return true;
}
catch (SocketException e)
{
if (e.ErrorCode == 10035) // Fehlercode, wenn Ressource gerade nicht vorhanden
{
client = null;
return false;
}
throw e;
}
}
while (active)
{
Socket client;
if (accept(socket, out client))
{
// mache was anderes
}
else
{
Thread.Sleep(sleepTime);
}
}
Lg oli
PS: suche aber immernoch nach einem eleganteren Weg 😉
PPS: Codesegmente sind nur hier im Forum geschrieben weil ich grad nicht zu Hause bin, könnten also fehlerhaft sein!
Hallo!
Ich schreibe gerade eine Netzwerk-Anwendung und da ich lieber mit den Sockets anstatt TcpListener und TcpClient arbeite, möchte ich euch fragen, wie ich die Methode TcpListener.Pending() realisieren könnte, da ich sie äußerst praktisch finde.
Ich möchte nicht auf den TcpListener umsteigen, ebenso interessiert mich die Frage auch ohne konkretes Problem 😉
Habt ihr Ideen?
Lg oli
Ich habe jetzt ein paar Beiträge gelesen und bin noch mehr verwirrt als zuvor ^^
Obwohl ich zwar denke, dass ich bei MDX bleibe, habe ich das Problem, dass es keine wirkliche Dokumentation gibt. Drum werd ich mir XNA mal herunterladen und anschauen, wie das funktioniert und ob ich damit machen kann, was ich möchte 😉
Lg oli
Hi!
Ich habe vor kurzem begonnen, mich mit DirectX bzw. im Speziellen mit Direct3D zu beschäftigen und habe hierbei mit Managed DirectX begonnen. Doch gibt es das nur mehr in der Version 1.1 und wird nicht mehr weiterentwickelt.
Ebenso fällt es mir schwer, eine richtige Dokumentation darüber zu finden. Es ist zwar, soweit ich das herausgefunden habe, ein Wrapper auf das normale DirectX, aber dennoch heißt nicht alles gleich und es ist schwer, das zu finden, was man sucht 😉
Darum bin ich auch auf XNA gestoßen, was anscheinend eine Art neues MDX sein soll, oder auch nicht? Ich lese immer wieder, dass es die Spieleentwicklung erleichtern soll. Zwar habe ich es mir noch nicht angesehen, aber ich denke, dass dieses Framework dann alles wirklich auf die Entwicklung von Spielen auslegt. Im Gegensatz zu MDX wird es jedoch weiterentwickelt.
Deshalb stellen sich mir folgende Fragen:
Was soll ich benutzen?
Inwiefern eignet sich XNA auch für andere 3D-Anwendungsgebiete wie z.B. CAD?
Worin liegen die Unterschiede zwischen MDX und XNA?
Ich hoffe, ihr könnt mir helfen, mir ein bisschen Klarheit in diesem Thema zu verschaffen und mir bei der Entscheidung zu helfen, was ich mir lernen sollte!
Vielen Dank schon mal im Voraus,
Lg oli
Oh sorry, hab ich gar nicht so mitgekriegt ^^
Lg oli
Probier mal folgendes:
m_Device.RenderState.CullMode = Cull.None;
m_Device.RenderState.Lightning = false;
Hey danke sehr 😁
Werde es dann mal testen, wenn ich mit meinen Schulsachen fertig bin ^^
Lg oli
Hallo!
Ich füge meiner ComboBox Items hinzu. Diese Objekte sind von einer selbstdefinierten Klasse und überschreiben die ToString-Methode, die eine Eigenschaft namens Name zurückgibt. Das funktioniert wunderbar, solange die Eigenschaft nicht geändert wird. Kann ich irgendwie ein Aktualisieren der Items auslösen?
Lg oli
So, ich habe jetzt eine, eigentlich sogar recht einfache Lösung gefunden:
public Form1()
{
InitializeComponent();
this.BackColor = SystemColors.Control;
this.TransparencyKey = SystemColors.Control;
this.pictureBox1.BackColor = Color.Transparent;
}
private void OnFormPaint(object sender, PaintEventArgs e)
{
Rectangle rect = this.RectangleToScreen(this.ClientRectangle);
e.Graphics.CopyFromScreen(
new Point(rect.Location.X + e.ClipRectangle.Location.X, rect.Location.Y + e.ClipRectangle.Location.Y),
e.ClipRectangle.Location, this.ClientRectangle.Size);
}
Zusätzlich wird ein Neuzeichnen beim Bewegung oder Größe Verändern des Fensters veranlasst. Es ruckelt zwar, aber da dieses Programm dafür gedacht sein wird, ein Immer-im-Hintergrund-Notizen-Programm zu sein, ist dies für meine Zwecke egal 😉
Anbei das Projekt als Visual Studio 2005 Solution.
Lg oli
Das macht nichts, wenn ich die Controls darunter nicht sehe, es wird sich nur um Panels oder so handeln, auf denen bzw. über denen sich Labels befinden werden.
Hier ein Screenshot, der zeigt, wie es aussieht und wie es aussehen sollte.
Hallo!
Ich habe eine Form, deren Hintergrund transparent ist (sprich mit BackColor und TransparencyKey erreicht). Nun möchte ich auf dieser transparenten Form eine PNG Grafik anzeigen lassen, welche auch halb-transparent ist, also z.B. einen Farbverlauf von Weiß nach Transparent beinhaltet.
Wie stelle ich das am besten an? Einfach das Bild in eine PictureBox laden funktioniert leider nicht, auch wenn die BackColor auf Transparent gestellt ist 😒
Lg oli
Danke, ich werde mir später dann den Link ansehen. Mir geht es prinzipiell darum, dass das Projekt nichts tolles können muss, sondern lediglich ein gutes exemplarisches Beispiel ist, wie z.B. Mensch -> Frau : Mensch, Mann : Mensch, was z.B. gut Vererbung zeigt, jedoch keinen großen Nutzen hat 😉
Hallo!
Crossthread in der DelphiPraxis
Dieses Jahr ist mein letztes Schuljahr, so muss ich eine Matura absolvieren und habe mich deswegen entschieden, eine Fachbereichsarbeit im Fach Informatik zu schreiben über das Thema "Objektorientiertes Programmieren".
Für eben diese Arbeit bin ich auf der Sache, nach einem guten Beispiel, um möglichst viele Funktion von OOP zu präsentieren. Doch leider habe ich im Moment keine Idee, was für ein (umfangreicheres) Beispiel ich in meiner FBA zeigen könnte. Ich möchte nicht so ein Standardbeispiel verwenden, wie eine Klasse Körper und dann vererbte Klassen Kugel, Quader, ... mit lediglich ein paar Eigenschaften zum Readonly Zugriff auf Klassenfelder.
Was das Beispiel im günstigsten Fall beinhaltet (einigermaßen nach Wichtigkeit gereiht):
* Konstruktoren (und Destruktoren)
* Methoden und Felder
* Vererbung
* Zugriffsebenen
* Eigenschaften
* Ereignisse
* Abstrakte Klassen
* Statische Klassen
* Interfaces
Das Beispiel kann durchaus ein wenig komplexer sein, es soll ja OOP von allen Seiten zeigen. Die Idee dafür kann auch in Form einer kleinen bis mittelgroßen Bibliothek sein, die eine gewisse Aufgabe durchführt. Wichtig jedenfalls ist es, die OOP-Features zu zeigen.
Also, habt ihr Ideen?
mfg oli
Danke, Friedel, das ist genau das, was ich gesucht habe 😉
Diese Variante war mir zwar noch aus meinen Win32 Zeiten in den Sinn gekommen, nur umsetzen in C# hätte ich sie alle mal nicht und ich habe gehofft, das Framework würde mir eventuell einen einfacheren Web bieten.
Hallo!
Ich suche nach einer Möglichkeit, das rote Kreuz einer Form zu disablen, damit der Benutzer auf diesem Wege die Form nicht schließen kann.
Zur Zeit verwende ich folgendes:
private void OnFormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
e.Cancel = true;
}
Der Nachteil hierbei ist, dass der User nicht weiß, wieso die Form nicht geschlossen werden kann, obwohl es im Grunde möglich sein sollte. So will ich eben dem Anwender signalisieren, dass dieses Formular auf diese Weise nicht geschlossen werden kann.
Lg oli
Ich hab inzwischen schon herausbekommen, wie ich die Packete auswerte und werde bald eine fertige Klasse hier presäntieren.
Für ein Online Spiel programmiere ich einen Private Server nach, rein aus Interesse. Meine bisherigen Quellen geben jedoch nicht mehr genug Auskunft über die einzelnen Packete, wodurch sich mein Unterfangen als äußert schwierig erweist 😉
Tja, und wie mach ich das? ^^
Ich weiß nicht, wie ich einen Proxy in die Verbindung einbauen kann, ich kann weder an Server noch Client etwas verändern in dieser Richtung.
Ich bin schon auf diesen Packet Monitor gestoßen, nur leider liefert der die ganzen Packte inklusive TCP Header etc. womit ich mich jedoch leider überhaupt nicht auskenne und daher meine Frage, wie komme ich an die Daten selbst?
Hallo!
Ich würde gerne wissen, wie es möglich ist, ein- und ausgehende Tcp Packete eines bestimmten Ports abzufangen und diese aufzuzeichnen. Die Packete sollen hierbei jedoch weitergeschickt werden an das Ziel. Das Progrann läuft auf dem Client-Computer auf einem Administrator-Account.
Lg oli
Was meinst du? Ich hab jetzt nicht ganz verstanden, was du zum Ausdruck bringen hast wollen 🤔
Ja, er tut, was er soll ^^
Aber was meinst du, für meine aktuellen Zwecke sollte er reichen?
Ist er fehlerhaft, unperformant oder hast du Verbesserungsvorschläge?
Lg oli
Also ich habe das Problem jetzt selbst gelöst.
Hier die wichtigen Teile:
try
{
SocketError error;
int size = client.Receive(buffer, 0, bufferSize, SocketFlags.None, out error);
if (error == SocketError.Success && size > 0)
{ }
else
{
// Disconnect
}
}
catch
{
// Disconnect
}
Hier ist meine Lösung gekapselt in einer Klasse mit Threading und allem drumherum:
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace SocketTest
{
public class TcpServer
{
/// <summary>
/// When a client connects to the server.
/// </summary>
public delegate void ClientConnected(Socket client);
/// <summary>
/// When a client connects to the server.
/// </summary>
public event ClientConnected OnClientConnected;
/// <summary>
/// When a client sends data.
/// </summary>
public delegate void DataReceived(Socket client, byte[] data);
/// <summary>
/// When a client sends data.
/// </summary>
public event DataReceived OnDataReceived;
/// <summary>
/// When a client disconnects.
/// </summary>
public delegate void ClientDisconnected(Socket client);
/// <summary>
/// When a client disconnects.
/// </summary>
public event ClientDisconnected OnClientDisconnected;
/// <summary>
/// The socket on which the tcp server is based on.
/// </summary>
private Socket socket;
/// <summary>
/// The server's port.
/// </summary>
private int port;
/// <summary>
/// The buffer size.
/// </summary>
private int bufferSize;
/// <summary>
/// The thread in which the server listens for incoming connections.
/// </summary>
private Thread listeningThread;
/// <summary>
/// A list of threads in which interaction with client is handled.
/// </summary>
private List<Thread> clientThreads;
/// <summary>
/// Defines if the server is active or not.
/// </summary>
private bool active;
/// <summary>
/// Defines if the server is active or not.
/// </summary>
public bool Active
{
get
{
return active;
}
}
/// <summary>
/// Creates a new tcp server on a certain port.
/// </summary>
/// <param name="port">The port on which the server should run.</param>
/// <param name="bufferSize">The size of the buffer.</param>
public TcpServer(int port, int bufferSize)
{
this.port = port;
this.bufferSize = bufferSize;
clientThreads = new List<Thread>();
}
/// <summary>
/// Starts the server.
/// <param name="backlog">The max. number of outstanding connections.</param>
/// </summary>
public void Start(int backlog)
{
active = true;
try
{
IPEndPoint endpoint = new IPEndPoint(new IPAddress(0), port);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(endpoint);
socket.Listen(backlog);
listeningThread = new Thread(new ThreadStart(listen));
listeningThread.Start();
}
catch
{
active = false;
}
}
/// <summary>
/// Stops the server.
/// </summary>
public void Stop()
{
try
{
active = false;
socket.Close();
}
catch { }
}
/// <summary>
/// Method in which the server listens for incoming connections.
/// </summary>
private void listen()
{
while (active)
{
try
{
Socket client = socket.Accept();
if (OnClientConnected != null)
OnClientConnected(client);
Thread thread = new Thread(new ParameterizedThreadStart(work));
clientThreads.Add(thread);
thread.Start(client);
}
catch
{
Stop();
}
}
}
/// <summary>
/// Method in which the server communicates with the client.
/// </summary>
private void work(object parameter)
{
Socket client = (Socket)parameter;
byte[] buffer = new byte[bufferSize];
SocketError error = SocketError.Success;
while (active && client.Connected)
{
try
{
int size = client.Receive(buffer, 0, bufferSize, SocketFlags.None, out error);
if (error == SocketError.Success && size > 0)
{
byte[] data = new byte[size];
Array.Copy(buffer, data, size);
if (OnDataReceived != null)
OnDataReceived(client, data);
}
else
{
if (OnClientDisconnected != null)
OnClientDisconnected(client);
client.Shutdown(SocketShutdown.Both);
client.Close();
}
}
catch
{
if (OnClientDisconnected != null)
OnClientDisconnected(client);
client.Shutdown(SocketShutdown.Both);
client.Close();
}
}
}
}
}
Hm, das was du sagst, ist schade :-\
Zur Zeit lese ich so Daten aus, dass eine while-Schleife läuft und wenn der NetworkStream bei DataAvailable true zurückgibt, Daten auslese. Wenn es jedoch zu einem Verbindungabbruch kommt, so wird der Stream wohl immer false bei DataAvailable ausgeben.
Wie kann ich also die Sache angehen, um den Vebindungsabbruch zu erkennen?
Lg oli
Kann mir denn niemand das einm wenig näher erklären?
Ich wäre euch echt sehr dankbar!
Lg oli
Könntest du das vielleicht nachsehen wie das geht?
Weil das wäre echt wichtig für mich!
Vielen Dank jetzt schon mal für deine bisherige und noch zukünftige Mühe 🙂
Lg oli
Tut mir Leid, ich weiß leider nicht, was FIN ist, aber eigentlich meine ich wenn der Client die Verbindung trennt, aber dies nicht zuerst über ein Packet ankündigt.
Hallo!
Ich habe folgendes Problem, und zwar schreibe ich eine Server-Anwendung die den TcpListener verwendet und TcpClients entgegennimmt. Das Problem, welches ich hierbei habe ist, dass es mir zur Zeit nicht möglich ist, zu erkennen, ob der Client noch verbunden ist oder nicht.
Habt ihr eine Möglichkeit, wie ich dies prüfen kann?
Schon mal vielen Dank im Vorraus!
Lg oli