Jeg ved der er mange der har spurgt om dette før men jeg forsøger mig nu engang også:
Jeg har i lang tid forsøgt at lave en chat i delphi. Den skal køre på sockets, med IP som det fængende, altså det der afgør hvem du sender til.
Derfor har jeg fundet denne artikel: http://delphi.about.com/library/weekly/aa112602a.htm
Det så ud til at virke i starten og jeg var lykkelig lige indtil man kører en client og en server på hver sin computer. Og så har jeg omskrevet koden sådan at man indtaster sin ip og trykker på en knap som så connecter til IP'en. Men når jeg gør det, så kommer den ene kun igennem (den på den anden computer)Han kan fint skrive og connecte mens clienten på min egen først tager lang tid om at loade og så hvis man skriver noget og sender med et tryk på en knap; skriver den følgende:
Asynchronus Socket Error!! Error no. 10060 has accuired. Jeg er ikke helt sikker på nummeret men resten passer.
PLEASE HJÆLP!! Jeg vil gerne have hjælp til at løse det her eller en helt ny kode.
// Kasper
»http://kaspertech.dk
PS: Min egen kode er så godt som den samme der er at finde på http://delphi.about.com/library/weekly/aa112602a.htm bare med de få ovenstående ændringer.
Hej Kasper,
Fejl 10060 får du når TClientSocket ikke kan få fat i den angivne IP + Port.
Den måde som eksemplet demonstrere brugen af TClientSocket/TServerSocket tager ikke højde for om serveren er startet op eller ej så derfor vil du få en exception hvis serveren ikke er startet.
Prøv at starte din klient/server i følgende rækkefølge:
1. Start Server og sæt den i "listen" mode (Active := True).
2 Start Klienten og angiv serverens IP.
Nu skulle du gerne kunne sende fra klient til server og omvendt.
HUSK!
Du skal ikke angive IP på serveren, da den får/opretter en forbindelse til klienten automatisk når klienten har connect'et.
Jeg har lavet 2 programmer Klient og Server som du kan prøve at bruge/bygge videre på:
Prøv evt. at bruge flere klienter samtidig...
KlientMain.dfm
object Form1: TForm1
Left = 192
Top = 107
BorderStyle = bsSingle
Caption = 'Klient - Disconnected'
ClientHeight = 239
ClientWidth = 274
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 8
Top = 0
Width = 47
Height = 13
Caption = 'Server IP:'
end
object Label2: TLabel
Left = 160
Top = 0
Width = 22
Height = 13
Caption = 'Port:'
end
object Edit1: TEdit
Left = 8
Top = 208
Width = 185
Height = 21
TabOrder = 0
end
object Memo1: TMemo
Left = 8
Top = 48
Width = 257
Height = 145
ScrollBars = ssVertical
TabOrder = 1
end
object Edit2: TEdit
Left = 8
Top = 16
Width = 145
Height = 21
TabOrder = 2
Text = '127.0.0.1'
end
object Button1: TButton
Left = 200
Top = 208
Width = 65
Height = 25
Caption = 'Send'
Enabled = False
TabOrder = 3
OnClick = Button1Click
end
object Button2: TButton
Left = 200
Top = 16
Width = 65
Height = 25
Caption = 'Connect'
TabOrder = 4
OnClick = Button2Click
end
object Edit3: TEdit
Left = 160
Top = 16
Width = 33
Height = 21
TabOrder = 5
Text = '23'
end
object ClientSocket1: TClientSocket
Active = False
ClientType = ctNonBlocking
Port = 0
OnConnect = ClientSocket1Connect
OnDisconnect = ClientSocket1Disconnect
OnRead = ClientSocket1Read
OnError = ClientSocket1Error
Left = 208
Top = 64
end
end
KlientMain.pas
unit KlientMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp;
type
TForm1 = class(TForm)
ClientSocket1: TClientSocket;
Edit1: TEdit;
Memo1: TMemo;
Edit2: TEdit;
Label1: TLabel;
Button1: TButton;
Button2: TButton;
Edit3: TEdit;
Label2: TLabel;
procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure Button2Click(Sender: TObject);
procedure ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Disconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
ErrorCode := 0; // her sørger vi for at der ikke bliver smidt en exception
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if (ClientSocket1.Active) then
begin
ClientSocket1.Active := False;
end
else
begin
ClientSocket1.Host := Edit2.Text;
ClientSocket1.Port := StrToInt(Edit3.Text);
ClientSocket1.Active := True;
end;
TButton(Sender).Enabled := False;
end;
procedure TForm1.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Button2.Caption := 'Disconnect';
Button2.Enabled := True;
Button1.Enabled := True;
Edit1.Enabled := True;
Form1.Caption := 'Klient - Connected';
end;
procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Button2.Caption := 'Connect';
Button2.Enabled := True;
Button1.Enabled := False;
Edit1.Enabled := False;
Form1.Caption := 'Klient - Discnnected';
end;
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1.Lines.Add(Socket.ReceiveText);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ClientSocket1.Socket.SendText(Edit1.Text);
Memo1.Lines.Add('Mig selv: '+Edit1.Text);
end;
end.
ServerMain.dfm
object Form1: TForm1
Left = 192
Top = 107
Width = 265
Height = 300
Caption = 'Server - Stopped'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 8
Top = 0
Width = 22
Height = 13
Caption = 'Port:'
end
object Edit1: TEdit
Left = 8
Top = 16
Width = 41
Height = 21
TabOrder = 0
Text = '23'
end
object Memo1: TMemo
Left = 8
Top = 40
Width = 241
Height = 193
ScrollBars = ssVertical
TabOrder = 1
end
object Edit2: TEdit
Left = 8
Top = 240
Width = 193
Height = 21
TabOrder = 2
end
object Button1: TButton
Left = 208
Top = 240
Width = 41
Height = 25
Caption = 'Send'
TabOrder = 3
OnClick = Button1Click
end
object Button2: TButton
Left = 56
Top = 16
Width = 65
Height = 21
Caption = 'Start server'
TabOrder = 4
OnClick = Button2Click
end
object ServerSocket1: TServerSocket
Active = False
Port = 0
ServerType = stNonBlocking
OnListen = ServerSocket1Listen
OnClientRead = ServerSocket1ClientRead
OnClientError = ServerSocket1ClientError
Left = 224
Top = 8
end
end
ServerMain.pas
unit ServerMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp;
type
TForm1 = class(TForm)
ServerSocket1: TServerSocket;
Label1: TLabel;
Edit1: TEdit;
Memo1: TMemo;
Edit2: TEdit;
Button1: TButton;
Button2: TButton;
procedure Button2Click(Sender: TObject);
procedure ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1Listen(Sender: TObject;
Socket: TCustomWinSocket);
procedure Button1Click(Sender: TObject);
private
procedure SendMessageToClients(Msg : String; AFromSocket: TCustomWinSocket = nil);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject);
begin
if (ServerSocket1.Active = False) then
ServerSocket1.Port := StrToInt(Edit1.Text)
else
begin
Caption := 'Server - Stopped';
Button2.Caption := 'Start server';
Button1.Enabled := False;
Edit2.Enabled := False;
end;
ServerSocket1.Active := not ServerSocket1.Active;
end;
procedure TForm1.ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
ErrorCode := 0;
end;
procedure TForm1.SendMessageToClients(Msg : String; AFromSocket: TCustomWinSocket = nil);
var
I : Integer;
begin
if AFromSocket = nil then
Msg := 'Server wrote :'+Msg
else
Msg := AFromSocket.RemoteAddress+' wrote: '+Msg;
Memo1.Lines.Add(Msg);
for I := 0 to ServerSocket1.Socket.ActiveConnections-1 do
begin
if (ServerSocket1.Socket.Connections[I] <> AFromSocket) then
ServerSocket1.Socket.Connections[I].SendText(Msg);
end;
end;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
Msg : String;
begin
Msg := Socket.ReceiveText;
SendMessageToClients(Msg, Socket);
end;
procedure TForm1.ServerSocket1Listen(Sender: TObject;
Socket: TCustomWinSocket);
begin
Caption := 'Server - Running';
Button2.Caption := 'Stop server';
Button1.Enabled := True;
Edit2.Enabled := True;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SendMessageToClients(Edit2.Text, nil);
end;
end.
Prøv at kig på koden og har du spørgsmål, så fyr løs.
God fornøjelse,
/Michael.