Laden...

Forenbeiträge von Franknstein Ingesamt 529 Beiträge

25.07.2006 - 22:20 Uhr

Ich muss sagen, dass es beim Logging kaum was besseres gibt, als die Ausgabeumleitung der Konsole in eine Datei. Ob man Performance verschenkt weiß ich nicht, aber dafür habe ich eine Klasse die ich auch in anderen Projekten ohne Änderungen nutzen kann.

Und das beste ist: Das sind nur ~10 Zeilen Quelltext

mfg
Franknstein

19.07.2006 - 23:32 Uhr

Nur ein kleiner Punkt:
Exceptions sollten besser direkt am Entstehungsort behandelt werden. Exceptions fressen nämlich Ressourcen wie verrückt. Nimm als Begründung für das Using, dass man nicht das Dispose im Finally vergessen kann oder der wichtige Code nicht so weit auseinandergezogen wird... 😁

Aber sonst ist das meines Wissens alles richtig.

--
mfg
Franknstein

18.06.2006 - 16:38 Uhr

Was ich vormals in der Metallwerkstatt vermurkst habe, musste immer in die Altmetalltonne....

Wtf? Fängt das mit dem Wort hier auch schon an! Ich bekomme bald Verfolgungswahn.

02.05.2006 - 21:24 Uhr

Das mit dem Timeout wird meines Erachtens so nicht funktionieren, da Socket.Receive den Thread so lange blockt, bis wirklich Daten empfangen wurden.
Es gibt zwei Alternativen:
a) Du liest in der MSDN nach, was die cSocket.RecieveTimeOut bewirkt setzt, falls das klappt, diese Zeit
b) Es müsste ein Feld geben, das Available oder so heißt. Wenn das größer 0 ist, sind Daten zum Empfangen vorhanden. Wenn du deinen Code so erweiterst, dass du vor dem Empfangen prüft, ob überhaupt was da ist, sollte dein Code so gehen.

02.05.2006 - 21:14 Uhr

z.B. kann man ja auf seinem eigenen Rechner einen WebServer einrichten. Damit aber auch noch normal surfen kann, und das nicht in Konflikt mit Port 80 setzen will, legt man konventionsmäßig den lokalen WebServer auf Port 8080.

In meiner grenzenlose Unwissehnheit behaupte ich, dass der Browser vermutlich nicht den Port 80 benutzt, wenn er eine Verbindung zu einem Webserver aufbaut. Der Browser sollte automatisch vom Betriebssystem einen freien Port zugewiesen bekommen. Er braucht ja auch keinen fest definierten Port, da der Browser nicht darauf angewiesen ist, auf Verbindungen von außen zu warten. Der Browser baut ja eine Verbindung zu einem Webserver auf(der Webserver horcht im Normalfall auf Port 80), schickt die Anfrage los, bekommt eine Antwort und schließt die Verbindung wieder.
Oder bin ich völlig unwissend und auf dem Holzweg?

17.04.2006 - 11:07 Uhr

Ich glaube ich kennen den Fehler:
x = cos(w + fi) * r
y = sin(w + fi) *r

Soweit ich das sehen kann, ist bei deiner Formel hier alles im Sinus erstens konstant (und zweitens nicht einheitenfrei). Daher bekommst du immer den selben Punkt. Wenn du die Winkelgeschwinigkeit einheitenfrei machst(also mit t multiplizierst) sollte es gehen. Du musst halt bei den Schleifendurchläufen die verstrichene Zeit messen.

Edit:
Übrigens würde ich nicht mit der Kanone auf die Spatzen schießen und die Kreisbahn mit
r² = x ² + y² beschreiben.

08.03.2006 - 17:42 Uhr

(Mein Beitrag ist völliger Blödsinn)

Das Fin ist aber vom Telnet-Protokoll implementiert und nicht vom TCP-Protokoll?

07.03.2006 - 22:39 Uhr

Richtig. Evlt. muss man auch quasi sowas wie Pings implementiert, um den Server wissen zu lassen, welche der Clients jetzt weg sind.

05.03.2006 - 23:15 Uhr

Eine Möglichkeit währe:


using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;

namespace TcpTest
{
    class MyTcpClient : TcpClient
    {
        public Socket GetSocket()
        {
            return base.Client;
        }
    }
}


Allerdings bin ich mir nicht sicher, ob das so funktioniert, da ich es nicht testen kann.
Anstatt einer neuen Funktion könnte man auch die Client-Property überschreiben(Falls ich lüge, sagt es mir nur)?

Bearbeitung:
Ich habe noch eben den Namespace geändert...

05.03.2006 - 16:56 Uhr

Kann es sein, dass es TcpClient.Client nur im Framework 2.0 gibt? Im SharpDevelope 1.1 gibts das nämlich nicht.

Stimmt nicht ganz, diese Eigenschaft ist nämlich nur nicht öffentlich wie in V2. Aber es existiert intern eine gleichnamige Socket-Variable. Das heißt, du musst einfach eine Klasse von der TCPClient-Klasse erben lassen, und diese Eigenschaft veröffentlichen. So kannst du dann auch darauf zugreifen. Ich denke, es müsste auch irgendwie per Reflection hinzuzimmern sein, aber das ist keine angemessene Lösung.

04.03.2006 - 18:42 Uhr

Ich habe noch nie ein Spiel programmiert, aber Spiele haben eh immer eine Endlosschleife, in welcher alle Aktionen abgearbeitet werden. Daher ist es auch kein Problem, da auch noch einen Socket abzufragen, ob neue Daten da sind... Und da ein Spiel eigentlich das selbe Verhalten wie eine Endlosschleife hat, welche nirgends pausiert, braucht man auch nirgends das Programm schlafen zu lassen.

28.02.2006 - 16:56 Uhr

Du senkst die Qalität der JPGs. So verbrauchen sie weniger Speicherplatz..

19.01.2006 - 16:28 Uhr

Wie genau verbindest du dich denn zur Datenbank?

18.01.2006 - 18:15 Uhr

Kann es sein, dass du versuchst, zweimal den selben Socket zu verbinden(Der das zweite mal schon eine Verbindung hat)?

17.01.2006 - 19:14 Uhr

Das anbinden fast jeder Datenbank funktioniert zimlich ähnlich. Dies kommt, weil von Microsoft Vorgaben existieren, was ein Datenbankclient zu können hat, und diese auch eingehalten werden. (Diese Aussage ist evtl. nicht allgemeingültig...)
Daher sind als gute Schlagwörter MySQLConnection, MySQLCommand und MySQLDataReader zu nennen. Falls du gute Schlagwörter für die andere Datenbank suchst, lass doch einfach das MySQL weg und setze stattdessen ein Teil des anderen Datenbanknamens ein.

Ob oder wie die Datenbanken direkt von Visual Studio zu verwenden sind, weiß ich nicht, weil ich das nie mache.

17.01.2006 - 19:02 Uhr

Bei Mysql geht das doch genauso. Da heißt es halt nicht @Identity sondern Last_Insert_Id() (vlg http://dev.mysql.com/doc/refman/4.0/de/miscellaneous-functions.html)

Übrigens kann man sich einen Command in deinem Quelltext evtl. sogar sparen, da für jede Verbindung das Ergebnis des letzten Einfügevorgangs in der Variablen @Identity oder der Funktion Last_Insert_Id() gespeichert wird. Daher funktioniert das Auswählen dieser Variablen oder Funktion auch ohne den Namen einer Tabelle anzugeben. Jedenfalls kann man diese Variablen auch noch im nächsten Kommando weiterverwenden....

Bearbeitet: Ich habe ca. 57 Rechtschreib- Grammatikschreibfehler entfernt.....

17.01.2006 - 06:41 Uhr

Je nach dem welche Funktionen beim MS Sql benutzet wurden, wirst du viel Vergnügen haben...

Je nach dem, wie die Daten aus der Datenbank kommen, genügt es, den Klassennamen zu ändern. Wenn du Pech hast, musst du aber einiges neu machen. Es kommt darauf an, welche Funktionen vom SqlServer verwendet wurden und ob vorher schon jemand dran gedacht hat, das Programm evtl später auf eine neue Datenbank zu portieren.

16.01.2006 - 21:41 Uhr

Stichwort: Remoting, Socket

14.01.2006 - 08:28 Uhr

Das mit den eckigen Klammern funktioniert. Ich habe es zwar noch nie gesehen, aber ich werde mir auf alle Fälle merken, dass man die auch benutzen kann.

Sind sich die Tabellenstrukturen der unterschiedlichen Tabellen sehr ähnlich, wenn aus allen Tabellen das gleiche ausgewählt wird? Könntest du dann nicht eine ,,große`` Tabelle verwenden und andere Unterscheidungsmerkmale einbauen?

Ob der Parameter im From-Teil funktioniert kannst du da nachlesen:
http://msdn2.microsoft.com/en-us/library/ms188927(en-US,SQL.90).aspx
Aber ich wüsste nicht, warum das nicht auch gehen soll.

12.01.2006 - 21:06 Uhr

Was ist genau das Problem daran, die Addresse zu speichern? Muss man die überhaupt so lange speichern?
Du könnstest doch auf die Message mit der IP vom Server warten und dannach direkt dich zu dem Server verbinden? Dann brauchst du die Addresse nur in Variablen zu speichern....

Oder deine Frage nochmal umformulieren?

11.01.2006 - 18:22 Uhr

Der DataReader kann einem doch auch gut die Schemadaten zurückgeben. Der Datareader hat eine Funktion GetSchemaTable(). Damit bekommt man das Schema in einem DataSet zurück.

10.01.2006 - 22:14 Uhr

Ich würde uneingeschränkt zum DataReader raten, weil man die Verbindung selbst im Griff hat. So bekommt man u.U. keine Probleme mit sich als störend erweisenden Eingenschaften des DataSet. Leider kann immer nur ein Datareader pro Verbindung gleichzeitig auf Daten zugreifen. Aber das ist kein allzugroßes Problem.

05.01.2006 - 13:09 Uhr

Hierfür gibt es evtl. eine schöne und einfache Lösung, da die Möglichkeit B einfach nur abgrundtief böse ist. Man muss nämlich immer vermeiden, Daten mehrfach in der Datenbank abzulegen. Daher bietet sich eine objektrelationale Datenbank an. Eine solche ist beispielsweise die Postgresql-Datenbank. Ich habe hier sogar einen Link für dich, der dir vielleicht weiterhilft:
http://www.postgresql.org/docs/8.1/interactive/sql-createtable.html
Stichwort INHERITS

31.12.2005 - 16:57 Uhr

Hallo,
Ich nutze den SqlServer 2005 ebenfalls für ein Projekt. Eigentlich wollte ich ja die PostGresql-Datenbank verwenden, allerdings wurde ich davon überzeugt, dass es besser sei, den SQLServer zu verwenden.
Die Installation des SQLServers war eine leider sehr zeitaufwändig,was ungewöhnlich für ein Microsoftprodukt ist. Allerdings bin ich positiv vom SQLServer überrascht, seit er läuft. Das einizge was mich geärgert hat, war das Microsoft Administrationswerkzeug was irgentwie nicht so wollte wie ich und andauernd abgestürzt ist. Daher nehme ich jetzt die kostenlose Version von SQL Manager 2005. Seitdem ich diesen Schritt gegangen bin, habe ich mich auch nicht mehr über den SQLSerer aufgeregt. Die Schnittstelle nach C# ist wie gewohnt sehr gut. Über die Geschwindigkeit kann ich noch keine Aussagen treffen. Der Funktionsumfang ist einfach riesig. Was ich allerdings noch nie gemacht habe, aber mal dringen probieren müsste ist, Assemblys als Stored Procedures einzubinden.

Alternativen sind wie erwähnt der PostgreSql-Server. Dieser hat den Vorteil, dass sich auch mit anderen Sprachen als T-SQL Stored Procedures erzeugen lassen. Außerdem treibt einen die Installation nicht in den Wahnsinn. Ich eigentlich nie Probleme mit dem Postgres. Vom Funktionsumfang ist diese Datenbank vielleicht noch etwas komplexer, da sie eine objektrelationale Datenbank darstellt.

MySQL 5?
Ist das eine Alternative? Habe seit Version 4 nichts mehr mit Mysql gemacht und damals war die Datenbank aufgrund fehlender Funktionen fast nutzlos. Aber das soll ja angeblich mit der 5. Version besser geworden sein. Ich werde sie dennoch nicht mehr so bald benutzen.

--
Franknstein

21.12.2005 - 22:34 Uhr

Für was braucht man sowas?

Ach ja:
Die MSDN ist dein Freund.

11.12.2005 - 22:21 Uhr

void ThisMyEvent(object sender, EventArgs e)
{
    if (this.InvokeRequired)
    {
          object[] args = { sender, e };
          this.Invoke(new EventHandler(this.ThisMyEvent, args);
          return;
    }
    //Hier beliebigen Code einfügen
}

Also, die Funktion die per Event aufgerufen wurde überprüft, ob sie sich invoken muss. Wenn nein gehts ganz normal weiter. Wenn ein Invoke durchgeführt werden muss, dann wird die Funktion einfach mit den selbigen Parametern aufgerufen. Aber vom richtigen Thread aus.

Wenn du dein Programm als Brücke zwischen zwei anderen verwendest gehe ich davon aus, dass du keinen Fehler im Programmablauf hast, sondern dass einfach was wichtiges dem anderen Programm fehlt, sodass das andere Programm die Verbindung wieder beendet.
Wie ich das sehe, gehst du ja stur die Packete zwischen den beiden Applikationen routen und greifst sie halt noch ab.
Vielleicht müsstest du das erstmal nur mit einem Programm machen. Also so, dass nur ein Programm zu deinem Programm verbinden kann. Später kannst du ja das andere noch dazu bauen. Wichtig ist, dass du deinen Quelltext erstmal von sinnlosem Zeug fern halten musst. So kannst du nämlich Fehler ausschließen.
Vielleicht machst du erstmal nur ein einfaches Konsolenprogramm, das nichts anderes tut, als die Verbindung zu brücken.

Ich hoffe doch, du hast nichts böses im Sinn 😁

11.12.2005 - 12:27 Uhr

Auf deine ersten beiden Fragen habe ich keine Lösung. ABer ich kann dir eventuell weiterhelfen den Fehler selbst zu finden:

a) Mach bitte aus der Funktion eine(mehrere) Klassen. Oder zumindest mehrere Funktionen. Es ist nämlich als Außenstehender nicht leicht, bei dem Code durchzublicken.

b) Warum verwendest du zwei Verbindungen? Dient dein Programm nur als Brücke zu einem weiteren Programm oder baust du zwei Verbindungen auf damit du auf einer sendest und auf der anderen empfängst? Hast du eigentlich den selben Code auch auf der Gegenseite laufen?

Aber bei den Events kann ich dir helfen.

Du fügst in der Klasse über deiner Funktion in etwa sowas ein:


public event EventHandler OnMessageArrive;

Und dann in deiner Funktion an der Stelle, an der du z.B. eine neue Meldung empfangen hast:


if(this.OnMessageArrive != null)
    this.OnMessageArrive(message, new EventArgs());

Das ist die einfachste Lösung einen Event zu realisieren. Aber auch die unschönste. Du missbrauchst das Feld sender quasi um deine eigene Meldung zu übertragen. Falls du das so nicht machen willst, musst du dir eine Klasse und ein Delegate definieren. Dann kannst du so viele Daten mit einem Event übertragen, wie du möchtest.

09.12.2005 - 16:34 Uhr

Hm, ein selbst verwaltendes Netzwerk(nenne ich in meiner Naivität einfach mal so) ist vermutlich nicht so leicht. Fang erstmal ,,klein" an und entwickle eine getrennte Server-Anwendung.

Dannach baust du eine Funktion ein, mit der du automatisch die Maschine mit dem Server finden kannst(also ohne die IP des PCs mit dem Server zu kennen).

Wenn das geschafft ist, kannst du ja wichtige Teile des Servers im neuen Projekt weiterverwenden.

Natürlich kannst du das oben auch überspringen und gleich sowas machen:
Die Applikation wartet auf dem Port x auf eine neue Verbindung. Weiterhin geht sie alle alle IPs im Netzwerk durch auf der Suche nach anderen Applikationen.
Falls dann mal eine andere Instanz gefunden wurde, fangen die kleinen Problemchen an. Hier gibt es nämlich mehrere Lösungen:
a) Alle Instanzen des Chatprogramms wissen immer genau, welcher Chatter an welcher Maschiene ist und jede Instanz weiß genau, wann sie was zu tun hat. Alle Instanzen haben die selben Rechte.
b) Eine Instanz wird zum Server bestimmt(dazu rate ich). Aber es macht bestimmt einen riesigen Aufwand das ganze zu testen und alle Fehler rauszubauen. Man muss hier halt verdammt aufpassen, dass rechtzeitig die Erbfolge des Servers bestimmt wird. Es kann ja immer mal passieren, dass ein PC vom Netz getrennt wird, abstürzt oder sowas.

Also, wie man wohl lesen kann, habe ich sowas noch nie gemacht. Aber das sind so im groben die Ideen die mir auf die Schnelle dazu eingefallen sind.

08.12.2005 - 23:32 Uhr

Hm, so blöd ist die Frage nicht. Du kannst ja auch einen TcpClient von einem TCPListener bekommen.

Jedenfalls hat man damit recht große Probleme, wenn man nicht VS2005 nimmt(Da bietet die Klasse endlich direkt Zugriff auf den Socket...)

Es gibt drei Möglichkeiten:
a) Eine neue Klasse erzeugen die vom TCPClient erbt und die Property Server öffentlich zugänglich macht.
b) Auf die Property Server per Reflection zugreifen(habe ich mal machen müssen)
c) Gleich Sockets verwenden

06.12.2005 - 21:54 Uhr

Mein interessantestes Projekt war die Mitarbeit an einem Kommunikationsstack für ein zukünftigen Fahrzeugbus. Hardwarebedingt natürlich nicht mit .Net möglich, dafür hab ich gelernt C als Sprache noch mehr zu hassen smile Aber es ist einfach faszinierend in den embedded Bereich reinzuschnuppern. Hardware mit der Seriennummer 1 und 2 vor sich zu haben wo keiner weiß ob die wirklich funktioniert großes Grinsen , nur die Möglichkeit für 5 Hardwarebreakpoints beim Debuggen um dann festzustellen das man eh net geschickt debuggen kann weil die IRS's alles durcheinanderhaun. Und das ganze wird in Zukunft auch noch auf unseren Straßen rumfahren smile Neben C# ist das echt eins von meinen Lieblingsgebieten.

Sowas ist für mich einer der Gründe Elektro- und Informationstechnik studieren zu wollen...

06.12.2005 - 19:17 Uhr

Zu dem Remoting kann ich nichts sagen, das habe ich noch nie gemacht.

Bisher habe ich immer nur mit Streams gearbeitet. Und ich weiß nicht, was dbf-Dateien sind. Aber im Prizip würde ich das so lösen:
Der Client baut beim Start eine Verbindung per TCP zum Server auf. Wenn dann eine Datei geändert/erzeugt wurde, wird diese Änderung zum Server übertragen. Ich würde dazu einfach ein Xml-Dokument erzeugen, welches verschiedene Daten des Clients und die Datei enthält. Das komprimiert man dann noch, falls es was bringt und schickt es zum Server.

Der Server wartet auf neue Verbindungen. Wenn ein Client verbindet, wird ein neuer Thread angelegt und zusammen mit einer ClientId in einer List abgelegt. Die ClientId wird dem Client geschickt. Der Client muss diese Id immer mitschicken, wenn er was zum Server überträgt. Der neu angelegte Thread macht eingentlich nur eins: Er wartet auf neue Daten vom Client. Wenn neue Daten empfangen wurden, wird das Packet mit dem Xml-Dokument zerlegt und die Datei daraus extrahiert. Dann kann man das Empfangene Packet auswerten in die Datenbank packen(, die anderen Clientes über Änderungen benachrichtigen) und dem Clienten sagen, dass alles gut verlaufen ist.

05.12.2005 - 17:34 Uhr

Es wird nur so lange bis zum nächsten Zeilenumbruch gelesen, bis ein Byte den Wert 0x00 hat.

Wobei das nicht unbedingt so klappen kann. Besser währe:


StringBuilder bd = new StringBuilder();
char[] buffer = new char[1024];
while(sr.Peek() != -1)
{
    sr.Read(buffer, 0, buffer.Lenght);
    bd.Append(buffer);
}

Console.WriteLine(bd.ToString());

Das tuts nämlich auch ohne ein Zeilenumbruch!
(Falls es überhaupt funktioniert, ich habe es nicht getestet)

28.11.2005 - 21:09 Uhr

Würde ich nicht asyncron machen. Es macht zwar mehr Aufwand, wenn du die Dateien zerlegst, versendest und dann wieder zusammenbaust, aber dafür kannst du einige Vorteile nutzen. So musst du zum Beispiel dich nicht dem dem asyncronen Zeuch rumplagen. Außerdem kannst du, je nach dem wie komplex das Protokoll ist, auch noch andere, wichtigere (Steuer)Daten übertragen. Und wenn mal die Verbindung zusammenbricht, macht das auch nichts, da du ja problemlos gucken kannst, welche Packete der Datei fehlen.

24.11.2005 - 22:39 Uhr

Ist der TCPListener ordnunsgemäß gestartet? Kannst du mal bitte noch den Code mit dem Teil zeigen, bei dem eine Verbindung vom Server angenommen wird?

Noch eine Frage:
Warum gibst du die Verbindungsdaten beim Erzeugen des Objekts und beim Herstellen der Verbindung an? Ich habe die IP und den Port immer nur der Connect-Methode mitgegeben. Und in der MSDN wird die Connect garnicht aufgerufen. Dort wird direkt der Stream nach dem Erzeugen des Objekts genommen um Daten zu übertragen. Evtl. liegt da der Fehler. (Was aber irgentwie unwarscheinlich ist)

21.11.2005 - 17:18 Uhr

Hallo, du kannst auch einen Socket auf eine neue Verbindung warten lassen. Das geht laut MSDN so:


// create the socket
    Socket listenSocket = new Socket(AddressFamily.InterNetwork, 
                                     SocketType.Stream,
                                     ProtocolType.Tcp);

    // bind the listening socket to the port
IPAddress hostIP = (Dns.Resolve(IPAddress.Any.ToString())).AddressList[0];
    IPEndPoint ep = new IPEndPoint(hostIP, port);
    listenSocket.Bind(ep); 

    // start listening
    listenSocket.Listen(backlog);


Probier das halt mal. Vielleicht klappts ja, aber ich wüsste nicht, warum ein Dienst im Zusammenhang mit einem TCPListener Probleme bereitet. Villeicht liegt das Problem auch andernweilig. Vielleicht kann der Dienst nicht mehr reagierern, wenn er auf eine neue Verbindung wartet? Ich weiß es nicht.

Wenn das oben nicht klappt, kannst du ja asyncron auf eine neue Verbindung warten.
Lies dir am besten mal das hier durch:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemnetsocketssocketclassbeginaccepttopic.asp

19.11.2005 - 01:24 Uhr

Den Fehler konnte ich bei mir noch nie feststellen, obwohl ich Teilweise schon TCP-Verbindungen über das Internet aufgebaut habe. Kannst du die Rahmenbedingungen des Test näher beschreiben?

17.11.2005 - 21:11 Uhr

Ich hätte gerne noch den Code der cd.StructThread.Abort()-Methoden gesehen.

Was mir an dem Code missfällt ist, dass dort zum Beispiel immer wenn was empfangen werden soll, du dir den Stream neu greifst. Hierbei wird, denke ich, aber nicht das Problem liegen.

Ich habe immer eine Client-Klasse geschrieben, welche die Verbindung zum Clienten/Server kapselt. Dieser kann man im Konstruktor den Socket mit der Verbindung zum Clienten übergeben. Diese Instanz wird dann von der Serverklasse, die auch auf neue Verbindungen wartet, in einer Liste gespeichert. Weiterhin stellt die Klasse Client zwei Methoden zum Senden und Empfangen bereit. Das Empfangen ist aber keine öffentliche Methode, da ich immer wenn Daten empfangen werden, einen Event auslöse, der von der übergeordneten Severklasse ausgewertet wird. Wenn die Verbindung zusammenbricht, oder eine SocketException in der Client-Klasse fliegt, versuche ich den Socket zu schließen, und löse dann einen Exit-Event aus. Dieser wird auch von der Server-Klasse abgefangen und daraufhin wird der Client aus der Liste der Verbindungen geworfen. Weiterhin existieren Mechanismen um auch Timeouts von Clientseiten zu erkennen. Also wenn der Client zum Beispiel mal zwei Minuten nichts geschickt hat, wird ihm auch die Verbindung getrennt.

17.11.2005 - 18:46 Uhr

Du musst einen Tcp-Listener Starten. Der wartet dann auf neuen Verbindungen. Wenn dann eine neue Verbindung hergestellt wird, erzeugst du einen neuen Thread der das Socket-Objekt(Oder TCP-Client-Objekt) verwaltet.

Aber warscheinlich weißt du das auch schon. Daher würde ich dich bitten, die Frage zu konkretisieren.

05.11.2005 - 09:48 Uhr

Guck mal bitte, ob der nachfolgende Code richtig funktioniert:


int height = 0;
int screen_id = -1;
foreach (DataRow row in dataSet21.TB_Screen.Rows)
{
    if((int) row["Screen_Height"] > height)
    {
        height = (int) row["Screen_Height"];
        screen_id = (int) row["Screen_Id"];
    }
}
Console.WriteLine("Maximalhöhe: {0}", height);
Console.WriteLine("Datensatznummer: {0}", screen_id);

Nachträglich angefügt:
Der Fehler mit Variable nicht zugewiesen kommt, weil die Variable in einer Schleife steht, du sie aber ,,globaler`` deklariert(?) hast. Du kannst mal testen, was passiert, wenn du w2 = "" anstatt nur string w2 schreibst.

13.10.2005 - 17:02 Uhr

Der hier http://dev.mysql.com/downloads/connector/net/1.0.html ist eigentlich recht gut....

26.09.2005 - 22:28 Uhr

Das mit den TCP und UDP-Packeten ins Internet senden sollte fast mit am leichtesten sein. Guck mal ob da was passendes dabei ist:
http://www.microsoft.com/germany/msdn/library/net/csharp/CsharpTippsTeil1NetzwerkUndInternet.mspx
An sonsten hilft dir bestimmt das Schlüsselwort Sockt weiter.

Das aufbauen der Telefonverbindung mit der Fritzcard sollte auch gut möglich sein. Ein Bekannter von mir hat sich mal eine Freisprecheinrichtung gebaut. Das GSM-Modem hat er dabei über AT-Kommandos angesteuert. Vielleicht hilft dir der Link hier weiter:
http://www.computerjockey.de/netzwerke/at/

Zu dem VoIP kann ich so nichts sagen. Damit habe ich mich noch nie befasst.

Sql

16.09.2005 - 21:59 Uhr

Also, die Unterstützung für den MSSql-Server 2000 ist meines Wissens immer schon standartmäßig beim Dotnet-Framework dabei. Bei dem 2005er wird der Zugriffsprovider auf alle Fälle mitgeliefert. Ich habe da nämlich vor kurzem eine Applikation für entwickelt und keine zusätzlichen Komponenten zum Verbinden zum Sql-Server gebraucht.

Sql

16.09.2005 - 16:38 Uhr

In groben Zügen?
Das sollte doch gehen:
-Du importierst den System.Data.SqlClient-Namespace
-Du erzeugst eine Verbindung zur Datenbank mit der SqlConnection-Klasse
-Du verwendest die Verbindung nach dem öffenen um einen SqlCommand auszuführen. -Dannach kannst du mit einem SqlDataReader die evtl ausgewählten Daten hohlen.

12.09.2005 - 15:52 Uhr

Ich habe mir mal einen solchen selbst geschrieben. Allerdings musst du einige Dinge beachten:
a) Alle Connections die du hohlst, musst du auch wieder immer zurückgeben. Sonst blockiert der Verbindungspool alle Threads die neue Verbindungen haben wollen. Timeouts, das die Verbindungen nach der Zeit x freigegeben werden, gibt es nicht.
b) Evtl muss du die Stelle auskommentieren, an der die Datenbankverbindung genullt wird, wenn sie dem Pool wieder übergeben wird. Dann musst du dich aber darum kümmern, dass sie automatisch neu erzeugt wird, wenn die Verbindung mal kaputt gehen sollte. (Die Klasse erzeugt nämlich immer eine neue Verbindung, wenn ein Verbindungsobjekt benötigt wird, was du ja nicht willst)
c) Du solltest es vermeiden, mehrere Verbindungen im selben Thread zu verwenden, wenn das maximale Verbindungslimit zu gering ist. Sonst kannst du das ganze Programm blockieren.

Warscheinlich mag es sinnvoll sein, diese Klasse lediglich als Anregung für einen eingenen Verbindungspool heranzuziehen und selbst einen Verbindungspool für deine Bedürfnisse zu entwickeln.

So und jetzt der Quelltext:


using System;
using System.Collections.Generic;
using System.Text;
using MySQLDriverCS;
using System.Threading;

namespace Chat.Server.Database
{
    class MySqlConnectionPool
    {
        MySQLConnection[] m_Connections = null;
        private bool m_HasFreeConnection = false;
        private Queue<int> m_FreeConnections = null;
        private AutoResetEvent m_Semaphore = null;
        private int m_MaxConnections = 5;
        private string m_ConnectionString = "Der Connectionstring";

        private MySqlConnectionPool()
        {
            this.m_Connections = new MySQLConnection[this.m_MaxConnections];

            this.m_Semaphore = new AutoResetEvent(false);
            this.m_FreeConnections = new Queue<int>();
            this.m_HasFreeConnection = true;

            this.m_HasFreeConnection = true;
            for (int i = 0; i < this.m_Connections.Length; i++)
            {
                this.m_FreeConnections.Enqueue(i);
            }
        }

        private static MySqlConnectionPool m_Instance = null;
        public static MySqlConnectionPool Instance
        {
            get
            {
                if (m_Instance == null)
                    m_Instance = new MySqlConnectionPool();

                return m_Instance;
            }
        }

        public MySQLConnection Get()
        {
            if (!this.m_HasFreeConnection)
                this.m_Semaphore.WaitOne();

            int Index = this.m_FreeConnections.Dequeue();
            this.m_Connections[Index] = new MySQLConnection(
                                     this.m_ConnectionString);
            this.m_Connections[Index].Open();
            this.m_Connections[Index].Database = "chatserver";

            if (this.m_FreeConnections.Count == 0)
                this.m_HasFreeConnection = false;

            return this.m_Connections[Index];
        }

        
        public void Return(MySQLConnection connection)
        {
            try
            {
                int index = this.IndexOf(connection);
                if (this.m_Connections[index].State != System.Data.ConnectionState.Closed)
                {
                    this.m_Connections[index].Close();
                    this.m_Connections[index].Dispose();
                }
                this.m_Connections[index] = null;
                this.m_FreeConnections.Enqueue(index);
                this.m_HasFreeConnection = true;
                this.m_Semaphore.Set();
            }
            catch (Exception)
            {
                if (connection.State != System.Data.ConnectionState.Closed)
                {
                    connection.Close();
                    connection.Dispose();
                    connection = null;
                }
                throw new Exception("Fehler: Die Datenbankverbindung existiert nicht in der Datenbankverbindungsliste");
            }
        }

        private int IndexOf(MySQLConnection con)
        {
            for (int i = 0; i < this.m_Connections.Length; i++)
            {
                if (this.m_Connections[i] == con)
                {
                    return i;
                }
            }
            throw new Exception("Das angegebene Element wurde nicht gefunden");
        }
    }
}

Bearbeitet:

Hier ist noch ein kleines Beispiel, wie die Klasse zu verwenden ist:


MySQLConnection con = null;
try
{
    con = MySqlConnectionPool.Instance.Get();
    MySQLCommand com = con.CreateCommand();
    com.CommandText = "DeinSQL";
    //Hier kannst du dann deinen DataReader/etc ausführen....   
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message, ex.StackTrace);
}
finally
{
    if(con != null)
    MySqlConnectionPool.Instance.Return(con);
}

12.09.2005 - 15:41 Uhr

writer.Write(reader.ReadToEnd());
ersetzt du durch:


byte[] buf = new byte[1024];

while(reader.Peek() != -1)
{
    reader.Read(buf, 0, 1024);    
    stream.Write(buf, 0, 1024);
}

Also, ich habe das jetzt mal so frei Schnautze aufgeschrieben, wie es evtl funktioniert. Es kann natürlich sein, dass irgent welche Parameter zu viel sind(bei dem stream.Write), aber es sollte passen. Guck halt mal ob es funktioniert. Wenn der Code vom Syntax richtig ist, aber der Server nur die ersten 1024 Bytes empfängt, musst du halt dort auch noch eine Schleife bauen, mit der du auch nachfolgende Daten hohlst.

Evtl musst du Binärdaten aber mit Convert.ToBase64String noch in das Base64-Format umwandeln.

12.09.2005 - 13:13 Uhr

Also, der Mysql-Treiber lockt immer die Verbindung, wenn ein DataReader gerade Daten von einem vorausgegangenen Command abhohlt. Dann wird die Verbindung erst wieder freigegeben, wenn der Reader auch geschlossen ist. Dieses Verhalten ist bei allen mir bekannten Datenbanktreibern mehr oder weniger feststellbar. (Mit weniger meine ich, dass es z.B. beim SQL-Base-Treiber meistens mit mehreren Kommandos pro Connections in unterschiedlichen Threads gekappt hat, aber eben nicht immer)

Du solltest einen Connection-Pool verwenden, der dir Datenbankverbindungen zur Verfügung stellt. Weiterhin läufst du dann auch nicht Gefahr, dass dir ein anderer deiner Threads die Datenbankverbindung schließt während du im einen Thread noch eine Abfrage ausführst.

12.09.2005 - 10:54 Uhr

Wenn du den Status der Übertragung meinst, kannst du nur die Bytes mitzählen, die du schon geschrieben hast. Dazu musst du aber deinen Code etwas verändern. Dazu darfst du nämlich die Datei nicht an einem Stück in den Netzwerkstream schicken, sondern musst sie in byte-Arrays aufteilen.(Geht bestimmt auch anders - ich würde das allerdings so tuen)

06.09.2005 - 16:19 Uhr

Ich würde erstmal ein FTP-Clienten schreiben....
Dann wirst du schonmal mit der Netzwerkprogrammierung und dem FTP-Protokoll vertraut, musst dich aber noch nicht um die Serverfunktionen kümmern.
Wenn du das getan hast, kannst du ja einen Server schreiben.

20.08.2005 - 18:51 Uhr

Ich würde ehr den Mehraufwand aufwenden beim Protkolldesign um den Datendurchsatz zu senken. Umso weniger Daten gesendet werden, umso weniger Packete gehen verlohren und müssen nachgeschickt werden.... Und umso weniger Daten müssen verarbeitet werden. Das kostet nämlich vermutlich mehr Zeit wie das verschicken(wenn du das ungünstig machst)....

19.08.2005 - 22:57 Uhr

Kann man ja auch garnicht! Das eine ist dazu da, um große Mengen Daten rauszufeuern, bei denen es Egal ist ob ein Teil dieser Daten abhanden kommt. Mit dem anderen muss man etwas übertragen und sich sicher sein, dass es auf der Gegenseite ankommt.