Autor Beitrag
MaltiMartin
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Fr 14.01.05 17:17 
Hallo,

mal wieder eine exotische Frage.
Habe hier zwei Anwendungen, einen Server und einen Clienten, realisiert mit ServerSocket und Clientsocket. An dem Server dürfen sich maximal vier Clienten andocken, der Server merkt sich von jedem Clienten die IP, den Hostnamen und einen mit SendText übertragenen Eigennamen. Soweit alles in Ordnung.

Jetzt aber mein Problem:
Wenn ein Client an den Server eine Meldung schickt, soll der Server diese Meldung an die anderen Clienten weiterschicken. Ich kann dann bei den Connections abfragen, welche IP eine Connection hat, aber: Den Eigennamen kriege ich dann ja nicht raus. Da nützt es mir auch nichts, daß ich mir den Eigennamen gemerkt habe.

z.B.
Client1:
IP: 127.0.0.1
Host: localhost
Eigenname: Ich

Client2:
IP: 127.0.0.1
Host: localhost
Eigenname: Ich2

Wie finde ich raus, welche Connection zu welchem Clienten führt, wenn mehrere Clienten die gleiche IP und den gleichen Hostnamen haben?

Mir die ursprüngliche Connectionnummer zu merken, bringt mir ja nix, da bei einem Abmelden eines Clienten das sich ja wieder ändern kann.

Wird nicht irgendwo für eine Session eine eindeutige Nummer vergeben oder so???

Ach ja, benutze Delphi 6.0 mit den TServerSocket und TClientSocket.

Gruß, Martin
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Fr 14.01.05 18:33 
das wollte ich auch gerade fragen :lol: :D
WeBsPaCe
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 2322
Erhaltene Danke: 1

FireFox 3, Internet Explorer 6 SP1
D1, D3Prof, D6Pers, D7Pers+Indy, VisualStudio Express
BeitragVerfasst: Fr 14.01.05 19:32 
Was hat denn das für einen Sinn, den Client auf einem PC mehrmals zu starten?? :D

Zu deiner Frage: Ich nehm mal an, dass es dann nich um besonders sensible Daten geht, wenn du auf Localhost arbeitest, also kannst du die Messages an alle Clients schicken, jedoch noch ein "Eigenname//" davorhängen. Dann überprüft jeder Client, ob er der Eigenname ist, wenn ja trennt er das "Eigenname//" vom Text und gibt den Text aus.

Zum Trennen von den Strings: www.delphi-forum.de/...34636&highlight=

Er teilt das dann zwar in mehrere Teil, wenn ein "//" in der Message vorkommt, aber das ist ja kein Problem. Sollten es mehrere Teile sein, dann fügst du sie einfach wieder zusammen. :D

War das so ungefähr was du wolltest?? :roll:

_________________
Steht der Bauer im Gemüse, hat er später grüne Füße.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10184
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Sa 15.01.05 09:28 
Moin!

@WeBsPaCe: positiv: du denkst wengistens manchmal nach; negativ: nicht genug... :wink: (nicht böse gemeint, wir kennen uns ja schon :) )

@MaltiMartin:
Die Lösung deines Problems steckt doch in den entsprechenden Ereignisprozeduren drin: der Socket (TCustomWinSocket) Parameter. Du könntest z.B. folgendes tun, um deine Clients auf der Serverseite auseinander zu halten:

Du machst eine StringListe auf, in die Strings tust du die Nick-Names (deines Chats? :) ), in die Objects den Socket-Parameter (der ja praktisch die Session darstellt). Wenn du nun von einem Client ein Datenpaket erhälst, dann gehst du einfach in einer Schleife die Stringliste durch und sendest an alle, bis auf den ursprünglichen Sender, auch das Paket. Den ursprünglichen Sender erkennst du an dem gespeicherten Socket-Object. Fertig.

Klar, du mußt natürlich die StringListe, die deine "Sessions" (als Socket-Parameter) speichert, aktuell halten und dazu auf die entsprechenden Ereignisse reagieren (OnConnect, OnDisconnect, etc).

cu
Narses
WeBsPaCe
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 2322
Erhaltene Danke: 1

FireFox 3, Internet Explorer 6 SP1
D1, D3Prof, D6Pers, D7Pers+Indy, VisualStudio Express
BeitragVerfasst: Sa 15.01.05 12:39 
Narses hat folgendes geschrieben:
@WeBsPaCe: positiv: du denkst wengistens manchmal nach; negativ: nicht genug... :wink: (nicht böse gemeint, wir kennen uns ja schon :) )

*g* Danke!! :D

Ich werd das auch mal versuchen umzusetzten, wenn ich Zeit finde. Dann poste ich's mal... :D

_________________
Steht der Bauer im Gemüse, hat er später grüne Füße.
MaltiMartin Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Sa 15.01.05 14:03 
ARGHHL...danke, Narses. Deine Idee ist so genial und einfach, daß ich mir in den A..... beißen könnte, daß ich nicht selber drauf gekommen bin...war mal wieder so blöd, daß ich ca. 8 Stunden lang einen Work-Around programmiert habe, und zwar auch in dem Stil, wie WebSpace ihn vorgeschlagen hat...schon faszinierend, daß mehrere Leute die gleichen Gedankengänge haben...

Werde das gleich mal in die Tat umsetzen...

Gruß, Martin
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Sa 15.01.05 16:37 
habe auch einen chat gemacht, nun möchte ich aber dass mehrere chatten können also einer schickt die nachricht an den server und der server schickt sie dann an alle anderen aber wie mache ich das ?

ausblenden volle Höhe Delphi-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:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
unit RMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Menus, ScktComp, mmsystem, shellapi, ComCtrls;

type
  TForm1 = class(TForm)
    Memo2: TMemo;
    Edit1: TEdit;
    Button1: TButton;
    MainMenu1: TMainMenu;
    Verbindung1: TMenuItem;
    Verbinden1: TMenuItem;
    Unterbrechen1: TMenuItem;
    N1: TMenuItem;
    Beenden1: TMenuItem;
    ClientSocket1: TClientSocket;
    ServerSocket1: TServerSocket;
    ChatLog1: TMenuItem;
    DieseSessionaufzeichnen1: TMenuItem;
    N2: TMenuItem;
    DiesenPCalsServerbenutzen1: TMenuItem;
    Optionen1: TMenuItem;
    Schrift1: TMenuItem;
    FontDialog1: TFontDialog;
    RichEdit1: TRichEdit;
    procedure Memo2KeyPress(Sender: TObject; var Key: Char);
    procedure ServerSocket1Accept(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Connect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Disconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
      ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
    procedure Verbinden1Click(Sender: TObject);
    procedure Beenden1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Edit1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure Unterbrechen1Click(Sender: TObject);
    procedure DieseSessionaufzeichnen1Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure DiesenPCalsServerbenutzen1Click(Sender: TObject);
    procedure ServerSocket1ClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure FormShow(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ServerSocket1ClientDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure Schrift1Click(Sender: TObject);
    procedure RichEdit1KeyPress(Sender: TObject; var Key: Char);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  protected
  isserver:boolean;
  end;

var
  Form1: TForm1;
  Server, Nick: String;
  recordS: boolean;

  implementation

{$R *.dfm}
{$R sounds.res}

procedure TForm1.Memo2KeyPress(Sender: TObject; var Key: Char);
begin
key:= #0;
end;

procedure TForm1.ServerSocket1Accept(Sender: TObject;
  Socket: TCustomWinSocket);
begin
IsServer := True;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
begin
richedit1.lines.add('');
richedit1.Lines.Add(Socket.ReceiveText);
PlaySound('newmessage',HInstance, snd_ASync or snd_Memory or snd_Resource);
end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
ClientSocket1.Socket.SendText('*** ' + nick + ' ist auf dem Server ! ***');
memo2.text := 'Verbunden mit: ' + Socket.RemoteHost;
end;

procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
memo2.text := 'Verbindung getrennt!';
end;

procedure TForm1.ClientSocket1Error(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
Memo2.text := 'Fehler beim Verbinden mit: ' + Server;
ErrorCode := 0;
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
begin
richedit1.lines.add('');
richedit1.Lines.Add(Socket.ReceiveText);
PlaySound('newmessage',HInstance, snd_ASync or snd_Memory or snd_Resource);
end;

procedure TForm1.Verbinden1Click(Sender: TObject);
begin
if ClientSocket1.Active then ClientSocket1.Active := False;
if InputQuery('Verbinden''Server-Addresse:', Server) then
if InputQuery('Benutzer''Benutzer-Name:', Nick) then
if Length(Server) > 0 then
if length(nick) <= 0 then nick := 'Gast';
with ClientSocket1 do
begin
Host := Server;
Active := True;
end;
end;

procedure TForm1.Beenden1Click(Sender: TObject);
begin
if recordS = true then richedit1.lines.SaveToFile('Chat.txt');
ServerSocket1.Close;
ClientSocket1.Close;
Close;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if length(nick) <= 0 then nick := 'Gast';
if edit1.Text <> '' then begin
if IsServer then
ServerSocket1.Socket.Connections[0].SendText(nick + ': ' + edit1.text)
else
ClientSocket1.Socket.SendText(nick + ': ' + edit1.text);
richedit1.lines.add('');
richedit1.lines.add(nick + ': ' + edit1.Text);
edit1.text:= '';
end;
end;

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
if length(nick) <= 0 then nick := 'Gast';
if Key = VK_Return then begin
if edit1.Text <> '' then begin
if IsServer then
ServerSocket1.Socket.Connections[0].SendText(nick + ': ' + edit1.text)
else
ClientSocket1.Socket.SendText(nick + ': ' + edit1.text);
richedit1.lines.add('');
richedit1.lines.add(nick + ': ' + edit1.Text);
edit1.text:= '';
end;
end;
end;

procedure TForm1.Unterbrechen1Click(Sender: TObject);
begin
ClientSocket1.Active := False;
ServerSocket1.Active := false;
memo2.text := 'Verbindung getrennt!';
end;

procedure TForm1.DieseSessionaufzeichnen1Click(Sender: TObject);
begin
DieseSessionaufzeichnen1.checked:= not DieseSessionaufzeichnen1.checked;
if DieseSessionaufzeichnen1.checked = true then
recordS:= true
else
recordS:= false;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
recordS:= MessageDlg('Möchten Sie die letzte Session speichern?', mtConfirmation, [mbYes,mbNo], 0) = mrYes;
if recordS = true then if recordS = true then richedit1.lines.SaveToFile('LastChat.txt');
end;

procedure TForm1.DiesenPCalsServerbenutzen1Click(Sender: TObject);
begin
DiesenPCalsServerbenutzen1.checked:= not DiesenPCalsServerbenutzen1.checked;
if DiesenPCalsServerbenutzen1.checked = true then begin
if length(nick) <= 0 then if InputQuery('Benutzer''Benutzer-Name:', Nick) then
if length(nick) <= 0 then nick := 'Gast';
isserver:= true;
serversocket1.active:= true;
memo2.text := 'Server erfolgreich erstellt!';
end else begin
isserver:= false;
serversocket1.active:= false;
memo2.text := 'Server heruntergefahren!';
end;
end;

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
ServerSocket1.Socket.Connections[0].SendText('*** Willkommen auf dem Chat42 Server von ' + nick + ' ! ***');
memo2.text := 'Verbunden mit: ' + Socket.RemoteAddress;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
edit1.SetFocus;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
SetBounds((Screen.Width - Width) div 2, (Screen.Height - Height) div 2, Width, Height);
RichEdit1.MaxLength:=MaxInt;
end;

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
memo2.text := 'Verbindung getrennt!';
end;

procedure TForm1.Schrift1Click(Sender: TObject);
begin
if fontdialog1.Execute then richedit1.Font:= fontdialog1.Font;
end;

procedure TForm1.RichEdit1KeyPress(Sender: TObject; var Key: Char);
begin
key:= #0;
end;

end.
MaltiMartin Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Sa 15.01.05 18:50 
Mach einfach in die ClientRead-Procedure ne for-schleife a la

for i:=0 to ServerSocket1.Socket.ActiveConnections-1
ServerSocket1.Socket.Connections[i].SendText(Socket.ReceiveText);

Ist wohl am einfachsten...
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Mo 17.01.05 18:27 
danke das hatte ich schon probiert aber man kann anscheinend nur einmal etwas mit dem receivetext machen danach wird er wieder verworfen also entweder an die clients senden oder anzeigen lassen, also hab ich den text in ne variable zwischengeladen und dann ging beides: DANKE !!! :lol: