现在要做一个关于C/S的程序.因为服务器要判断客户机的请求然后做出应答,而客户机也要在收到服务器的应答之后再发出相应的请求.想请教一下在这种情况下,ServerSocket控件和ClientSocket控件应该在什么时候读和写?在哪个事件中?
解决方案 »
- dilphi做的浏览器,如果网页中的连接时指向_blank新窗口,请问才能让新建窗口的连接也能在自己的浏览器中打开,而不是调用默认的ie浏览器
- 请问怎么样改变BusinessSkinForm的窗口大小?(好象它的窗口宽度,不能变的很小)
- 请帮助一下.
- 请教个问题
- 挑战高手
- asta client 的问题
- 一个非常奇怪的问题?
- 如何连接internet上的一台sql server数据库服务器?
- to zbird(谢谢,接分2)
- 动态创建的一批控件,如何添加事件(在线等待,立即给分!!!)
- 大家做软件主界面是什么样式的?我想做一个图形主界面?
- 菜鸟问:打开BDE 之后在 Databases 底下有名为IBLocal 的数据库,用户名是SYSDBA,密码哪里找?
http://expert.csdn.net/Expert/topic/1093/1093894.xml?temp=2.544582E-03阻塞方式加上线程,因为是应答过程,所以Client要等待Server的响应,所以应该在线程中来实现,其中重要的功能就是winsock.Select函数了,其实的就是自已定义的,你先看看.还有这是我刚写的非阻塞下的代码,但是不正确,但意思是相同的.你看看.
//clientMain.pas
unit ClientMain;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ScktComp;type
TForm2 = class(TForm)
RadioGroup1: TRadioGroup;
CommandButton: TButton;
ClientSocket1: TClientSocket;
HostEdit: TEdit;
OpenButton: TButton;
PortEdit: TEdit;
Memo1: TMemo;
procedure CommandButtonClick(Sender: TObject);
procedure OpenButtonClick(Sender: TObject);
procedure ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form2: TForm2;implementationuses WinSock;{$R *.dfm}
const
SizeInt = SizeOf(Integer); { Command constant }
ccMsg = $0001;
ccASKSome = $0002;
ccError = $0003;procedure TForm2.CommandButtonClick(Sender: TObject);
var
Socket: TCustomWinSocket; function WaitServer: Boolean;
var
FDSet: TFDSet;
Timeout: TTimeVal;
begin
FD_ZERO(FDSet);
FD_SET(Socket.SocketHandle, FDSet);
// 5 seconds
Timeout.tv_sec := 5;
Timeout.tv_usec := 0;
// wait for server reponse
Result := select(0, @FDSet, nil, nil, @Timeout) > 0;
end; procedure SendMsgToServer;
const
SMsgToServer = 'hello, server';
var
Len, ReLen, Command, RetLen: Integer;
begin
Len := Length(SMsgToServer);
Command := ccMsg;
RetLen := Socket.SendBuf(Command, SizeInt);
if RetLen <> SizeInt then
raise ESocketError.Create('socket Write error');
RetLen := Socket.SendBuf(Len, SizeInt);
if RetLen <> SizeInt then
raise ESocketError.Create('socket Write error');
RetLen := Socket.SendBuf(PChar(SMsgToServer)^, Len);
if RetLen <> Len then
raise ESocketError.Create('socket Write error');
if WaitServer then
begin
RetLen := Socket.ReceiveBuf(Command, SizeInt);
if (RetLen <> SizeInt) or (Command <> ccMsg) then
raise Exception.Create('server reponse command is error');
RetLen := Socket.ReceiveBuf(ReLen, SizeInt);
if (RetLen <> SizeInt) or (ReLen <> Len) then
raise Exception.Create('server response length is error');
Memo1.Lines.Add('msg is send to server');
end
else
raise ESocketError.Create('Server not reponse or timeout');
end; //procedure Send
begin
if not ClientSocket1.Active then
raise ESocketError.Create('Socket not open');
Socket := ClientSocket1.Socket;
case RadioGroup1.ItemIndex of
0: SendMsgToServer;
1: ;
2: ;
else
;
end;
end;procedure TForm2.OpenButtonClick(Sender: TObject);
begin
with ClientSocket1 do
begin
if Active then Close;
Sleep(10);
Port := StrToInt(PortEdit.Text);
Host := HostEdit.Text;
Open;
end;
end;procedure TForm2.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1.Lines.Add('is connect to server, you can send command')
end;end.//clientMain.dfm
object Form2: TForm2
Left = 192
Top = 103
Width = 544
Height = 375
Caption = 'Form2'
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 RadioGroup1: TRadioGroup
Left = 240
Top = 160
Width = 241
Height = 105
Caption = 'RadioGroup1'
ItemIndex = 0
Items.Strings = (
'Some message to Server'
'Ask Server and Wait...'
'Error Request')
TabOrder = 0
end
object CommandButton: TButton
Left = 240
Top = 280
Width = 121
Height = 25
Caption = 'Send Command'
TabOrder = 1
OnClick = CommandButtonClick
end
object HostEdit: TEdit
Left = 248
Top = 48
Width = 121
Height = 21
TabOrder = 2
Text = '127.0.0.1'
end
object OpenButton: TButton
Left = 248
Top = 80
Width = 113
Height = 25
Caption = 'Connect to Host'
TabOrder = 3
OnClick = OpenButtonClick
end
object PortEdit: TEdit
Left = 248
Top = 16
Width = 121
Height = 21
TabOrder = 4
Text = '211'
end
object Memo1: TMemo
Left = 32
Top = 16
Width = 185
Height = 297
Lines.Strings = (
'Memo1')
TabOrder = 5
end
object ClientSocket1: TClientSocket
Active = False
Address = '127.0.0.1'
ClientType = ctNonBlocking
Port = 0
OnConnect = ClientSocket1Connect
Left = 368
Top = 280
end
end
unit serverMain;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ScktComp, StdCtrls;type
TForm1 = class(TForm)
ServerSocket1: TServerSocket;
Memo1: TMemo;
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}const
SizeInt = SizeOf(Integer); { Command constant }
ccMsg = $0001;
ccASKSome = $0002;
ccError = $0003; SMsgToClient = 'yes, you can.';
SMsgError = 'Error Message';procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
P, Data: PChar;
RetLen, Command, StreamLen, Count: Integer;
begin
RetLen := Socket.ReceiveLength;
if RetLen = 0 then Exit;
RetLen := Socket.ReceiveBuf(Command, SizeInt);
if RetLen <> SizeInt then
raise ESocketError.Create('Socket read error');
RetLen := Socket.ReceiveBuf(Count, SizeInt);
if RetLen <> SizeInt then
raise ESocketError.Create('Socket read error');
GetMem(Data, Count);
try
P := Data;
case Command of
ccMsg:
begin
StreamLen := Count;
while Count > 0 do
begin
RetLen := Socket.ReceiveBuf(P^, Count);
if RetLen > 0 then
begin
Inc(Integer(P), RetLen);
Dec(Count, RetLen);
end;
end;
Socket.SendBuf(Command, SizeInt);
Socket.SendBuf(StreamLen, SizeInt);
Memo1.Lines.Add(Format('message: %s', [Data]));
end;
ccASKSome:
begin
Command := ccASKSome;
Count := Length(SMsgToClient);
Socket.SendBuf(Command, SizeInt);
Socket.SendBuf(Count, SizeInt);
Socket.SendBuf(PChar(SMsgToClient)^, Count);
Memo1.Lines.Add('Response client Ask some.')
end;
else
Command := ccError;
Count := Length(SMsgError);
Socket.SendBuf(Command, SizeInt);
Socket.SendBuf(Count, SizeInt);
Socket.SendBuf(PChar(SMsgError)^, Count);
Memo1.Lines.Add('Client request is error');
end;
finally
FreeMem(Data);
end;
end;end.
//serverMain.dfm
object Form1: TForm1
Left = 192
Top = 103
Width = 544
Height = 375
Caption = 'Form1'
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 Memo1: TMemo
Left = 272
Top = 32
Width = 241
Height = 305
Lines.Strings = (
'Memo1')
TabOrder = 0
end
object ServerSocket1: TServerSocket
Active = True
Port = 211
ServerType = stNonBlocking
OnClientRead = ServerSocket1ClientRead
Left = 208
Top = 96
end
end