Autor Beitrag
O'rallY
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 563



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 317



BeitragVerfasst: 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? :cry:
O'rallY
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 563



BeitragVerfasst: Mi 06.11.02 15:15 
Guck mal in meinen FAQ-Eintrag über Fehlerbehandlung oder nutze einfach das OnError-Event, um den Fehler abzufangen:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 317



BeitragVerfasst: Mi 06.11.02 15:49 
danke! ich hab schon kurz mit onerrorevent rumgespielt aber immer so ein abort vergessen.

Danke!!!!! :lol:
ebi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 23



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 317



BeitragVerfasst: Sa 23.11.02 12:57 
ehm, ich hab hier noch ein Problem mit Records. Wenn ich
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 23



BeitragVerfasst: Sa 23.11.02 13:43 
Ganz einfach!!

8)


Du mußt erst den TMyRecord definieren und dann kannst du erst mit einer Variable drauf zugreifen.

ausblenden 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! :wink:

_________________
Greetings EBI
alexschultze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 317



BeitragVerfasst: Sa 23.11.02 14:16 
ehm, noch ein kleines Problem:
ich sende immer in einem Zuge:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 23



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 317



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 110



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 317



BeitragVerfasst: So 24.11.02 12:02 
das kann ich doch nieeee koordinieren!
Savage
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 110



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 317



BeitragVerfasst: 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:

ausblenden volle Höhe Quelltext
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:

ausblenden volle Höhe Quelltext
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 317



BeitragVerfasst: So 01.12.02 19:30 
antwortet mal :(
Savage
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 110



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 317



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 110



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 317



BeitragVerfasst: Mo 02.12.02 14:12 
okay, klingt gut.
alexschultze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 317



BeitragVerfasst: 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.
ausblenden 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 ?