File Transfer speed problem in LAN

Hi everyone.

I use Sparks 2.5.8. All my computers are in the same LAN but when I try use tranfer file the speed is about 50K per second. How is it possible? I think should be 1M but always get 50K. Can I configure this?

Sorry my poor english and thanks in advance.

are you using wifi? i had the same problem- i have a wifi and wired (mixed network) as we have both laptops and desktops. i saw very poor speed when transferring from a wifi to wired pc but the wired to wired transfer was so fast (of a 650KB) file that i didn’t know it it had even started and ended.

Try the latest 2.6.0 RC2 version http://bamboo.igniterealtime.org/browse/SPARK-INSTALL4J-207/artifact/Install4j/s park_2_6_0_12222.exe

Try this patch for Spark 2.6.0.

The patch is uploaded as attach file.
Spark Patch.zip (592276 Bytes)

Michael, please explain what exactly your patch is fixing. Maybe you want to share your patch in a diff format, so it could be added to the source code (if it is ok) of Spark?

Hi, wroot.

I found that the smackx only got the IP address in the first Network Interface using method:

java.net.InetAddress.getLocalHost().

The source code is here:

Line 99 in class org.jivesoftware.smackx.bytestreams.socks.Socks5Proxy.

The original source code is:

/**
     * Private constructor.
     */
    private Socks5Proxy() {
        this.serverProcess = new Socks5ServerProcess();         // add default local address
        try {
            this.localAddresses.add(InetAddress.getLocalHost().getHostAddress());
        }
        catch (UnknownHostException e) {
            // do nothing
        }     }

I don’t think it’s intelligent to code like this.

If I have multi-network interface in my computer, the method getLocalHost() gets only the first IP for the first network interface.

I think it should be optional for users. If users do not point out which IP to use, we can use getLocalHost() to get the local internet address. But if users want to bind Spark at the specific IP, there should be a way for users to do this.

So, I modified the code as:

/**
     * Private constructor.
     */
    private Socks5Proxy() {
        this.serverProcess = new Socks5ServerProcess();         // add default local address
        try {
            InetAddress localHost;
            try {
                localHost = getInetAddress();
                if(localHost == null){
                    localHost = InetAddress.getLocalHost();
                }
            } catch (IOException e) {
                localHost = InetAddress.getLocalHost();
                e.printStackTrace();
            }             this.localAddresses.add(localHost.getHostAddress());
        }
        catch (UnknownHostException e) {
            // do nothing
        }     }

and the method getInetAddress is just as below:

/**
     * Returns the local IP address
     * Author Michael Pan
     */
    private InetAddress getInetAddress() throws IOException{
        File patchFile = new File("patch.dat");
        BufferedReader br = new BufferedReader(new FileReader(patchFile));
        String str = null;
        InetAddress inetAddr = null;
        while((str = br.readLine()) != null){
            str = str.trim();
            if(str.startsWith("#")) continue;
            str = str.toUpperCase();
            str = str.replaceAll(" ", "");
            str = str.replaceAll("\t", "");
            if(str.startsWith("IP:")){
                inetAddr= InetAddress.getByName(str.substring(3));
                if(inetAddr != null) break;
            }else if(str.startsWith("IPV6:")){
                str = str.replaceAll("-", ":");
                inetAddr = InetAddress.getByName(str.substring(5));
                if(inetAddr != null) break;
            }else if(str.startsWith("MAC:")){
                str = str.substring(4);
                str = str.replaceAll(":", "");
                str = str.replaceAll("-", "");                 String hostName;
                InetAddress localHost;
                InetAddress[] localAddresses;                 localHost = InetAddress.getLocalHost();
                hostName = localHost.getHostName();                 localAddresses = InetAddress.getAllByName(hostName);
                if (localAddresses == null || localAddresses.length == 0) continue;                 for (int i = 0; i < localAddresses.length; i++) {
                    localHost = localAddresses[i];
                    NetworkInterface nic = NetworkInterface.getByInetAddress(localHost);
                    byte[]mac = nic.getHardwareAddress();
                    if(mac == null) continue;
                    StringWriter sw = new StringWriter();
                    PrintWriter pw = new PrintWriter(sw);
                    for(int j=0; j < mac.length; j++){
                        pw.printf("%2X", mac[j]);
                    }
                    if(sw.toString().equals(str)){
                        inetAddr = localHost;
                        break;
                    }
                }
            }
        }
        br.close();
        return inetAddr;
    }

The format of patch.dat is like this:

# please enter your local IP(both IPv4 and IPv6 are OK) or MAC address.
# comment with '#'
IP: 172.18.8.54
#IPv6: 2001:da8:1002:a537:8c02:c337:8649:2619
#MAC: 84-2B-2B-AB-14-D0

Of cource, I just give a simple method for bind Spark at a specific IP as a temporary solution for my Spark. It will be better to add a choosing panel in Spark Settings. Sorry to say that I have little time to read Spark UI codes now and I don’t know how to add a panel in Spark codes till now. I hope that developers could think about it.

Thanks!
Original_Socks5Proxy_Smackx_3_2_0.zip (4165 Bytes)
Modified_Socks5Proxy_Smackx_3_2_0.zip (4803 Bytes)
patch.dat.zip (282 Bytes)

changing the ip in spark ui is hardly possible. smack doesn’t support to change/select your local ip. as you see you made changes in smackx.jar. spark uses smack as precompiled libary.

No, I don’t think so.

Smack does support changing/selecting the local IP.

At line 202 in org.jivesoftware.smackx.bytestreams.socks.Socks5Proxy.java, the method

public void addLocalAddress(String address)

and line 239, the method

public void replaceLocalAddresses(List<String> addresses)

can help Spark change the local IP.

Unfortunately, I don’t know how to add a panel in Spark. The code hierarchy is so complex for me. If there’s a doc about developing in Spark, it will be no better more.

the ui would not be the problem but all the logic for file transfer is handled in the smack. to use the method’s you mentioned you need to create your own OutgoingFileTransfer in smack. The call hirachy is something like this:

SparkTransferManager -> FileTransferManager -> OutgoingFileTransfer -> FileTransferNegotiator -> Socks5BytestreamManager -> Socks5Proxy

The problem is that you might not be able to create your own OutgoingFileTransfer because its construtor is protected.

this topic should be discussed in smack support, i think. maybe we should ask Robin Collier.

Thank you very much!

I’ll try better to read and understand the source codes of spark and smack.

Thanks again.

no problem! i know it is sometimes hard to understand the source code of spark, even reading is not much easier.

Logged as SMACK-337. Should be resolved in 3.3.

Any idea how to fix this in the Smack trunk?