Sockets
Übersicht

![]() |
FirstdeathmakerBetreff: Sockets |
![]() Antworten mit Zitat ![]() |
---|---|---|
Kann mir jemand ein mini-Beispiel geben wie das mit den Sockets funktioniert?
Also einfach einen Server, der dann von einem Client eine Nachricht empfängt. Ich krieg einfach nirgendwo eine Info her wie das geht (Und auch das rumprobieren hat bisher nicht zum erfolg geführt). |
||
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon Gewinner des BCC #57 User posted image |
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Code: [AUSKLAPPEN] Local socket:TSocket = Null
Local tcp:TSocketStream = Null socket = CreateTCPSocket() If socket <> Null If BindSocket(socket, port) SocketListen(socket) 'Stream Objekt aus dem Socket erstellen tcp = CreateSocketStream(socket, True) EndIf EndIf Erst wird ein Socket erstellt, dieses wird für einen Server an den lokalen Port gebunden und wird dann in den Listening Modus versetzt. Aus dem Socket lässt sich dann ein Stream-Objekt erstellen. Mit dem kann man ganz normal die Read/Write Befehle wie bei BB benutzen: Code: [AUSKLAPPEN] WriteByte(tcp, 20)
Zum verbinden funktioniert es beinahe identisch, nur wird statt SocketListen() die Funktion ConnectSocket() verwendet. |
||
![]() |
Firstdeathmaker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Aha, vielen Dank! Fast soweit war ich auch schon mit meinen Überlegungen, nur fehlte mir das Wissen wie es mit dem Listen zu realisieren wäre, ob man das vielleicht eben jeden Schleifendurchgang abfragen müsste oder so, was ja nicht der Fall zu sein scheint. Nur jetzt ist ein Fehler aufgetaucht, den ich immer noch nicht zu lösen vermag. Ich hab nun einen Server und einen Client. Der Server wird zuerst gestartet und soll nun alles ausgeben was er empfängt. Damit er nicht zuviel Last zieht hab ich mal ein Delay 10 eingebaut. Nun starte ich den Client, welcher dem Server einen String schicken soll (Also eine einzige Zeile). Sobald ich den Client nun aber starte, bekommt der Server eine Fehlermeldung genau an der Stelle wo er die Nachricht printen müsste, in der Zeile
Zitat: Print ReadLine (tcp)
wo ich eine Unhandled Exception bekomme, also "Attempt to access field or method of Null object". Das komische ist jedoch, dass ich nirgentwo ein solches nicht verbundenes Objekt entdecken kann im Debugger. oder liegt es einfach daran, dass ich versuche vom Client aus eine Verbindung mit der Server auf dem gleichen PC herzustellen und man das nicht darf? Zum Nachvollziehen (und vielleicht testen), mein Code sieht folgendermaßen aus: Server Code: [AUSKLAPPEN] Local socket:TSocket = Null
Local tcp:TSocketStream = Null Local port:Int = 120 socket = CreateTCPSocket() If socket <> Null If BindSocket(socket, port) SocketListen(socket) 'Stream Objekt aus dem Socket erstellen tcp = CreateSocketStream(socket, True) EndIf EndIf Repeat If Eof(tcp) <> 0 Print ReadLine (tcp) EndIf Delay 10 Until KeyHit(KEY_ESCAPE) End Client Code: [AUSKLAPPEN] Local socket:TSocket = Null
Local tcp:TSocketStream = Null Local port:Int = 190 socket = CreateTCPSocket() If socket <> Null If BindSocket(socket, port) ConnectSocket(socket, ipint("127.0.0.1"), 120) 'Stream Objekt aus dem Socket erstellen tcp = CreateSocketStream(socket, True) EndIf Else Print "Could not create socket" EndIf WriteLine (tcp, "Hello") End Function ipint:Int(umwandeln$) Local teil1:Int = Int(Instr(umwandeln$,".")) Local teil2:Int = Int(Instr(umwandeln$,".",teil1+1)) Local teil3:Int = Int(Instr(umwandeln$,".",teil2+1)) Local temp1:Int = Int(Mid(umwandeln$,1,teil1-1)) Local temp2:Int = Int(Mid(umwandeln$,teil1+1,teil2-1)) Local temp3:Int = Int(Mid(umwandeln$,teil2+1,teil3-1)) Local temp4:Int = Int(Mid(umwandeln$,teil3+1)) zurueck:Int = (temp1 Shl 24) + (temp2 Shl 16) + (temp3 Shl 8) + temp4 Return zurueck End Function |
||
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon Gewinner des BCC #57 User posted image |
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Bin mir nicht mehr ganz sicher ob Bindsocket beim Client auch nötig ist. Wahrscheinlich sucht der sich automatisch einen lokalen Port. Aber ich glaube daran liegts nicht..
Versuch statt Eof(tcp) mal tcp.Socket().ReadAvail() > 0, vielleicht bringt das was. Oder evtl. hilft es das TCP Delay umzustellen: Code: [AUSKLAPPEN] socket = CreateTCPSocket()
If socket <> Null If BindSocket(socket, port) SocketListen(socket) socket.SetTCPNoDelay(True) <------------------ Hier 'Stream Objekt aus dem Socket erstellen tcp = CreateSocketStream(socket, True) EndIf EndIf Ansonsten weiss ich auch nicht.. vielleicht ist der Fehler auch im BMax Modul selber.. |
||
![]() |
Firstdeathmaker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Nee, hat leider alles nix gebracht. Aber trotzdem danke für deine Mühe!
Ich werd die Frage mal im englischen Board stellen, vielleicht wissen die ja eine Lösung... Edit: Hab da was gefunden http://www.blitzbasic.com/Comm...847#643388 |
||
![]() |
Firstdeathmaker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hab das ganze mal auseinandergefummelt, für alle die es interessiert ein kleines Beispiel:
Server Wichtig: Man hat einen Hauptsocket im Listen Modus, auf dem man nach Verbindungsanfragen lauscht. Wenn eine Anfrage kommt, wird diese mit einem NEUEN Socket verbunden und von dem aus wird ein Stream erstellt aus dem man die Daten auslesen kann. Komischerweise muss man in die Listenschleife wo nach neuen Connections gelauscht wird ein delay einbauen, sonst funktioniert das nicht (Jedenfalls nicht an einem PC, an zwei hab ich jetzt nicht getestet). Später braucht man nur noch auf den einen Stream den man erstellt hat zuzugreifen. Code: [AUSKLAPPEN] SuperStrict
Global MainSocket:TSocket = CreateTCPSocket() BindSocket(MainSocket, 666) SocketListen(MainSocket) Local receivesocket:TSocket Local IncomingStream:TStream Repeat receivesocket:TSocket = SocketAccept(MainSocket) IncomingStream:TStream = CreateSocketStream(receivesocket) Delay 10 Until receivesocket <> Null Print "Incoming..." Repeat If IncomingStream <> Null While Not Eof(IncomingStream) Local line:String = ReadLine(IncomingStream) If line <> "" Print line Wend EndIf Until KeyHit(KEY_ESCAPE) End Client Der Client hat einen anderen Knackpunkt an dem ich fast verzweifelt bin: Man darf nicht zu früh anfangen etwas in den Stream zu schreiben, sonst gehen die Daten darin verloren. Deshalb das delay 100 bevor ich etwas in den Stream schreibe. Danach ist aber alles in Ordnung. Vielleicht könnte man das auch eleganter lösen indem man Abfragen einbaut, ob die Connection schon soweit ist, aber damit werde ich mich erst später beschäftigen. Ich bin froh das es jetzt erstmal so läuft ![]() Falls jmd Verbesserungen hat, immer her damit! Code: [AUSKLAPPEN] SuperStrict
Global SendSocket:TSocket = CreateTCPSocket() Global SendStream:TStream = CreateSocketStream(SendSocket) ConnectSocket(SendSocket, HostIp("localhost"), 666) Delay 100 WriteLine SendStream, "Hallo" Delay 1000 WriteLine SendStream, "Zweiter Batzen" End |
||
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon Gewinner des BCC #57 User posted image |
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Achso, logisch ![]() Sorry hab nicht mehr daran gedacht, ist mir beim überfliegen deines Codes auch irgendwie nicht aufgefallen.. aber war bei TCP ja eigentlich schon immer so ![]() |
||
X0r |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich weiß, das Thema ist schon längst gegessen, aber bei mir muss das Programm nicht stoppen(Kein delay benutzen), damit die Daten ankommen.
Ist zwar fast der selbe code aber hier ist meiner: Server: Code: [AUSKLAPPEN] socket:Tsocket=CreateTCPSocket() BindSocket socket,0 SocketListen(socket) For Local ips=EachIn HostIps("") ip=ips Next Print ip Print SocketLocalPort(socket) Repeat receivesocket:TSocket = SocketAccept(socket) stream:TStream = CreateSocketStream(receivesocket) Until receivesocket <> Null Repeat If stream<>Null Then While Not Eof(stream) Local line:String = ReadLine(stream) If line<>"" Then Print line Wend EndIf Until KeyHit(1) CloseSocket(socket) Client Code: [AUSKLAPPEN] socket:Tsocket=CreateTCPSocket() stream=CreateSocketStream(socket) ConnectSocket(socket,ipint,port) WriteLine Stream, "Hallo" WriteLine Stream, "world!" CloseSocket(socket) Nachdem ihr Server gestartet habt, wird die IP als Integer Wert und der Port gezeigt. Dann startet das Client Programm und gibt bei ipint die zurückgegebene IP und bei port den zurückgebenen port ein. |
||
![]() |
Jolinah |
![]() Antworten mit Zitat ![]() |
---|---|---|
Das Delay war nicht da um auf Daten zu warten, sondern um die CPU- Auslastung zu mindern. Bei Delay wird der Prozess unterbrochen, so dass Windows etwas mehr Zeit hat noch andere Dinge zu erledigen und dein Programm nicht 100% die CPU auslastet ![]() |
||
X0r |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
>Der Client hat einen anderen Knackpunkt an dem ich fast verzweifelt bin: Man darf nicht zu früh anfangen etwas in den Stream zu schreiben, sonst gehen die Daten darin verloren. Deshalb das delay 100 bevor ich etwas in den Stream schreibe.
Und was sagst du dazu? du hattest FDM zugestimmt. Und selbst wenn es mit 100% so wäre, der müsste trotzdem senden. Und? Gibt es eine elegantere Lösung, um die Auslastung zu verhinden? Ich habs schon mit socketconnected und so versucht, hat irgendwie alles nichts gebracht. Und es ist schon komisch, dass man extra ein delay am Ende der Schleife setzen muss, damit das CPU nicht crashed. Ist zwar logisch, aber es muss doch eine bessere Lösung geben, oder? Denn langsamere Computer brauchen dann doch mehr Zeit, oder wie ist das mit TCP streams? |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group