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
