EXE zur Laufzeit überschreiben/Datei senden
-
Hi,
kann ich davon ausgehen, dass ich unter jeder Plattform oder zumindest unter jeder Windowsversion die EXE überschreiben kann, während sie grade läuft? Ich denke ja, dass das Programm beim Starten komplett in den RAM geladen wird und deswegen müsst ich ja einfach bei einem Autoupdate die EXE überschreiben können (bzw. zuerst temporär runterladen und dann ersetzen, nicht, dass die EXE nur halb da ist, wenn die Verbindung unterbrochen ist) und dann einfach die EXE sich selbst neustarten lassen (also ganz am Ende mit ShellExecute() sich selbst wieder starten)?
Und dann noch eine Frage: Wie übertrage ich am besten eine Datei mit Sockets über das Internet? Dass ich nicht send() und recv() mit einem Riesenbuffer aufrufen darf, ist ja klar, aber wie groß mach ich den Buffer am besten? Vor allem darf send() beim Server nicht blockieren, sondern muss sofort zurückkehren (was ich bei einem riesigen Buffer bezweifle, weil der ja nicht sofort gesendet werden kann).
Und ist bei einer TCP-Übertragung die Datenintegrität 100%ig gewährleistet und muss ich da selbst vorsorgen (CRC32)?Viele Fragen...
ChrisM
-
kann ich davon ausgehen, dass ich unter jeder Plattform oder zumindest unter jeder Windowsversion die EXE überschreiben kann, während sie grade läuft?
geht nicht
[...] und dann einfach die EXE sich selbst neustarten lassen (also ganz am Ende mit ShellExecute() sich selbst wieder starten)?
Mh. Ich würds so machen:
- Update runterladen in ein Tempverzeichnis
- Update starten und das alte Programm beenden
- Das neue Programm merkt, dass es in einem Tempverzeichnis ist, und kopiert sich ins Programmverzeichnis, somit die alte Version überschreibend (evtl. sollte das Update noch testen ob ne ältere Version im Speicher aktiv ist, und entweder warten, oder es abschießen)
- Neustart des Updates, jedoch diesmal aus dem Programmverzeichnis
Und dann noch eine Frage: Wie übertrage ich am besten eine Datei mit Sockets über das Internet? Dass ich nicht send() und recv() mit einem Riesenbuffer aufrufen darf, ist ja klar, aber wie groß mach ich den Buffer am besten?
Meine Versuche mit den MFC Socket haben ergeben, dass der Sendbuffer ca. 38 Kilobyte groß ist. Oder auch nicht. Der kann auch kleiner sein. Oder größer. Ist undefiniert.
Am einfachsten finde ich es, wenn du ganz simpel das HTTP 1.0 Protokol implementierst, da findest du auch jede Menge plattformunabhängiger Clients für. Das hat auch noch den Vorteil, dass dein Autoupdater nen Proxy verwenden kann.Vor allem darf send() beim Server nicht blockieren, sondern muss sofort zurückkehren (was ich bei einem riesigen Buffer bezweifle, weil der ja nicht sofort gesendet werden kann).
Ich denke du verwendest die Standard Winsockets?
Dann musst du wohl oder übel für jeden neuen Client einen eigenen Thread starten. Das ist aber recht langsam. Bei vielen Threads hab ich bei meinem altem 400mhz Rechner ne deutliche Verzögerung beim starten gemerkt.
Am Besten (d.h. um die beste Performance zu bekommen) startest du direkt beim Serverstart mehrere Threads, und speicherst die Handles in ner Liste. Wenn dein Thread dann einen Client updaten soll, wird er gestartet.[quote]
Und ist bei einer TCP-Übertragung die Datenintegrität 100%ig gewährleistet und muss ich da selbst vorsorgen (CRC32)?
[quote]
Die Daten kommen perfekt an, jedoch ist nicht garantiert ob die Pakete unterwegs aufgestückelt werden. Jedoch sind Pakete mit ca. 1KB höchst selten zerstückelt (read: nie).
Das Problem würde sich allerdings erneut erübrigen, wenn du auf HTTP arbeitest.Soweit mein Senf dazu, hoffe es hilft
-
Die WinInet-API ist eigentlich relativ einfach zu bedienen, falls du HTTP, FTP o.Ä. nehmen willst -> MSDN.
Und wenn die Server-Sockets nicht blockieren sollen, warum nimmst du dann nicht nonblocking Sockets?
-
Hi,
erstmal danke für deine Antwort!
Mh. Ich würds so machen:
- Update runterladen in ein Tempverzeichnis
- Update starten und das alte Programm beenden
- Das neue Programm merkt, dass es in einem Tempverzeichnis ist, und kopiert sich ins Programmverzeichnis, somit die alte Version überschreibend (evtl. sollte das Update noch testen ob ne ältere Version im Speicher aktiv ist, und entweder warten, oder es abschießen)
- Neustart des Updates, jedoch diesmal aus dem Programmverzeichnis
So werd ich das jetzt auch machen, evtl. mit einer ganzen Batchdatei, die einfach nur ein "del game.exe
copy temp.exe game.exe
game.exe" enthält oder so...Am einfachsten finde ich es, wenn du ganz simpel das HTTP 1.0 Protokol implementierst, da findest du auch jede Menge plattformunabhängiger Clients für. Das hat auch noch den Vorteil, dass dein Autoupdater nen Proxy verwenden kann.
Ja, das hätte dann wohl auch noch den Vorteil, dass ich auch von einem Webserver runterladen kann und die extrem beschränkte Bandbreite des Spieleservers nur für das Übertragen der Hashdaten (und natürlich das eigentliche Spiel) verwenden muss.
Ich denke du verwendest die Standard Winsockets?
Ja.
Dann musst du wohl oder übel für jeden neuen Client einen eigenen Thread starten.
Hmm... ich dachte, ich kann genauso gut mit select() arbeiten? Also immer jeden Serverframe ein select() und von den Clients, die dann noch im FD_SET drinstehen die handlePacket()-Methode aufrufen und die müsste halt falls sie was sendet (beim Empfangen gibt's ja keine Probleme, sie wird ja nur aufgerufen, wenn auch wirklich was da ist) auch sofort zurückkehren.
Ich meine nämlich, ob sowas wie es in der MSDN steht, auch noch passieren kann:
If no buffer space is available within the transport system to hold the data to be transmitted, send will block unless the socket has been placed in nonblocking mode.
ChrisM
-
Hi,
Die WinInet-API ist eigentlich relativ einfach zu bedienen, falls du HTTP, FTP o.Ä. nehmen willst -> MSDN.
Na, einen HTTP-Client werd ich schon hinkriegen
Und wenn die Server-Sockets nicht blockieren sollen, warum nimmst du dann nicht nonblocking Sockets?
Weil die nicht portabel sind (Stichwort WSAAsyncSelect()).
ChrisM
-
Wo wir gerade beim Senden von Dateien via Windows Sockets sind: Kann man da wirklich eine grosse Datei mit einem einzigen send() verschicken? Oder muss man die Datei manuell fragmentieren? Wenn man dies nicht muss, sollte man es?
-
Hi,
ich weiß es nicht.
*push*
Vor allem das mit den Sockets interessiert mich jetzt doch, mir wurde gesagt, der Server könne fast genauso performant auch mit select() arbeiten! (ohne Multithreading)
ChrisM
-
malfunction schrieb:
Wo wir gerade beim Senden von Dateien via Windows Sockets sind: Kann man da wirklich eine grosse Datei mit einem einzigen send() verschicken? Oder muss man die Datei manuell fragmentieren? Wenn man dies nicht muss, sollte man es?
Meine Versuche mit den MFC Socket haben ergeben, dass der Sendbuffer ca. 38 Kilobyte groß ist. Oder auch nicht. Der kann auch kleiner sein. Oder größer. Ist undefiniert.
Die Daten kommen perfekt an, jedoch ist nicht garantiert ob die Pakete unterwegs aufgestückelt werden. Jedoch sind Pakete mit ca. 1KB höchst selten zerstückelt (read: nie).
Beantwortet das deine Fragen? (wer lesen kann ist klar im Vorteil :p)
ChrisM:
Was wolltest du nochmal wissen?Achso, Select vs. Multithreading
Ich habe mit select noch nicht wirklich viel gemacht, aber wenn es darauf hinausläuft dass du in einer while (1) Schleife regelmäßig den Status abfragst ("pollst") ist es im allgemeinen schlechter als nen Thread zu starten.
Wenn du magst kann ich dir nen Artikel über performante Webserver geben (). War vor ein paar Wochen auf /. . Der ist zwar für (posix) Linux/*BSD, aber ich denke ein paar nützliche Sachen kann man da schon für niedere Betriebssysteme rausziehen
-
Hi,
ja, der Artikel würde mich wirklich sehr interessieren!
ChrisM
-
Hi,
*push*
ChrisM
-
Hi,
so, ich habe den Artikel von Headhunter jetzt erhalten, aber dort geht es um Webserver, die zigtausende von Clients gleichzeitig handlen sollen.
Das will ich natürlich nicht, und mich würde nur interessieren, ob ich mit select() die Performance genauso gut hinkriege wie mit einem Thread für jeden Client.
ChrisM
-
Hi,
*push*
ChrisM
-
Hi,
und mich würde nur interessieren, ob ich mit select() die Performance genauso gut hinkriege wie mit einem Thread für jeden Client.
bitte, ich bin wirklich kein fauler Programmierer, der jede Arbeit abgenommen haben will und ich hab auch schon viele Tutorials gelesen und gesucht, aber dazu kaum brauchbare Informationen gefunden.
ChrisM