Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Opening a socket needs long time???

46 views
Skip to first unread message

firstshine

unread,
Jul 12, 2001, 10:06:29 AM7/12/01
to
In my application,there are three buttons,the following is their event:

procedure TForm1.Button1Click(Sender: TObject);
begin
ClientSocket1.open;
clientsocket1.socket.sendtext('111');
clientsocket1.close;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ClientSocket1.open;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
clientsocket1.socket.sendtext('111');
clientsocket1.close;
end;

The question is :
After application run,I clicked button1,the string did not been sent to
server,only after I clicked button1 twice,it can be sent to server.
After application restart,I clicked button2,then clicked button3,the
string can be sent to server.
Why?
Now,I have to write something which like the following statement to send
a string to a dozen server,how can I do?

procedure TForm1.Button1Click(Sender: TObject);
var
icount:integer;
begin
for icount:=0 to listbox1.items.count - 1 do
begin
clientsocked1.close;
clientsocked1.address:=listbox1.items.string[icount];
clientsocked1.port:=88888;
ClientSocket1.open;
clientsocket1.socket.sendtext('111');
clientsocket1.close;
end;
end;


Vic

unread,
Jul 12, 2001, 10:21:52 AM7/12/01
to
Look at Delphi Chat example '\Delphi5\Demos\Internet\Chat'

firstshine <ca...@21cn.com> wrote in message news:3b4dae87_1@dnews...

Vic

unread,
Jul 12, 2001, 11:01:54 AM7/12/01
to
or you could use this:-
This method sets up a thread for each server connection. The advantage of
this is that you don't need to wait for each connection to complete before
initiating the next.....
Hope this helps!


type
TWaitThr = class(TThread)
private
IPList : Array[0..60] of string;
ServerCount : integer;
ErrorState : integer;
procedure GetIPAddress;
protected
procedure Execute; override;
public
constructor Create;
destructor Destroy; override;
end;

type
TWriteBuff = array[0..31] of Char;
TConnectToSrv = class(TThread)
private
{ Private declarations }
ReturnMsg : string;
ReceivedString : string;
thdIPAddress : string;
thdStringToSend : TWriteBuff;
thdErrorState : boolean;
protected
procedure Execute; override;
procedure DoTerminate; virtual;
public
constructor Create(IPAddress : string);
destructor Destroy; override;
end;

var
MainFrm: TMainFrm;

implementation

{$R *.DFM}

{ TConnectToSrvThd }
constructor TConnectToSrvThd.Create(IPAddress);
var i: integer;
begin
inherited Create(TRUE);
thdIPAddress := IPAddress;
thdStringToSend := 'Hello Server';
FreeOnTerminate := TRUE;
Resume;
end;

destructor TTedGetStatThd.Destroy;
begin
inherited;
end;

procedure TTedGetStatThd.Execute;
var
SocketStream : TWinSocketStream;
SocketConnection : TClientSocket;
buffer : array[0..254] of char;
begin
SocketConnection := nil;
try
// set up client socket
SocketConnection := TClientSocket.Create(nil);
try
with SocketConnection do
begin
ClientType := ctBlocking;
Address := thdIPAddress;
Port := 88888;
Active := True;
end;
except
SocketConnection.Free;
terminate;
exit;
end;
try
SocketStream := TWinSocketStream.Create(SocketConnection.Socket,
20000);
try
if (not Terminated) and (SocketConnection.Active) then
begin
SocketStream.Write(thdStringToSend,length(thdStringToSend)+1);
FillChar(buffer,255,0);
// if you need to wait for a response then do this part
if SocketStream.WaitForData(10000) then
begin
if SocketStream.Read(buffer,255) > 0 then
begin
ReturnMsg := buffer;
synchronize(// send the response to the main form // );
end;
end;
end;
finally
SocketConnection.Close;
SocketStream.Free;
SocketConnection.Free;
SocketConnection := nil;
terminate;
end;
except
SocketConnection.Close;
SocketConnection.Free;
SocketConnection := nil;
terminate;
end;

except
terminate;
end;
end;

procedure TWaitThr.GetIPAddress;
var
i: integer;
begin
ServerCount := listbox1.items.count;
for i:=0 to ServerCount -1 do
IPList[i] := listbox1.items.string[i];
end;

constructor TWaitThr.Create;
begin
inherited Create(TRUE);
FreeOnTerminate := TRUE;
Resume;
end;

destructor TWaitThr.Destroy;
begin
inherited;
end;


procedure TWaitThr.Execute;
var
i : integer;
hndlArr : Array[0..10] of THandle;
thrArr : Array[0..10] of TConnectToSrvThd;
ThreadIndex : integer;
begin
synchronize(GetIPAddress);
if ServerCount > 0 then
begin
ThreadIndex := 0;
while ((ThreadIndex < ServerCount) and (not Terminated)) do
begin
// create a maximum of 10 threads at one time
i := 0;
repeat
thrArr[i] := TConnectToSrvThd.Create(IPList[ThreadIndex]);
hndlArr[i] := thrArr[i].Handle;
inc(ThreadIndex);
inc(i);
until (i = 10) or (ThreadIndex = TerminalCount);
WaitForMultipleObjects(i,@hndlArr,TRUE,INFINITE);
end;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
// connect and send text to servers
TWaitThr.Create;
end;

firstshine <ca...@21cn.com> wrote in message news:3b4dae87_1@dnews...

Mike C

unread,
Jul 12, 2001, 11:55:14 AM7/12/01
to

Just guessing on Button1Click, but the Open method begins the process of
opening the socket connection. You need to wait for confirmation that the
socket is open before trying to use SendText. It opens fast, but takes than
longer than your program to process the SendText.

When you click on button2, then button3, the socket is open by the time you
fire off sendtext. However, you can't rely upon the socket to open that
quickly. You should check your socket, send your data, and watch
exceptions/OnError to make sure it worked.

For your multiple server scenario, sendtext in the OnConnected Event...

...MC


firstshine <ca...@21cn.com> wrote in message news:3b4dae87_1@dnews...

firstshine

unread,
Jul 13, 2001, 4:41:56 AM7/13/01
to

"Vic" <v...@scotcomms.co.uk> wrote in message news:3b4dbb84_2@dnews...

Vic

unread,
Jul 13, 2001, 7:12:19 AM7/13/01
to
Look in windows.pas

firstshine <ca...@21cn.com> wrote in message news:3b4eb492$1_2@dnews...

Claire

unread,
Jul 15, 2001, 9:43:14 AM7/15/01
to
Is your socket blocking or nonblocking?
If it's nonblocking, most functions return immediately after calling and
before they've completed their task. So attempting to write a string
immediately after calling Connect wouldnt work.
With non-blocking you would rely on asynchronous callbacks via the socket
events eg OnWrite OnConnect etc to control program flow.
That usually means writing some sort of state engine to keep track of what
you're doing,

If the socket is blocking you would be able to use your code as it is. The
application would wait until each call was processed before passing on to
the next line of code .
Unfortunately, unless the code is run within a separate thread, your
application will spend a lot of time unresponsive to the user. If you write
it using threads you will have to create thread safe variables and use
synchronize methods etc.

0 new messages