From 496da3f0c483f178c397c3b2d8941fff03174298 Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Mon, 21 Jul 2025 16:51:16 +0800 Subject: [PATCH] protocol automatically compatible with IPv4/IPv6 address --- HISTORY | 4 + pom.xml | 2 +- .../org/csource/fastdfs/ClientGlobal.java | 9 +- .../java/org/csource/fastdfs/ProtoCommon.java | 18 ++- .../org/csource/fastdfs/StorageClient.java | 17 ++- .../fastdfs/StructIPv4StorageStat.java | 45 ++++++ .../fastdfs/StructIPv6StorageStat.java | 45 ++++++ .../csource/fastdfs/StructStorageStat.java | 31 ++-- .../org/csource/fastdfs/TrackerClient.java | 141 ++++++++++++------ src/test/java/org/csource/fastdfs/Test1.java | 2 +- 10 files changed, 237 insertions(+), 77 deletions(-) create mode 100644 src/main/java/org/csource/fastdfs/StructIPv4StorageStat.java create mode 100644 src/main/java/org/csource/fastdfs/StructIPv6StorageStat.java diff --git a/HISTORY b/HISTORY index 25e8be3..dfd20a5 100644 --- a/HISTORY +++ b/HISTORY @@ -1,4 +1,8 @@ +Version 1.33 2024-07-21 + * protocol automatically compatible with IPv4/IPv6 address + this version for FastDFS server V6.06 and higher version + Version 1.32 2024-02-12 * change FDFS_VERSION_SIZE from 6 to 8 you must upgrade your FastDFS server to V6.12 or higher version diff --git a/pom.xml b/pom.xml index 0b4cb6c..ec93418 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.csource fastdfs-client-java - 1.32-SNAPSHOT + 1.33-SNAPSHOT fastdfs-client-java fastdfs client for java jar diff --git a/src/main/java/org/csource/fastdfs/ClientGlobal.java b/src/main/java/org/csource/fastdfs/ClientGlobal.java index a135c94..b9138fe 100644 --- a/src/main/java/org/csource/fastdfs/ClientGlobal.java +++ b/src/main/java/org/csource/fastdfs/ClientGlobal.java @@ -86,9 +86,12 @@ public class ClientGlobal { private static void loadStorageServersFromTracker() throws IOException, MyException { TrackerClient tracker = new TrackerClient(); - StringBuilder builder = tracker.fetchStorageIds(); - if (builder.length() == 0) { - return; + StringBuilder builder = tracker.fetchStorageIds(true); + if (builder == null) { + builder = tracker.fetchStorageIds(false); + if (builder == null || builder.length() == 0) { + return; + } } boolean without_port = true; diff --git a/src/main/java/org/csource/fastdfs/ProtoCommon.java b/src/main/java/org/csource/fastdfs/ProtoCommon.java index e56c777..9d90b5c 100644 --- a/src/main/java/org/csource/fastdfs/ProtoCommon.java +++ b/src/main/java/org/csource/fastdfs/ProtoCommon.java @@ -73,16 +73,22 @@ public class ProtoCommon { public static final int FDFS_PROTO_PKG_LEN_SIZE = 8; public static final int FDFS_PROTO_CMD_SIZE = 1; public static final int FDFS_GROUP_NAME_MAX_LEN = 16; - public static final int FDFS_IPADDR_SIZE = 46; + public static final int FDFS_IPV4_SIZE = 16; + public static final int FDFS_IPV6_SIZE = 46; public static final int FDFS_DOMAIN_NAME_MAX_SIZE = 128; - public static final int FDFS_VERSION_SIZE = 8; + public static final int FDFS_OLD_VERSION_SIZE = 6; + public static final int FDFS_NEW_VERSION_SIZE = 8; public static final int FDFS_STORAGE_ID_MAX_SIZE = 16; public static final String FDFS_RECORD_SEPERATOR = "\u0001"; public static final String FDFS_FIELD_SEPERATOR = "\u0002"; - public static final int TRACKER_QUERY_STORAGE_FETCH_BODY_LEN = FDFS_GROUP_NAME_MAX_LEN - + FDFS_IPADDR_SIZE - 1 + FDFS_PROTO_PKG_LEN_SIZE; - public static final int TRACKER_QUERY_STORAGE_STORE_BODY_LEN = FDFS_GROUP_NAME_MAX_LEN - + FDFS_IPADDR_SIZE + FDFS_PROTO_PKG_LEN_SIZE; + public static final int TRACKER_QUERY_STORAGE_FETCH_IPV4_BODY_LEN = FDFS_GROUP_NAME_MAX_LEN + + FDFS_IPV4_SIZE - 1 + FDFS_PROTO_PKG_LEN_SIZE; + public static final int TRACKER_QUERY_STORAGE_FETCH_IPV6_BODY_LEN = FDFS_GROUP_NAME_MAX_LEN + + FDFS_IPV6_SIZE - 1 + FDFS_PROTO_PKG_LEN_SIZE; + public static final int TRACKER_QUERY_STORAGE_STORE_IPV4_BODY_LEN = FDFS_GROUP_NAME_MAX_LEN + + FDFS_IPV4_SIZE + FDFS_PROTO_PKG_LEN_SIZE; + public static final int TRACKER_QUERY_STORAGE_STORE_IPV6_BODY_LEN = FDFS_GROUP_NAME_MAX_LEN + + FDFS_IPV6_SIZE + FDFS_PROTO_PKG_LEN_SIZE; public static final byte FDFS_FILE_EXT_NAME_MAX_LEN = 6; public static final byte FDFS_FILE_PREFIX_MAX_LEN = 16; public static final byte FDFS_FILE_PATH_LEN = 10; diff --git a/src/main/java/org/csource/fastdfs/StorageClient.java b/src/main/java/org/csource/fastdfs/StorageClient.java index 9c608ee..cd2f26d 100644 --- a/src/main/java/org/csource/fastdfs/StorageClient.java +++ b/src/main/java/org/csource/fastdfs/StorageClient.java @@ -1575,19 +1575,28 @@ public class StorageClient { out.write(wholePkg); pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(), - ProtoCommon.STORAGE_PROTO_CMD_RESP, - 3 * ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE + - ProtoCommon.FDFS_IPADDR_SIZE); + ProtoCommon.STORAGE_PROTO_CMD_RESP, -1); this.errno = pkgInfo.errno; if (pkgInfo.errno != 0) { return null; } + int front_len = 3 * ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE; + int ip_size; + if (pkgInfo.body.length == front_len + ProtoCommon.FDFS_IPV6_SIZE) { //IPv6 + ip_size = ProtoCommon.FDFS_IPV6_SIZE; + } else if (pkgInfo.body.length == front_len + ProtoCommon.FDFS_IPV4_SIZE) { //IPv4 + ip_size = ProtoCommon.FDFS_IPV4_SIZE; + } else { + this.errno = ProtoCommon.ERR_NO_EINVAL; + throw new IOException("Invalid body length: " + pkgInfo.body.length); + } + long file_size = ProtoCommon.buff2long(pkgInfo.body, 0); int create_timestamp = (int) ProtoCommon.buff2long(pkgInfo.body, ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE); int crc32 = (int) ProtoCommon.buff2long(pkgInfo.body, 2 * ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE); - String source_ip_addr = (new String(pkgInfo.body, 3 * ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE, ProtoCommon.FDFS_IPADDR_SIZE)).trim(); + String source_ip_addr = (new String(pkgInfo.body, front_len, ip_size)).trim(); return new FileInfo(true, FileInfo.FILE_TYPE_NORMAL, file_size, create_timestamp, crc32, source_ip_addr); } catch (IOException ex) { diff --git a/src/main/java/org/csource/fastdfs/StructIPv4StorageStat.java b/src/main/java/org/csource/fastdfs/StructIPv4StorageStat.java new file mode 100644 index 0000000..a8d76c3 --- /dev/null +++ b/src/main/java/org/csource/fastdfs/StructIPv4StorageStat.java @@ -0,0 +1,45 @@ +/** + * Copyright (C) 2025 Happy Fish / YuQing + *

+ * FastDFS Java Client may be copied only under the terms of the GNU Lesser + * General Public License (LGPL). + * Please visit the FastDFS Home Page https://github.com/happyfish100/fastdfs for more detail. + */ + +package org.csource.fastdfs; + +import java.util.Date; + +/** + * C struct body decoder + * + * @author Happy Fish / YuQing + * @version Version 1.33 + */ +public class StructIPv4StorageStat extends StructStorageStat { + protected static int fieldsTotalSize; + protected static StructBase.FieldInfo[] fieldsArray = new StructBase.FieldInfo[StructStorageStat.FIELD_COUNT]; + + static { + fieldsTotalSize = StructStorageStat.initFieldsArray(fieldsArray, + ProtoCommon.FDFS_IPV4_SIZE, ProtoCommon.FDFS_OLD_VERSION_SIZE); + } + + /** + * get fields total size + * + * @return fields total size + */ + public static int getFieldsTotalSize() { + return fieldsTotalSize; + } + + /** + * + * @param bs byte array + * @param offset start offset + */ + public void setFields(byte[] bs, int offset) { + super.setFields(fieldsArray, bs, offset); + } +} diff --git a/src/main/java/org/csource/fastdfs/StructIPv6StorageStat.java b/src/main/java/org/csource/fastdfs/StructIPv6StorageStat.java new file mode 100644 index 0000000..ae1aca0 --- /dev/null +++ b/src/main/java/org/csource/fastdfs/StructIPv6StorageStat.java @@ -0,0 +1,45 @@ +/** + * Copyright (C) 2025 Happy Fish / YuQing + *

+ * FastDFS Java Client may be copied only under the terms of the GNU Lesser + * General Public License (LGPL). + * Please visit the FastDFS Home Page https://github.com/happyfish100/fastdfs for more detail. + */ + +package org.csource.fastdfs; + +import java.util.Date; + +/** + * C struct body decoder + * + * @author Happy Fish / YuQing + * @version Version 1.33 + */ +public class StructIPv6StorageStat extends StructStorageStat { + protected static int fieldsTotalSize; + protected static StructBase.FieldInfo[] fieldsArray = new StructBase.FieldInfo[StructStorageStat.FIELD_COUNT]; + + static { + fieldsTotalSize = StructStorageStat.initFieldsArray(fieldsArray, + ProtoCommon.FDFS_IPV6_SIZE, ProtoCommon.FDFS_NEW_VERSION_SIZE); + } + + /** + * get fields total size + * + * @return fields total size + */ + public static int getFieldsTotalSize() { + return fieldsTotalSize; + } + + /** + * + * @param bs byte array + * @param offset start offset + */ + public void setFields(byte[] bs, int offset) { + super.setFields(fieldsArray, bs, offset); + } +} diff --git a/src/main/java/org/csource/fastdfs/StructStorageStat.java b/src/main/java/org/csource/fastdfs/StructStorageStat.java index 7d17f5e..7693921 100644 --- a/src/main/java/org/csource/fastdfs/StructStorageStat.java +++ b/src/main/java/org/csource/fastdfs/StructStorageStat.java @@ -14,7 +14,7 @@ import java.util.Date; * C struct body decoder * * @author Happy Fish / YuQing - * @version Version 1.25 + * @version Version 1.33 */ public class StructStorageStat extends StructBase { protected static final int FIELD_INDEX_STATUS = 0; @@ -82,10 +82,9 @@ public class StructStorageStat extends StructBase { protected static final int FIELD_INDEX_LAST_HEART_BEAT_TIME = 60; protected static final int FIELD_INDEX_IF_TRUNK_FILE = 61; - protected static int fieldsTotalSize; - protected static StructBase.FieldInfo[] fieldsArray = new StructBase.FieldInfo[62]; + protected static final int FIELD_COUNT = 62; - static { + protected static int initFieldsArray(StructBase.FieldInfo[] fieldsArray, int ipaddr_size, int version_size) { int offset = 0; fieldsArray[FIELD_INDEX_STATUS] = new StructBase.FieldInfo("status", offset, 1); @@ -94,8 +93,8 @@ public class StructStorageStat extends StructBase { fieldsArray[FIELD_INDEX_ID] = new StructBase.FieldInfo("id", offset, ProtoCommon.FDFS_STORAGE_ID_MAX_SIZE); offset += ProtoCommon.FDFS_STORAGE_ID_MAX_SIZE; - fieldsArray[FIELD_INDEX_IP_ADDR] = new StructBase.FieldInfo("ipAddr", offset, ProtoCommon.FDFS_IPADDR_SIZE); - offset += ProtoCommon.FDFS_IPADDR_SIZE; + fieldsArray[FIELD_INDEX_IP_ADDR] = new StructBase.FieldInfo("ipAddr", offset, ipaddr_size); + offset += ipaddr_size; fieldsArray[FIELD_INDEX_DOMAIN_NAME] = new StructBase.FieldInfo("domainName", offset, ProtoCommon.FDFS_DOMAIN_NAME_MAX_SIZE); offset += ProtoCommon.FDFS_DOMAIN_NAME_MAX_SIZE; @@ -103,8 +102,8 @@ public class StructStorageStat extends StructBase { fieldsArray[FIELD_INDEX_SRC_ID] = new StructBase.FieldInfo("srcId", offset, ProtoCommon.FDFS_STORAGE_ID_MAX_SIZE); offset += ProtoCommon.FDFS_STORAGE_ID_MAX_SIZE; - fieldsArray[FIELD_INDEX_VERSION] = new StructBase.FieldInfo("version", offset, ProtoCommon.FDFS_VERSION_SIZE); - offset += ProtoCommon.FDFS_VERSION_SIZE; + fieldsArray[FIELD_INDEX_VERSION] = new StructBase.FieldInfo("version", offset, version_size); + offset += version_size; fieldsArray[FIELD_INDEX_JOIN_TIME] = new StructBase.FieldInfo("joinTime", offset, ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE); offset += ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE; @@ -274,7 +273,7 @@ public class StructStorageStat extends StructBase { fieldsArray[FIELD_INDEX_IF_TRUNK_FILE] = new StructBase.FieldInfo("ifTrunkServer", offset, 1); offset += 1; - fieldsTotalSize = offset; + return offset; } protected byte status; @@ -340,15 +339,6 @@ public class StructStorageStat extends StructBase { protected Date lastHeartBeatTime; protected boolean ifTrunkServer; - /** - * get fields total size - * - * @return fields total size - */ - public static int getFieldsTotalSize() { - return fieldsTotalSize; - } - /** * get storage status * @@ -913,7 +903,7 @@ public class StructStorageStat extends StructBase { * @param bs byte array * @param offset start offset */ - public void setFields(byte[] bs, int offset) { + protected void setFields(StructBase.FieldInfo[] fieldsArray, byte[] bs, int offset) { this.status = byteValue(bs, offset, fieldsArray[FIELD_INDEX_STATUS]); this.id = stringValue(bs, offset, fieldsArray[FIELD_INDEX_ID]); this.ipAddr = stringValue(bs, offset, fieldsArray[FIELD_INDEX_IP_ADDR]); @@ -979,4 +969,7 @@ public class StructStorageStat extends StructBase { this.lastHeartBeatTime = dateValue(bs, offset, fieldsArray[FIELD_INDEX_LAST_HEART_BEAT_TIME]); this.ifTrunkServer = booleanValue(bs, offset, fieldsArray[FIELD_INDEX_IF_TRUNK_FILE]); } + + public void setFields(byte[] bs, int offset) { + } } diff --git a/src/main/java/org/csource/fastdfs/TrackerClient.java b/src/main/java/org/csource/fastdfs/TrackerClient.java index 29312cb..101891f 100644 --- a/src/main/java/org/csource/fastdfs/TrackerClient.java +++ b/src/main/java/org/csource/fastdfs/TrackerClient.java @@ -183,18 +183,30 @@ public class TrackerClient { } ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(), - ProtoCommon.TRACKER_PROTO_CMD_RESP, - ProtoCommon.TRACKER_QUERY_STORAGE_STORE_BODY_LEN); + ProtoCommon.TRACKER_PROTO_CMD_RESP, -1); this.errno = pkgInfo.errno; if (pkgInfo.errno != 0) { return null; } - ip_addr = new String(pkgInfo.body, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN, ProtoCommon.FDFS_IPADDR_SIZE - 1).trim(); + if (pkgInfo.body.length < ProtoCommon.TRACKER_QUERY_STORAGE_STORE_IPV4_BODY_LEN) { + this.errno = ProtoCommon.ERR_NO_EINVAL; + throw new IOException("Invalid body length: " + pkgInfo.body.length); + } - port = (int) ProtoCommon.buff2long(pkgInfo.body, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN - + ProtoCommon.FDFS_IPADDR_SIZE - 1); - store_path = pkgInfo.body[ProtoCommon.TRACKER_QUERY_STORAGE_STORE_BODY_LEN - 1]; + int ip_size; + if (pkgInfo.body.length == ProtoCommon.TRACKER_QUERY_STORAGE_STORE_IPV6_BODY_LEN) { + ip_size = ProtoCommon.FDFS_IPV6_SIZE; + } else if (pkgInfo.body.length == ProtoCommon.TRACKER_QUERY_STORAGE_STORE_IPV4_BODY_LEN) { + ip_size = ProtoCommon.FDFS_IPV4_SIZE; + } else { + this.errno = ProtoCommon.ERR_NO_EINVAL; + throw new IOException("Invalid body length: " + pkgInfo.body.length); + } + + ip_addr = new String(pkgInfo.body, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN, ip_size - 1).trim(); + port = (int) ProtoCommon.buff2long(pkgInfo.body, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + ip_size - 1); + store_path = pkgInfo.body[pkgInfo.body.length - 1]; return new StorageServer(ip_addr, port, store_path); } catch (IOException ex) { @@ -269,17 +281,26 @@ public class TrackerClient { return null; } - if (pkgInfo.body.length < ProtoCommon.TRACKER_QUERY_STORAGE_STORE_BODY_LEN) { + if (pkgInfo.body.length < ProtoCommon.TRACKER_QUERY_STORAGE_STORE_IPV4_BODY_LEN) { this.errno = ProtoCommon.ERR_NO_EINVAL; - return null; + throw new IOException("Invalid body length: " + pkgInfo.body.length); } int ipPortLen = pkgInfo.body.length - (ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + 1); - final int recordLength = ProtoCommon.FDFS_IPADDR_SIZE - 1 + ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE; - - if (ipPortLen % recordLength != 0) { - this.errno = ProtoCommon.ERR_NO_EINVAL; - return null; + int recordLength = ProtoCommon.FDFS_IPV6_SIZE - 1 + ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE; + int ip_size; + if ((pkgInfo.body.length >= ProtoCommon.TRACKER_QUERY_STORAGE_STORE_IPV6_BODY_LEN) && + ipPortLen % recordLength == 0) + { + ip_size = ProtoCommon.FDFS_IPV6_SIZE; + } else { + recordLength = ProtoCommon.FDFS_IPV4_SIZE - 1 + ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE; + if (ipPortLen % recordLength == 0) { + ip_size = ProtoCommon.FDFS_IPV4_SIZE; + } else { + this.errno = ProtoCommon.ERR_NO_EINVAL; + throw new IOException("Invalid body length: " + pkgInfo.body.length); + } } int serverCount = ipPortLen / recordLength; @@ -293,8 +314,8 @@ public class TrackerClient { int offset = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN; for (int i = 0; i < serverCount; i++) { - ip_addr = new String(pkgInfo.body, offset, ProtoCommon.FDFS_IPADDR_SIZE - 1).trim(); - offset += ProtoCommon.FDFS_IPADDR_SIZE - 1; + ip_addr = new String(pkgInfo.body, offset, ip_size - 1).trim(); + offset += ip_size - 1; port = (int) ProtoCommon.buff2long(pkgInfo.body, offset); offset += ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE; @@ -424,18 +445,33 @@ public class TrackerClient { return null; } - if (pkgInfo.body.length < ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_BODY_LEN) { + int server_count = 1; + int ip_size; + if (pkgInfo.body.length < ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_IPV4_BODY_LEN) { + this.errno = ProtoCommon.ERR_NO_EINVAL; throw new IOException("Invalid body length: " + pkgInfo.body.length); } - if ((pkgInfo.body.length - ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_BODY_LEN) % (ProtoCommon.FDFS_IPADDR_SIZE - 1) != 0) { + if ((pkgInfo.body.length >= ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_IPV6_BODY_LEN) && + (pkgInfo.body.length - ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_IPV6_BODY_LEN) % + (ProtoCommon.FDFS_IPV6_SIZE - 1) == 0) + { + ip_size = ProtoCommon.FDFS_IPV6_SIZE; + server_count += (pkgInfo.body.length - ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_IPV6_BODY_LEN) / + (ProtoCommon.FDFS_IPV6_SIZE - 1); + } else if ((pkgInfo.body.length - ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_IPV4_BODY_LEN) % + (ProtoCommon.FDFS_IPV4_SIZE - 1) == 0) + { + ip_size = ProtoCommon.FDFS_IPV4_SIZE; + server_count += (pkgInfo.body.length - ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_IPV4_BODY_LEN) / + (ProtoCommon.FDFS_IPV4_SIZE - 1); + } else { + this.errno = ProtoCommon.ERR_NO_EINVAL; throw new IOException("Invalid body length: " + pkgInfo.body.length); } - int server_count = 1 + (pkgInfo.body.length - ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_BODY_LEN) / (ProtoCommon.FDFS_IPADDR_SIZE - 1); - - ip_addr = new String(pkgInfo.body, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN, ProtoCommon.FDFS_IPADDR_SIZE - 1).trim(); - int offset = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + ProtoCommon.FDFS_IPADDR_SIZE - 1; + ip_addr = new String(pkgInfo.body, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN, ip_size - 1).trim(); + int offset = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + ip_size - 1; port = (int) ProtoCommon.buff2long(pkgInfo.body, offset); offset += ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE; @@ -443,8 +479,8 @@ public class TrackerClient { ServerInfo[] servers = new ServerInfo[server_count]; servers[0] = new ServerInfo(ip_addr, port); for (int i = 1; i < server_count; i++) { - servers[i] = new ServerInfo(new String(pkgInfo.body, offset, ProtoCommon.FDFS_IPADDR_SIZE - 1).trim(), port); - offset += ProtoCommon.FDFS_IPADDR_SIZE - 1; + servers[i] = new ServerInfo(new String(pkgInfo.body, offset, ip_size - 1).trim(), port); + offset += ip_size - 1; } return servers; @@ -568,6 +604,20 @@ public class TrackerClient { return this.listStorages(trackerServer, groupName, storageIpAddr); } + private int getIpaddrLength(String ip, byte[] bIpAddr) { + if (bIpAddr.length < ProtoCommon.FDFS_IPV4_SIZE) { + return bIpAddr.length; + } else if (ip.indexOf(':') >= 0) { //IPv6 address + if (bIpAddr.length < ProtoCommon.FDFS_IPV6_SIZE) { + return bIpAddr.length; + } else { + return ProtoCommon.FDFS_IPV6_SIZE - 1; + } + } else { //IPv4 address + return ProtoCommon.FDFS_IPV4_SIZE - 1; + } + } + /** * query storage server stat info of the group * @@ -576,8 +626,8 @@ public class TrackerClient { * @param storageIpAddr the storage server ip address, can be null or empty * @return storage server stat array, return null if fail */ - public StructStorageStat[] listStorages(TrackerServer trackerServer, - String groupName, String storageIpAddr) throws IOException, MyException { + public StructStorageStat[] listStorages(TrackerServer trackerServer, String groupName, + String storageIpAddr) throws IOException, MyException { byte[] header; byte[] bGroupName; byte[] bs; @@ -601,11 +651,7 @@ public class TrackerClient { byte[] bIpAddr; if (storageIpAddr != null && storageIpAddr.length() > 0) { bIpAddr = storageIpAddr.getBytes(ClientGlobal.g_charset); - if (bIpAddr.length < ProtoCommon.FDFS_IPADDR_SIZE) { - ipAddrLen = bIpAddr.length; - } else { - ipAddrLen = ProtoCommon.FDFS_IPADDR_SIZE - 1; - } + ipAddrLen = getIpaddrLength(storageIpAddr, bIpAddr); } else { bIpAddr = null; ipAddrLen = 0; @@ -627,8 +673,15 @@ public class TrackerClient { return null; } - ProtoStructDecoder decoder = new ProtoStructDecoder(); - return decoder.decode(pkgInfo.body, StructStorageStat.class, StructStorageStat.getFieldsTotalSize()); + if (pkgInfo.body.length % StructIPv6StorageStat.getFieldsTotalSize() == 0) { + ProtoStructDecoder decoder = new ProtoStructDecoder(); + return decoder.decode(pkgInfo.body, StructIPv6StorageStat.class, + StructIPv6StorageStat.getFieldsTotalSize()); + } else { + ProtoStructDecoder decoder = new ProtoStructDecoder(); + return decoder.decode(pkgInfo.body, StructIPv4StorageStat.class, + StructIPv4StorageStat.getFieldsTotalSize()); + } } catch (IOException ex) { try { connection.close(); @@ -683,14 +736,8 @@ public class TrackerClient { Arrays.fill(bGroupName, (byte) 0); System.arraycopy(bs, 0, bGroupName, 0, len); - int ipAddrLen; byte[] bIpAddr = storageIpAddr.getBytes(ClientGlobal.g_charset); - if (bIpAddr.length < ProtoCommon.FDFS_IPADDR_SIZE) { - ipAddrLen = bIpAddr.length; - } else { - ipAddrLen = ProtoCommon.FDFS_IPADDR_SIZE - 1; - } - + int ipAddrLen = getIpaddrLength(storageIpAddr, bIpAddr); header = ProtoCommon.packHeader(ProtoCommon.TRACKER_PROTO_CMD_SERVER_DELETE_STORAGE, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + ipAddrLen, (byte) 0); byte[] wholePkg = new byte[header.length + bGroupName.length + ipAddrLen]; System.arraycopy(header, 0, wholePkg, 0, header.length); @@ -814,7 +861,7 @@ public class TrackerClient { * @param groupName the group name to upload file to, can be empty * @return storage server object, return null if fail */ - public StringBuilder fetchStorageIds() throws IOException, MyException { + public StringBuilder fetchStorageIds(boolean haveAllowEmptyField) throws IOException, MyException { byte[] header; int offset = 0; int length; @@ -823,13 +870,21 @@ public class TrackerClient { Connection connection = getConnection(null); try { + int reqBodyLength; OutputStream out = connection.getOutputStream(); StringBuilder builder = new StringBuilder(); - header = ProtoCommon.packHeader(ProtoCommon.TRACKER_PROTO_CMD_FETCH_STORAGE_IDS, 5, (byte)0); - byte[] wholePkg = new byte[header.length + 5]; + if (haveAllowEmptyField) { + reqBodyLength = 5; + } else { + reqBodyLength = 4; + } + header = ProtoCommon.packHeader(ProtoCommon.TRACKER_PROTO_CMD_FETCH_STORAGE_IDS, reqBodyLength, (byte)0); + byte[] wholePkg = new byte[header.length + reqBodyLength]; System.arraycopy(header, 0, wholePkg, 0, header.length); - wholePkg[wholePkg.length - 1] = 1; + if (haveAllowEmptyField) { + wholePkg[wholePkg.length - 1] = 1; + } do { byte[] bs = ProtoCommon.int2buff(offset); System.arraycopy(bs, 0, wholePkg, header.length, bs.length); diff --git a/src/test/java/org/csource/fastdfs/Test1.java b/src/test/java/org/csource/fastdfs/Test1.java index 4e85cc8..993a3ff 100644 --- a/src/test/java/org/csource/fastdfs/Test1.java +++ b/src/test/java/org/csource/fastdfs/Test1.java @@ -35,7 +35,7 @@ public class Test1 { System.out.println("network_timeout=" + ClientGlobal.g_network_timeout + "ms"); System.out.println("charset=" + ClientGlobal.g_charset); - TrackerGroup tg = new TrackerGroup(new InetSocketAddress[]{new InetSocketAddress("47.95.221.159", 22122)}); + TrackerGroup tg = new TrackerGroup(new InetSocketAddress[]{new InetSocketAddress("192.168.3.202", 22122)}); TrackerClient tc = new TrackerClient(tg); TrackerServer ts = tc.getTrackerServer();