我写了一个聊天程序,用的是Tserversocket和Tclientsocket。
但是无法接收到信息,调试发现Tserversocket的onclientread事件没有被触发。
望高手指点。
源代码如下:unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp;type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Edit1: TEdit;
cs: TClientSocket;
ss: TServerSocket;
Label1: TLabel;
Edit2: TEdit;
Label2: TLabel;
Edit3: TEdit;
Label3: TLabel;
Edit4: TEdit;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
begin
// if ss.Active then ss.Close;
// ss.Port :=strtoint(edit2.Text);
// ss.Open;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
if ss.Active then ss.Close;
ss.Port :=strtoint(edit2.Text);
ss.Open;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
if cs.Active then cs.Close;
cs.Host :=edit3.text;
cs.Port :=strtoint(edit4.Text);
cs.Open;
cs.Socket.SendText(edit1.Text);
cs.Close;
end;procedure TForm1.ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
var rec : string;
begin
rec:= Socket.ReceiveText;
memo1.Lines.Add(rec);
end;end.
窗体(dfm)文件:
object Form1: TForm1
Left = 192
Top = 140
Width = 523
Height = 255
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 384
Top = 8
Width = 52
Height = 13
Caption = 'local port :'
end
object Label2: TLabel
Left = 384
Top = 64
Width = 57
Height = 13
Caption = 'remote IP : '
end
object Label3: TLabel
Left = 384
Top = 120
Width = 59
Height = 13
Caption = 'remote port :'
end
object Memo1: TMemo
Left = 8
Top = 8
Width = 361
Height = 177
Lines.Strings = (
'Memo1')
TabOrder = 0
end
object Button1: TButton
Left = 296
Top = 192
Width = 75
Height = 25
Caption = 'send'
TabOrder = 1
OnClick = Button1Click
end
object Edit1: TEdit
Left = 8
Top = 192
Width = 281
Height = 21
TabOrder = 2
Text = 'Edit1'
end
object Edit2: TEdit
Left = 384
Top = 32
Width = 121
Height = 21
TabOrder = 3
Text = '5001'
end
object Edit3: TEdit
Left = 384
Top = 88
Width = 121
Height = 21
TabOrder = 4
Text = 'localhost'
end
object Edit4: TEdit
Left = 384
Top = 144
Width = 121
Height = 21
TabOrder = 5
Text = '5001'
end
object Button2: TButton
Left = 408
Top = 184
Width = 75
Height = 25
Caption = 'listen'
TabOrder = 6
OnClick = Button2Click
end
object cs: TClientSocket
Active = False
ClientType = ctNonBlocking
Host = 'localhost'
Port = 5001
Left = 96
Top = 72
end
object ss: TServerSocket
Active = False
Port = 5001
ServerType = stNonBlocking
OnClientRead = ssClientRead
Left = 136
Top = 72
end
end
但是无法接收到信息,调试发现Tserversocket的onclientread事件没有被触发。
望高手指点。
源代码如下:unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp;type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Edit1: TEdit;
cs: TClientSocket;
ss: TServerSocket;
Label1: TLabel;
Edit2: TEdit;
Label2: TLabel;
Edit3: TEdit;
Label3: TLabel;
Edit4: TEdit;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
begin
// if ss.Active then ss.Close;
// ss.Port :=strtoint(edit2.Text);
// ss.Open;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
if ss.Active then ss.Close;
ss.Port :=strtoint(edit2.Text);
ss.Open;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
if cs.Active then cs.Close;
cs.Host :=edit3.text;
cs.Port :=strtoint(edit4.Text);
cs.Open;
cs.Socket.SendText(edit1.Text);
cs.Close;
end;procedure TForm1.ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
var rec : string;
begin
rec:= Socket.ReceiveText;
memo1.Lines.Add(rec);
end;end.
窗体(dfm)文件:
object Form1: TForm1
Left = 192
Top = 140
Width = 523
Height = 255
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 384
Top = 8
Width = 52
Height = 13
Caption = 'local port :'
end
object Label2: TLabel
Left = 384
Top = 64
Width = 57
Height = 13
Caption = 'remote IP : '
end
object Label3: TLabel
Left = 384
Top = 120
Width = 59
Height = 13
Caption = 'remote port :'
end
object Memo1: TMemo
Left = 8
Top = 8
Width = 361
Height = 177
Lines.Strings = (
'Memo1')
TabOrder = 0
end
object Button1: TButton
Left = 296
Top = 192
Width = 75
Height = 25
Caption = 'send'
TabOrder = 1
OnClick = Button1Click
end
object Edit1: TEdit
Left = 8
Top = 192
Width = 281
Height = 21
TabOrder = 2
Text = 'Edit1'
end
object Edit2: TEdit
Left = 384
Top = 32
Width = 121
Height = 21
TabOrder = 3
Text = '5001'
end
object Edit3: TEdit
Left = 384
Top = 88
Width = 121
Height = 21
TabOrder = 4
Text = 'localhost'
end
object Edit4: TEdit
Left = 384
Top = 144
Width = 121
Height = 21
TabOrder = 5
Text = '5001'
end
object Button2: TButton
Left = 408
Top = 184
Width = 75
Height = 25
Caption = 'listen'
TabOrder = 6
OnClick = Button2Click
end
object cs: TClientSocket
Active = False
ClientType = ctNonBlocking
Host = 'localhost'
Port = 5001
Left = 96
Top = 72
end
object ss: TServerSocket
Active = False
Port = 5001
ServerType = stNonBlocking
OnClientRead = ssClientRead
Left = 136
Top = 72
end
end
现经调试发现不仅Tserversocket的onclientread事件没有被触发,而且Tclientsocket在执行了open方法后,active仍为false
-------------------------------------------------
改为机器名后一样不行
另外给你个建议,使用TCPCLIENT,TCPSERVER控件,这个比较好用。下面给你一个DEMO:
unit Chatmain;interfaceuses
Classes, QControls, QStdCtrls, QExtCtrls, QButtons, QForms, Sockets;
type
TForm1 = class(TForm)
memRecv: TMemo;
Panel1: TPanel;
memSend: TMemo;
Panel2: TPanel;
btnSend: TButton;
Panel3: TPanel;
Label1: TLabel;
edtRemoteHost: TEdit;
Label2: TLabel;
edtRemotePort: TEdit;
Label3: TLabel;
edtLocalPort: TEdit;
btnActivateServer: TButton;
TcpClient1: TTcpClient;
TcpServer1: TTcpServer;
procedure btnSendClick(Sender: TObject);
procedure TcpServer1Accept(sender: TObject;
ClientSocket: TCustomIpClient);
procedure btnActivateServerClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; // you must create your own thread to synch
// writing to a gui component
TClientDataThread = class(TThread)
private
public
ListBuffer :TStringList;
TargetList :TStrings;
procedure synchAddDataToControl;
constructor Create(CreateSuspended: Boolean);
procedure Execute; override;
procedure Terminate;
end;var
Form1: TForm1;
//DataThread: TClientDataThread;implementation{$R *.xfm}//------------- TClientDataThread impl -----------------------------------------
constructor TClientDataThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := true;
ListBuffer := TStringList.Create;
end;procedure TClientDataThread.Terminate;
begin
ListBuffer.Free;
inherited;
end;procedure TClientDataThread.Execute;
begin
Synchronize(synchAddDataToControl);
end;procedure TClientDataThread.synchAddDataToControl;
begin
TargetList.AddStrings(ListBuffer);
end;
//------------- end TClientDataThread impl -------------------------------------
procedure TForm1.btnActivateServerClick(Sender: TObject);
begin
TcpServer1.LocalPort := edtLocalPort.Text;
TcpServer1.Active := True;
end; procedure TForm1.btnSendClick(Sender: TObject);
var
I: Integer;
begin
TcpClient1.RemoteHost := edtRemoteHost.Text;
TcpClient1.RemotePort := edtRemotePort.Text;
try
if TcpClient1.Connect then
for I := 0 to memSend.Lines.Count - 1 do
TcpClient1.Sendln(memSend.Lines[I]);
finally
TcpClient1.Disconnect;
end;
end;procedure TForm1.TcpServer1Accept(sender: TObject;
ClientSocket: TCustomIpClient);
var
s: string;
DataThread: TClientDataThread;
begin
// create thread
DataThread:= TClientDataThread.Create(true);
// set the TagetList to the gui list that you
// with to synch with.
DataThread.TargetList := memRecv.lines; // Load the Threads ListBuffer
DataThread.ListBuffer.Add('*** Connection Accepted ***');
DataThread.ListBuffer.Add('Remote Host: ' + ClientSocket.LookupHostName(ClientSocket.RemoteHost) +
' (' + ClientSocket.RemoteHost + ')');
DataThread.ListBuffer.Add('===== Begin message =====');
s := ClientSocket.Receiveln;
while s <> '' do
begin
DataThread.ListBuffer.Add(s);
s := ClientSocket.Receiveln;
end;
DataThread.ListBuffer.Add('===== End of message ====='); // Call Resume which will execute and synch the
// ListBuffer with the TargetList
DataThread.Resume;end;end.
//FORM code:object Form1: TForm1
Left = 149
Top = 162
Width = 873
Height = 642
VertScrollBar.Range = 169
ActiveControl = memRecv
Caption = 'Net Chat'
Color = clButton
Font.Color = clText
Font.Height = 17
Font.Name = 'MS Sans Serif'
Font.Pitch = fpVariable
Font.Style = []
Font.Weight = 40
ParentFont = False
OnCreate = btnActivateServerClick
PixelsPerInch = 96
TextHeight = 20
TextWidth = 8
object memRecv: TMemo
Left = 0
Top = 61
Width = 873
Height = 473
Align = alClient
ReadOnly = True
ScrollBars = ssAutoVertical
TabOrder = 0
end
object Panel1: TPanel
Left = 0
Top = 534
Width = 873
Height = 108
Align = alBottom
BevelOuter = bvNone
TabOrder = 1
object memSend: TMemo
Left = 0
Top = 0
Width = 773
Height = 108
Align = alClient
ScrollBars = ssAutoVertical
TabOrder = 0
end
object Panel2: TPanel
Left = 773
Top = 0
Width = 100
Height = 108
Align = alRight
BevelOuter = bvNone
ParentColor = True
TabOrder = 1
object btnSend: TButton
Left = 9
Top = 9
Width = 88
Height = 94
Caption = 'Send'
TabOrder = 0
OnClick = btnSendClick
end
end
end
object Panel3: TPanel
Left = 0
Top = 0
Width = 873
Height = 61
Align = alTop
TabOrder = 2
object Label1: TLabel
Left = 34
Top = 23
Width = 99
Height = 20
Caption = 'Remote Host:'
Layout = tlCenter
end
object Label2: TLabel
Left = 256
Top = 23
Width = 94
Height = 20
Caption = 'Remote Port:'
Layout = tlCenter
end
object Label3: TLabel
Left = 410
Top = 23
Width = 75
Height = 20
Caption = 'Local Port:'
Layout = tlCenter
end
object edtRemoteHost: TEdit
Left = 119
Top = 19
Width = 130
Height = 28
MaxLength = 32767
TabOrder = 0
Text = 'localhost'
end
object edtRemotePort: TEdit
Left = 333
Top = 19
Width = 52
Height = 28
MaxLength = 32767
TabOrder = 1
Text = '5000'
end
object edtLocalPort: TEdit
Left = 478
Top = 19
Width = 52
Height = 28
MaxLength = 32767
TabOrder = 2
Text = '5000'
end
object btnActivateServer: TButton
Left = 546
Top = 17
Width = 69
Height = 27
Caption = 'Change'
TabOrder = 3
OnClick = btnActivateServerClick
end
end
object TcpClient1: TTcpClient
Left = 640
Top = 18
end
object TcpServer1: TTcpServer
OnAccept = TcpServer1Accept
Left = 680
Top = 18
end
end
-----------------------------------------------
d7中加入dclsockets70.bpl就有Tserversocket和Tclientsocket这两个组件了,
另外,TCPCLIENT,TCPSERVER控件我会用,楼上的demo是delphi7自带的,我看过了,
但我觉得TCPCLIENT,TCPSERVER控件不如Tserversocket和Tclientsocket好用。
begin
if cs.Active then cs.Close;
cs.Host :=edit3.text;
cs.Port :=strtoint(edit4.Text);
cs.Open;
cs.Socket.SendText(edit1.Text);
cs.Close;
end;这里不大对头,可能你对同步异步传送数据没分清楚,你可以换这样
第一种改法:
procedure TForm1.Button1Click(Sender: TObject);
begin
if cs.Active then cs.Close;
cs.Host :=edit3.text;
cs.Port :=strtoint(edit4.Text);
////
CS.ClientType := ctBlocking; //同步模式,保证open后立即就可以发送数据
////
cs.Open;
cs.Socket.SendText(edit1.Text);
cs.Close;
end;
第二种改法(麻烦了点,不过可以看看):
procedure TForm1.Button1Click(Sender: TObject);
begin
if cs.Active then cs.Close;
cs.Host :=edit3.text;
cs.Port :=strtoint(edit4.Text);
cs.Open;
////
while not cs.Active { (and Time < 10s) etc...} do Application.ProcessMessages; //等待操作系统帮你连通,自己加代码防止死循环。
if cs.Active then
////
cs.Socket.SendText(edit1.Text);
cs.Close;
end;