 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Mat Ballard Guest
|
Posted: Tue Aug 01, 2006 7:41 am Post subject: Need advice - Synapse - Connection Reset by Peer |
|
|
Hi everyone,
I'm new to the world of winsock apps and am getting the dreaded error 10054 -
Connection Reset by Peer.
I'm using the Synapse TTCPBlockSocket component.
At the moment I'm just trying to send a text message from client to server, and
have the server display the message in the main thread VCL GUI.
Since the ultimate aim is to perform memory-intensive graphical manipulations in
response to a client request, I have designed the server application to have a
listening thread that then Synchronizes back to the main VCL thread to perform
the actual communication. I know that most designs (eg: "Echo") will instead
spawn a worker thread, but I want to serialize "sessions" to maximize available
memory, and also because of the graphical manipulations, which I understand can
only be performed in the main VCL thread anyway.
My client code is:
procedure TClientForm.ConnectActionExecute(Sender: TObject);
var
Sock: TTCPBlockSocket;
begin
Sock := blcksock.TTCPBlockSocket.Create;
Sock.CreateSocket; // does nothing ?
Sock.SetLinger(true, 10);
Sock.Connect(ServerEdit.Text, PortNEdit.Text);
if (Sock.LastError = 0) then
begin
Sock.SendString('Hello Server !');
SendMemo.Lines.Add('Hello Server !');
end else begin
ShowMessageFmt('Internet Communication Error' + #13#10#13#10 + '%s',
[Sock.LastErrorDesc]);
end;
Sock.CloseSocket;
Sock.Free;
end;
and my relevant server code is:
ServerDaemon := TTCPServerDaemon.Create;
ServerDaemon.SynchMethod := SynchMethod;
ServerDaemon.Port := PortNEdit.Text;
...
procedure TTCPServerDaemon.Execute;
begin
FSock.CreateSocket;
FSock.SetLinger(true, 10);
FSock.Bind('0.0.0.0', Self.Port);
FSock.Listen;
repeat
if Self.Terminated then break;
if FSock.CanRead(1000) then
begin
FClientSock := 0;
FClientSock := FSock.Accept;
if (FSock.LastError = 0) and Assigned(SynchMethod) then
Synchronize(SynchMethod);
// = jump back to main VCL thread to grab data and perform calculations
end;
until false;
end;
...
procedure TServerForm.SynchMethod;
var
Sock : TTCPBlockSocket;
Str: String;
begin
ReceiveMemo.Lines.Add('We got hit !');
Sock := TTCPBlockSocket.Create;
KillConnectionBitBtn.Tag := 0;
KillConnectionBitBtn.Enabled := TRUE;
try
Sock.Socket := ServerDaemon.ClientSock; // yes, it gets a valid socket, 1668
Sock.GetSins;
{FSock.LocalSin = (2, 2, 49425, (('', #0, #0, #1), (127, 256), 16777343), (#0,
#0, #0, #0, #0, #0, #0, #0), 49425, 16777343, ((#0, #0, #0, #0, #0, #0, #0, #0,
#0, #0, #0, #0, #0, #0, #0, #0), (0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0)), 0)
FSock.RemoteSin = (2, 2, 6929, (('', #0, #0, #1), (127, 256), 16777343), (#0,
#0, #0, #0, #0, #0, #0, #0), 6929, 16777343, ((#0, #0, #0, #0, #0, #0, #0, #0,
#0, #0, #0, #0, #0, #0, #0, #0), (0, 0, 0, 0, 0, 0, 0, 0), (0, 0, 0, 0)), 0)}
repeat
Application.ProcessMessages;
if (KillConnectionBitBtn.Tag > 0) then
break;
Str := Sock.RecvString(ReadTimeoutNEdit.AsInteger);
ReceiveMemo.Lines.Add(Str);
if (Sock.LastError <> 0) then
begin
ShowMessageFmt('Internet Communication Error' + #13#10#13#10 + '%s',
[Sock.LastErrorDesc]);
break;
end;
until false;
finally
Sock.Free;
KillConnectionBitBtn.Enabled := FALSE;
KillConnectionBitBtn.Tag := 0;
end;
end;
Any hints on how to progress this problem would be greatly appreciated,
Thanks in advance,
Mat |
|
| Back to top |
|
 |
Mat Ballard Guest
|
Posted: Tue Aug 01, 2006 8:11 am Post subject: Re: Need advice - Synapse - Connection Reset by Peer |
|
|
ps: the actual 10054 error occurs here in the server code, at
TTCPBlockSocket.RecvString, which has correctly been fired by the ServerDaemon
thread using Synchronize:
| Quote: | procedure TServerForm.SynchMethod;
...
Str := Sock.RecvString(ReadTimeoutNEdit.AsInteger);
ReceiveMemo.Lines.Add(Str);
if (Sock.LastError <> 0) then
|
cheers,
Mat |
|
| Back to top |
|
 |
theo Guest
|
Posted: Tue Aug 01, 2006 5:03 pm Post subject: Re: Need advice - Synapse - Connection Reset by Peer |
|
|
You close the sockets on either side, so one of them is actually closing
the connection. What's the problem?
However your design is a bit strange. Servers usually don't have a GUI.
If you're interested, here is a little Synapse Client-Server Demo I wrote:
http://www.theo.ch/Kylix/perftest.zip |
|
| Back to top |
|
 |
Mat Ballard Guest
|
Posted: Wed Aug 02, 2006 5:15 am Post subject: Re: Need advice - Synapse - Connection Reset by Peer |
|
|
g'day theo,
thanks for your reply - have downloaded your demo and will study it *very
carefully*.
As for the strange design, this is due to the following.
The Win32 GUI app performs very complex and memory-intensive manipulations of
images; crudely speaking, it does:
NewImage := function(Image1, Image2, Image3, Very_Long_List_of_Parameters).
We have a customer who loves what this Win32 GUI app can do, and then asked:
"but how can we make it talk to our Unix C++ processes ? By September."
After thinking about it, the best way forward seemed to be to "bolt on" TCPIP
server capability, and also client capability for testing purposes. The GUI app
can then be run as a server, or as a client, but not both at the same time. The
GUI_Client then throws {Image1, Image2, Image3, Very_Long_List_of_Parameters} to
the GUI_Server, which calculates NewImage and throws it back to GUI_Client.
There will not be more than one connection at a time, and trying to do two sets
of calculation at the same time is a Very_Bad_Idea because the calculations are
very CPU and Memory intensive (~100 - 1000 MB, 10 - 500 s).
The problem is that the client is disconnecting before it sends it data;
GUI_Client does:
Sock.Connect(ServerEdit.Text, PortNEdit.Text);
i := Sock.LastError;
if (i = 0) then
begin
Sock.SendString('Hello Server !'); <- this is sent without error
....
Misc.Wait(10000, FALSE); <- wait 10 s before closing socket
Sock.CloseSocket;
this then hits the listening thread on the GUI_Server:
FSock.Listen;
repeat
if Self.Terminated then break;
if FSock.CanRead(PollEvery) then
begin
FClientSock := 0;
FClientSock := FSock.Accept;
if (FSock.LastError = 0) and Assigned(SynchMethod) then
Synchronize(SynchMethod); <- jump back to main GUI thread here
which then hits SynchMethod in the main GUI:
Sock := TTCPBlockSocket.Create;
try
Sock.Socket := ServerDaemon.ClientSock; // 1668
Sock.GetSins;
repeat
Str := Sock.RecvString(1000); <- this fails
if (Sock.LastError = 0) then <- error 10054 here
9000 ms later, the GUI_Client does Sock.CloseSocket;
So the GUI_Client hasn't actually closed its socket until after the GUI_Server
has whinged about 10054 (Connection Reset by Peer).
So I am somehow losing the connection, but cannot see where.
cheers,
Mat |
|
| Back to top |
|
 |
Lukas Gebauer Guest
|
Posted: Wed Aug 02, 2006 8:11 am Post subject: Re: Need advice - Synapse - Connection Reset by Peer |
|
|
Mat Ballard wrote:
| Quote: | ps: the actual 10054 error occurs here in the server code, at
TTCPBlockSocket.RecvString, which has correctly been fired by the ServerDaemon
thread using Synchronize:
|
RecvString expecting CRLF string terminator. But SendString sending data
as is... if you are sending by SendString and you are receiving it by
Recvstring, you must send your data by Sendstring(yourdata + CRLF); |
|
| Back to top |
|
 |
Mat Ballard Guest
|
Posted: Thu Aug 03, 2006 7:22 am Post subject: Re: Need advice - Synapse - Connection Reset by Peer |
|
|
g'day Lukas
re:
| Quote: | RecvString expecting CRLF string terminator. But SendString sending data
as is... if you are sending by SendString and you are receiving it by
Recvstring, you must send your data by Sendstring(yourdata + CRLF);
|
*THANK YOU* !
It then hit other errors, but it solved that problem.
cheers,
Mat |
|
| Back to top |
|
 |
Tony Caduto Guest
|
Posted: Mon Aug 07, 2006 5:10 pm Post subject: Re: Need advice - Synapse - Connection Reset by Peer |
|
|
Mat Ballard wrote:
| Quote: | g'day theo,
thanks for your reply - have downloaded your demo and will study it *very
carefully*.
As for the strange design, this is due to the following.
The Win32 GUI app performs very complex and memory-intensive manipulations of
images; crudely speaking, it does:
|
Matt,
You should consider using windows messages instead of synchronize.
What I do is create a object to contain whatever I want to send back to
the GUI from the thread and then cast the object as a integer and send
that integer back as the wparam of a message, then in the gui, cast the
integer back as the object type and get your data. Be sure to free the
object when you are finished with it.
You could also do something with a queue or stack depending on your
needs.
when data comes in you could push it into the data structure and then in
the GUI check the count and if stuff is waiting start popping it off.
A FIFO queue may work for you.
--
Tony Caduto
http://www.amsoftwaredesign.com
Home of PG Lightning Admin for Postgresql 8.x |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|