| Autor |
Beitrag |
O'rallY
      
Beiträge: 563
|
Verfasst: Mi 30.10.02 21:27
Ok, auch gut! Dann weißt du jetzt, dass du nen Namensvetter hast (<- nennt man doch so?) :mrgeen:
_________________ .oO'rallY
Linux is like a tipi: No gates, no windows and a gnu-eating apache inside...
|
|
alexschultze 
      
Beiträge: 317
|
Verfasst: Di 05.11.02 16:02
also, folgendes:
ich habe jetzt experimentiert und experimentiert, und wenn jetzt der Server aus ist oder der Port nicht stimmt, kommt immer der Ausnahmefehler 'Asynchroner Socketfehler 10061'.
Ich will nett unbedingt das die Benutzer das sehen, sondern eher 'Fehler beim Zugriff'.
Was soll ich tun? 
|
|
O'rallY
      
Beiträge: 563
|
Verfasst: Mi 06.11.02 15:15
Guck mal in meinen FAQ-Eintrag über Fehlerbehandlung oder nutze einfach das OnError-Event, um den Fehler abzufangen:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TForm1.ClientSocket1OnError(..., ErrorCode: integer); begin
case ErrorCode of 10062: ShowMessage('Verbindung fehlgeschlagen!"); end;
Abort;
end; |
_________________ .oO'rallY
Linux is like a tipi: No gates, no windows and a gnu-eating apache inside...
Zuletzt bearbeitet von O'rallY am Mi 06.11.02 17:22, insgesamt 1-mal bearbeitet
|
|
alexschultze 
      
Beiträge: 317
|
Verfasst: Mi 06.11.02 15:49
danke! ich hab schon kurz mit onerrorevent rumgespielt aber immer so ein abort vergessen.
Danke!!!!! 
|
|
ebi
      
Beiträge: 23
|
Verfasst: Mi 13.11.02 17:08
Schaut bitte mal in www.auq.de/viewtopic.php?p=19754#19754...
Es geht um OnError.
Thx
_________________ Greetings EBI
|
|
alexschultze 
      
Beiträge: 317
|
Verfasst: Sa 23.11.02 12:57
ehm, ich hab hier noch ein Problem mit Records. Wenn ich
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| var a:integer; MyRecord: TMyRecord;
begin
type TMyRecord = record s1, s2: string; i1, i2, i3: integer; end;
Clientsocket1.Socket.SendBuf(MyRecord, SizeOf(TMyRecord)); |
versuche, meckert er, das er TMyRecord nicht kennt. Was tun?!!?
|
|
ebi
      
Beiträge: 23
|
Verfasst: Sa 23.11.02 13:43
Ganz einfach!!
Du mußt erst den TMyRecord definieren und dann kannst du erst mit einer Variable drauf zugreifen.
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| type TMyRecord = record s1, s2: string; i1, i2, i3: integer; end;
[...]
var a:integer; MyRecord: TMyRecord; |
Soo einfach! 
_________________ Greetings EBI
|
|
alexschultze 
      
Beiträge: 317
|
Verfasst: Sa 23.11.02 14:16
ehm, noch ein kleines Problem:
ich sende immer in einem Zuge:
Quelltext 1: 2: 3:
| Clientsocket1.Socket.SendText('Daten');
Clientsocket1.Socket.SendBuf(MyRecord, SizeOf(TMyRecord)); |
Nun kann ich das ganze empfangen, beim Server kommt dann immer bei ReceiveText
Daten,]E
D.h. also er hat beide Pakete in eines zusammengepresst. Kann ich jetzt einfach die ersten 5 Buchstaben (alswie den Text) aus dem ReceiveBuf wieder rauslöschen? (sonst krieg ich den Record ja nicht wieder hin)
|
|
ebi
      
Beiträge: 23
|
Verfasst: Sa 23.11.02 21:27
Ne, das geht nicht
du mußt schon vorgeben, was empfangen werden soll, d.h. ein RECORD!!!
Schreibe doch in den Record, dass das Daten sind!
Und schicke nur einen RECORD!!!!
Viel Spass noch
_________________ Greetings EBI
|
|
alexschultze 
      
Beiträge: 317
|
Verfasst: Sa 23.11.02 23:20
Titel: Eh eh eh
ehm?
Du willst mir damit sagen dass mein Programm ausschließlich Records verwenden soll, oder das, wenn ein Record gesendet wird, ein String vorhanden ist = 'Daten', und mein Empfänger, egal ob es ein String oder ein Record ist, versucht dieses String aus dem Record zu lesen, und wenn der String ='Daten' das ganze als Record behandeln?
Was nun?
|
|
Savage
      
Beiträge: 110
|
Verfasst: So 24.11.02 11:48
Hi,
verwende einfach 2 Datenkanäle, den einen für Befehle und den anderen für deine Records, damit verhinderst du auf jedemfall, dass sich verschiedene Daten zusammenschließen. Dadurch lassen sich deine Daten dann besser "steuern".
MfG
Savage
|
|
alexschultze 
      
Beiträge: 317
|
Verfasst: So 24.11.02 12:02
das kann ich doch nieeee koordinieren!
|
|
Savage
      
Beiträge: 110
|
Verfasst: So 24.11.02 12:23
hmm, dann darfst du die 2 Daten nicht hintereinander senden sondern getrennt.
z.B.
Du sendest zuerst den String 'Daten', der Empfänger empfängt diesen String, bereitet sich auf die Daten vor und sendet zB ein 'DatenOK' zurück, nachdem du diesen String wieder empfangen hast, sendest du erst den Record rüber. Es entsteht also eine nette kleine Kommunikation. Die Datenkommunikation bei SMTP Servern oder POP Servern ist ähnlich aufgebaut.
Savage
|
|
alexschultze 
      
Beiträge: 317
|
Verfasst: So 24.11.02 12:46
aber bei 100 Clienten ist das recht schwer zu koordinieren (dann immer die richtigen Daten zu senden). Ich schreib hier mal ein Programm das ich gefunden habe. Es sendet einen Screenshot, und zwar mit nur EINER Prozedur:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ScktComp;
type TForm1 = class(TForm) Image1: TImage; Button2: TButton; ServerSocket1: TServerSocket; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button2Click(Sender: TObject); procedure ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket); procedure ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); private { Private-Deklarationen } FBitmap: TBitmap; public { Public-Deklarationen } end;
var Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject); begin FBitmap := TBitmap.Create; FBitmap.Width := 800; FBitmap.Height := 600; FBitmap.PixelFormat := pf8bit; end;
procedure TForm1.FormDestroy(Sender: TObject); begin FBitmap.Free; end;
procedure TForm1.Button2Click(Sender: TObject); var dc: hdc; dx, dy: integer; i: integer; FStream: TMemoryStream; Buf: Pointer; begin dc := CreateDC('DISPLAY', Nil, Nil, Nil); dx := screen.Width; dy := screen.Height; BitBlt(FBitmap.Canvas.Handle, 0, 0, dx, dy, DC, 0, 0, SRCCopy); deletedc(dc); Image1.Picture.Assign(FBitmap); FStream := TMemoryStream.Create; FBitmap.SaveToStream(FStream); Buf := FStream.Memory; with ServerSocket1.Socket do begin for i := 0 to ActiveConnections - 1 do begin Connections[i].SendText('Daten' + IntToStr(FStream.Size)); Connections[i].SendBuf(Buf^, FStream.Size); end; {for i := 0 to ActiveConnections do} end; {with ServerSocket1.Socket do} end;
procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin Caption := 'Server ' + IntToStr(ServerSocket1.Socket.ActiveConnections); end;
procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin Caption := 'Server ' + IntToStr(ServerSocket1.Socket.ActiveConnections - 1); end;
end. |
Connections[i].SendText('Daten'
+ IntToStr(FStream.Size));
Connections[i].SendBuf(Buf^, FStream.Size); in einer Prozedur:
und der andere:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ScktComp, ExtCtrls, StdCtrls, Menus;
type TForm1 = class(TForm) Image1: TImage; ClientSocket1: TClientSocket; MainMenu1: TMainMenu; Connect1: TMenuItem; Disconnect1: TMenuItem; procedure ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Connect1Click(Sender: TObject); procedure Disconnect1Click(Sender: TObject); private { Private-Deklarationen } FStream: TMemoryStream; FPos: integer; FSize: integer; FDaten: boolean; public { Public-Deklarationen } end;
var Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket); begin Caption := 'Verbunden'; end;
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); var a: array[0..4096] of Byte; Buf: Pointer; i: integer; s: string; begin if FDaten = false then begin s := Socket.ReceiveText; if Copy(s, 1, 5) = 'Daten' then begin Delete(s, 1, 5); try FSize := StrToInt(s); FDaten := true; Image1.Picture.Bitmap := nil; FStream.Clear; except
end; end; {if Copy(s, 1, 5) = 'Daten' then} end {if FDaten = false then} else begin Buf := @a; i := Socket.ReceiveBuf(Buf^, 4096); FStream.Write(Buf^, i); FPos := FPos + i; if FPos >= FSize then begin FDaten := false; FStream.Position := 0; FPos := 0; Image1.Picture.Bitmap.LoadFromStream(FStream); end; end; {else FDaten = false then} end; {procedure TForm1.ClientSocket1Read}
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin ClientSocket1.Close; end;
procedure TForm1.FormCreate(Sender: TObject); begin FStream := TMemoryStream.Create; end;
procedure TForm1.FormDestroy(Sender: TObject); begin FStream.Free; end;
procedure TForm1.Connect1Click(Sender: TObject); var s: string; begin if InputQuery('Server', 'Host-Name', s) = true then begin ClientSocket1.Host := s; ClientSocket1.Open; end; end;
procedure TForm1.Disconnect1Click(Sender: TObject); begin ClientSocket1.Close; end;
end. |
Empfangen mit einer Prozedur mit einem mal.
Ich blicke hier nur nicht ganz durch:
Er sendet zwei Sachen auf einmal, kriegt die wieder auseinander.. ??
|
|
alexschultze 
      
Beiträge: 317
|
Verfasst: So 01.12.02 19:30
antwortet mal 
|
|
Savage
      
Beiträge: 110
|
Verfasst: So 01.12.02 20:28
nun ja,
den Source, den du gepostet hast, funktioniert im Prinzip so:
Sender:
sendet mit einen Rutsch den String 'Daten' + Größe der File
also z.B. "Daten234534' und gleich danach als Buffer die File bzw. Nutzlast.
Empfänger:
Und hier aber meines erachtens das gleiche Problem wie bei dir. Der Empfänger geht davon aus, dass der String und die Nutzlast getrennt ankommen. Das Sieht man an der If Klausel, die heist:
IF FDaten = false then {nach String 'Daten' prüfen,...} else {Nutzlast empfangen und schreiben}
Und jetzt kann es meines erachtens wieder je nach Netzwerkspeed zu fehlern kommen. Es dürfte als keine wirkliche alternative sein. Ich lass mich jedoch gern eines besseren belehren.
Mein Vorschalg:
Dein Sendevorgang wird immer mit einen bestimmten String angekündigt.
Deshalb kannst du ja mal folgendes versuchen: Definiere einen bestimmten Bereich mit z.B. der Länge 10 Byte (10 Zeichen für deine Befehlsstring müsste reichen). Danach schreibst du diesen Bereich VOR deinen Record (wenn du als einen Stream zum senden verwenden solltest, dann schreib zuerst in den Stream die 10 Zeichen und danach die Nutzlast, und dann sende den STream.
Der Empfänger empfäng die Daten und schneidet von diesen Paket die ersten 10 Zeichen ab, wertet diese aus und bearbeitet den rest nach deinen Wünschen weiter.
Mehr fällt mir dazu leider nicht ein.
MFG
Savage
|
|
alexschultze 
      
Beiträge: 317
|
Verfasst: So 01.12.02 20:35
Genau diese Idee hatte ich auch!!!!
Ich wusste nur nicht wie ich dann beim Empfänger beim Paket den Anfang (die 10 Byte) wegschneiden und dann immer noch das Paket weiterverwenden kann!
|
|
Savage
      
Beiträge: 110
|
Verfasst: So 01.12.02 20:45
hm,
schreib den gesamten empfangenen Buffer in einen TMemorystream,
lies z.B. die ersten 10 Byte aus und speichere diese in einen String --> wegen weiterer Auswertung.
Danach würde ich den Memorystream auf Position 10 setzten und den Rest (memorystream.size-10) so speichern, wie ich ihn brauch. Wenn es ne File werden soll, dann
z.B filestream.copyfrom(memorystream,memorystream.size-10)
So in etwa würd ich es machen, viel Glück!
Mfg
Savage
|
|
alexschultze 
      
Beiträge: 317
|
Verfasst: Mo 02.12.02 14:12
|
|
alexschultze 
      
Beiträge: 317
|
Verfasst: Fr 06.12.02 22:02
also,
ich habe folgendes vor:
Ich schicke Text 'Record' plus gleich den Record der hinterher kommt.
WIe lese ich den Record ohne die ersten 6 Zeichen wieder aus?
Meine erfolglosen Versuche (hab schon mehr oder weniger rumgemanscht *g*)
Zitat:
Memo ist ein TmemoryStream
Record selbstklärend der Zielrecord.
Quelltext 1: 2: 3:
| socket.ReceiveBuf(memo, sizeof(TMemoryStream)); //memo.copyfrom(,memorystream.size-6) memo.write(RecRecord, SizeOf(TMyRecord)); |
Alles mehr oder weniger erfolglos.
Ob man über einen weiteren Buffer, ein MemoryStream geht oder sonstwas ist egal, hauptsache der Record kommt wieder
Wie mach ich das ?
|
|
|