Hi,

I'm developing an application that uses Synapse's FTPSend to exchange 
files with a self made hardware that can act as FTP Server. In my 
Windows XP based computer everything goes just right. But when I try to 
send files using a Windows 98 box most of the time (about 95% or even 
more) it can't send a complete file, meaning that the last few bytes 
were not stored. To make sure that there were no problem with our FTP 
Server with used the command line Windows FTP to send files and 
eveything went ok.

So I found out that it would be good to monitor the network with 
Ethereal to better analyze what was going on. By doing this I was able 
to figure out that every time were file could be sent the sequence of 
network commands was something like this:

...
PC -> HW --- [FIN, PSH, ACK]
HW -> PC --- [ACK]
HW -> PC --- [FIN, PSH, ACK]
HW -> PC --- 226 TRANSFER COMPLETE

And, every time that the transmission failed the sequence was as follows:

PC -> HW --- [FIN, PSH, ACK]
HW -> PC --- [ACK]
PC -> HW --- [RST]
HW -> PC --- 426 CONNECTION CLOSED. TRANSFER ABORTED

The "RST" flag is related with "CloseSocket" function and, according to 
Microsoft documentation (at 
http://msdn2.microsoft.com/en-us/library/ms737582.aspx), "The semantics 
of *closesocket* are affected by the socket options SO_LINGER and 
SO_DONTLINGER as follows"

Option
        Interval
        Type of Close
        Wait for Close
SO_DONTLINGER
        Do not care
        Graceful
        No
SO_LINGER
        Zero
        Hard
        No
SO_LINGER
        Nonzero
        Graceful
        Yes


"If SO_LINGER is set with a zero time-out interval (that is, the 
*linger* <http://msdn2.microsoft.com/en-us/library/ms739165.aspx> 
structure members *l_onoff* is not zero and *l_linger* is zero), 
*closesocket* is not blocked even if queued data has not yet been sent 
or acknowledged. This is called a hard or abortive close, because the 
socket's virtual circuit is reset immediately, and any unsent data is 
lost. Any *recv* call on the remote side of the circuit will fail with 
WSAECONNRESET <http://msdn2.microsoft.com/en-us/library/ms740668.aspx>."

"If SO_LINGER is set with a nonzero time-out interval on a blocking 
socket, the *closesocket* call blocks on a blocking socket until the 
remaining data has been sent or until the time-out expires. This is 
called a graceful disconnect. If the time-out expires before all data 
has been sent, the Windows Sockets implementation terminates the 
connection before *closesocket* returns."

Based on this I found that the FTPSend's function DataSocket, when the 
FTPSend's PassiveMode is set to false - which is the case of our 
application, since our FTP Server does not allows for PassiveMode - had 
the following line "FDSock.SetLinger(True, 10);" which makes the 
TBlockSocket class to create a TSynaOption of kind SOT_LINGER with 
properties Enabled as true and Value as 10 and it calls the 
DelayedOption procedure resulting in a call to SetDelayedOption 
procedure. At this point there is a case block that evaluates the 
TSynaOption's Value property that is SOT_LINGER.

Looking the line "li.l_linger := Value.Value div 1000;" we can verify 
that the value passed to SetLinger (which was 10) will get divided by 
1000, resulting 0 (zero). Thus it will make the CloseSocket function to 
do a hard or abortive close (send the RST command).

I don't know why the problem arrises only on Windows 98 and not in XP. 
May be there are some differences in the DLL implementation. But the 
fact is that FTPSend should pass the SetLinger value in miliseconds and 
the SetDelayedOption of TBlockSocket would translate it to seconds 
(divide by 1000).

So I'd changed the FTPSend's DataSocket to the following:

"FDSock.SetLinger(True, 10000);"

After the change everything works fine on both Windows 98 and XP.

Best regards,

Marcelo

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
synalist-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/synalist-public

Reply via email to