[jcifs] Re: Disconnect from a share

Levi Purvis mail at levipurvis.com
Wed Oct 19 17:34:47 GMT 2005


I'm not very familiar with the internals of the JCIFS code, but in
general it is fairly easy to create a dedicated "logoff" thread to fix
this problem.  Rather than rudely closing the socket, execute the code
for reading the "logoff" response and closing the socket on a separate
thread.  This way the rest of the code doesn't have to wait, but the
other end won't get the "Connection reset by peer" problem.  You may
only need one thread to act as a "sink" for cleaning up, so
performance should be comparable to the current code.  Throw in NIO,
and it will be even better.  :-)  A thread pool might be in order if
many concurrent logoff responses are expected and NIO is not an
option, to avoid having sockets that need closing pile up.


On 10/19/05, Alexander Saupp <asaupp at web.de> wrote:
> > What versions of JCIFS and Samba are you using?
>         JCIFS 1.2.6, Samba 3.0.14a-0.4 (as it comes with std. SUSE SLES9 SP2).
>
>         # rpm -qa |grep samba |grep -v yast
>         samba-winbind-3.0.14a-0.4
>         samba-3.0.14a-0.4
>         samba-client-3.0.14a-0.4
>
> >Also what is your smb.conf log level set to?
>         Its not set - default should be 1-3 i would guess.
>
> >If JCIFS has an existing session with the desired domain and username
> >then probably not. It will simply reuse the existing session even with
> >jcifs.smb.client.ssnLimit=1. You would have to use different credentials
> >each time you query to ensure that a new transport is created.
>
>     You might be right for the session - but the transport is definitly a
>     new one.
>         public class SmbTransport extends Transport implements SmbConstants {
>         ...
>         static synchronized SmbTransport getSmbTransport( UniAddress address,
>                          int port, InetAddress localAddr, int localPort ) {
>             ...
>             if( SSN_LIMIT != 1 ) {
>                 ..
>             }
>             conn = new SmbTransport( address, port, localAddr, localPort );
>
>
>     I used the following line to monitor my smbd pids while running the
>     testclass.
>         while (true); do ps -aef |grep smbd |grep -v tail |grep -v grep |awk '{
>            print "smbd PID: "$2 } ;'; smbstatus -S;  sleep 1; done
>
>     It shows the same PID when not setting the ssn_limit for the first 3
>     connects (no timout happening) and anothe rone for the forth (timeout in
>     between).
>
>     The picture changes if i set ssn_limit=1 - a new PID is generated for each
>     connect - because of the new transport, I'd guess.
>     I am not quite clear about what transport and session mean.
>
>
> >What other JCIFS properties are you setting?
> >One of the main issues with trying to resolve this issue was that I
> >could not reproduce the problem. Is there anything special about the
> >program you used to test the problem?
>
>     Thanks for beeing willing to have a deeper look - i attached the test class
>     i used below. You can see the JCIFS parameters set in there also.
>
>         package jcifsTest;
>         import jcifs.smb.SmbFile;
>         public class JCIFSServiceCheck {
>           public static void sleep(){
>             try {
>               System.out.println("\tSleeping..");Thread.sleep(3*1000);
>             }catch (Exception ex){ System.out.println(ex.toString()); }
>           }
>
>           public static void testConnect(String SHARE_USER, String SHARE_PWD,
>                    String SHARE_IP, String SHARE_NAME, String SHARE_TESTFILE){
>             try {
>               // String url="smb://;:@" + v_host_ip + "/smb_control/";
>               String url = "smb://;" + SHARE_USER + ":" + SHARE_PWD + "@" +
>                  SHARE_IP  + SHARE_NAME;
>
>               SmbFile smb = new SmbFile(url);
>               // jcifs starts a new smbtransport for this command
>               // a smbtransport has its own Thread
>               String[] sm = smb.list();
>
>               // List Directory
>               for (int count = 0; count < sm.length; count++) {
>                 System.out.println("\t"+sm[count]);
>               }
>             } catch (Exception ex) {
>               System.out.println(ex.toString());
>             }
>           }
>
>           public static void main(String[] args) {
>      ### UNCOMMENT THE LINE BELOW FOR THE SECOND RUN MENTIONED ABOVE
>             jcifs.Config.setProperty("jcifs.smb.client.ssnLimit", "1");                      ###
> UNCOMMENT THE LINE ABOVE FOR THE SECOND RUN MENTIONED ABOVE
>             jcifs.Config.setProperty("jcifs.util.loglevel", "0");
>             jcifs.Config.setProperty("jcifs.smb.client.soTimeout","5000");
>
>             testConnect("username", "pwd", "192.168.1.100", "/share/",
>               "testfile");
>             sleep();
>             testConnect("username", "pwd", "192.168.1.100", "/share/",
>               "testfile");
>             sleep();
>             testConnect("username", "pwd", "192.168.1.100", "/share/",
>               "testfile");
>             sleep();sleep();sleep();sleep();
>             testConnect("username", "pwd", "192.168.1.100", "/share/",
>               "testfile");
>             sleep();
>
>             System.out.println("Finished..\n");
>           }
>         }
>
>
>
> > What's my topic?
>         To me it looks currently like i have a choice: Have a new smbd each time
>         (I would want that for my checks definitly) - or get rid of the nasty
>         error message below (showing up in /var/log/samba/log.smbd).
>         But I would like to have both - which is possible with the fix mentioned
>         earlier in this thread.
>
>         [2005/10/19 14:30:39, 0] lib/util_sock.c:read_socket_data(384)
>           read_socket_data: recv failure for 4. Error = Connection reset by peer
>
>


More information about the jcifs mailing list