8 Commits
14 changed files with 184 additions and 131 deletions
+13
View File
@@ -1,4 +1,17 @@
Version 1.40 2026-06-28
* ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ALL protocol changed
you must upgrade your FastDFS server V6.16.0 and higher version
Version 1.39 2025-12-19
* ConnectionPool.getKey() use '-' instead of ':'
* ConnectionManager.java: remove private AtomicInteger freeCount
* ConnectionManager.java: prevent re-entrancy for closeConnection
Version 1.38 2025-11-28
* bugfixed: loadStorageServersFromTracker correctly with rw option
* throw IOException with msg "connection broken" when in.read() < 0
Version 1.37 2025-11-06
* query file info support two combined flags:
ProtoCommon.FDFS_QUERY_FINFO_FLAGS_NOT_CALC_CRC32
+4 -4
View File
@@ -26,7 +26,7 @@ mvn install:install-file -DgroupId=org.csource -DartifactId=fastdfs-client-java
<dependency>
<groupId>org.csource</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.31-SNAPSHOT</version>
<version>1.39-SNAPSHOT</version>
</dependency>
```
@@ -57,7 +57,7 @@ tracker_server = 10.0.11.249:22122
connection_pool.enabled = true
connection_pool.max_count_per_entry = 500
connection_pool.max_idle_time = 3600
connection_pool.max_wait_time_in_ms = 1000
connection_pool.max_wait_time_in_ms = 3000
```
注1tracker_server指向您自己IP地址和端口,1-n个
@@ -89,7 +89,7 @@ fastdfs.tracker_servers = 10.0.11.201:22122,10.0.11.202:22122,10.0.11.203:22122
fastdfs.connection_pool.enabled = true
fastdfs.connection_pool.max_count_per_entry = 500
fastdfs.connection_pool.max_idle_time = 3600
fastdfs.connection_pool.max_wait_time_in_ms = 1000
fastdfs.connection_pool.max_wait_time_in_ms = 3000
```
注1properties 配置文件中属性名跟 conf 配置文件不尽相同,并且统一加前缀"fastdfs.",便于整合到用户项目配置文件
@@ -135,7 +135,7 @@ ClientGlobal.configInfo(): {
g_connection_pool_enabled = true
g_connection_pool_max_count_per_entry = 500
g_connection_pool_max_idle_time(ms) = 3600000
g_connection_pool_max_wait_time_in_ms(ms) = 1000
g_connection_pool_max_wait_time_in_ms(ms) = 3000
trackerServers = 10.0.11.101:22122,10.0.11.102:22122
}
```
+1 -1
View File
@@ -4,7 +4,7 @@
<target name="init">
<property name="project.name" value="fastdfs-client-java"/>
<property name="project.version" value="1.27-SNAPSHOT"/>
<property name="project.version" value="1.39-SNAPSHOT"/>
<property name="project.java" value="${basedir}/src/main/java"/>
<property name="project.resources" value="${basedir}/src/main/resources"/>
<property name="project.build" value="${basedir}/build"/>
+1 -1
View File
@@ -21,4 +21,4 @@ fastdfs.connection_pool.max_count_per_entry = 500
fastdfs.connection_pool.max_idle_time = 3600
## Maximum waiting time when the maximum number of connections is reached, unit: millisecond, default value is 1000
fastdfs.connection_pool.max_wait_time_in_ms = 1000
fastdfs.connection_pool.max_wait_time_in_ms = 3000
+1 -1
View File
@@ -25,4 +25,4 @@ connect_first_by = tracker
connection_pool.enabled = true
connection_pool.max_count_per_entry = 500
connection_pool.max_idle_time = 3600
connection_pool.max_wait_time_in_ms = 1000
connection_pool.max_wait_time_in_ms = 3000
+1 -1
View File
@@ -4,7 +4,7 @@
<groupId>org.csource</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.37-SNAPSHOT</version>
<version>1.40-SNAPSHOT</version>
<name>fastdfs-client-java</name>
<description>fastdfs client for java</description>
<packaging>jar</packaging>
@@ -106,7 +106,7 @@ public class ClientGlobal {
String[] ipAddresses = new String[lines.length];
for (String line : lines) {
String[] cols = line.split(" ");
if (cols.length != 3) {
if (!(cols.length == 3 || cols.length == 4)) {
throw new MyException("invalid line: " + line);
}
@@ -15,6 +15,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.InetSocketAddress;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
@@ -174,35 +175,48 @@ public class ProtoCommon {
* @param expect_body_len expect response package body length
* @return RecvHeaderInfo: errno and pkg body length
*/
public static RecvHeaderInfo recvHeader(InputStream in, byte expect_cmd, long expect_body_len) throws IOException {
byte[] header;
int bytes;
long pkg_len;
public static RecvHeaderInfo recvHeader(InputStream in, InetSocketAddress socketAddr,
byte expect_cmd, long expect_body_len) throws IOException
{
byte[] header;
int bytes;
long pkg_len;
header = new byte[FDFS_PROTO_PKG_LEN_SIZE + 2];
header = new byte[FDFS_PROTO_PKG_LEN_SIZE + 2];
bytes = in.read(header);
if (bytes != header.length) {
if (bytes < 0) {
throw new IOException("server " + socketAddr.getAddress().getHostAddress()
+ ":" + socketAddr.getPort() + ", connection broken");
} else {
throw new IOException("server " + socketAddr.getAddress().getHostAddress() + ":"
+ socketAddr.getPort() + ", recv package size " + bytes + " != " + header.length);
}
}
if ((bytes = in.read(header)) != header.length) {
throw new IOException("recv package size " + bytes + " != " + header.length);
}
if (header[PROTO_HEADER_CMD_INDEX] != expect_cmd) {
throw new IOException("server " + socketAddr.getAddress().getHostAddress() + ":"
+ socketAddr.getPort() + ", recv cmd: " + header[PROTO_HEADER_CMD_INDEX]
+ " is not correct, expect cmd: " + expect_cmd);
}
if (header[PROTO_HEADER_CMD_INDEX] != expect_cmd) {
throw new IOException("recv cmd: " + header[PROTO_HEADER_CMD_INDEX] + " is not correct, expect cmd: " + expect_cmd);
}
if (header[PROTO_HEADER_STATUS_INDEX] != 0) {
return new RecvHeaderInfo(header[PROTO_HEADER_STATUS_INDEX], 0);
}
if (header[PROTO_HEADER_STATUS_INDEX] != 0) {
return new RecvHeaderInfo(header[PROTO_HEADER_STATUS_INDEX], 0);
}
pkg_len = ProtoCommon.buff2long(header, 0);
if (pkg_len < 0) {
throw new IOException("server " + socketAddr.getAddress().getHostAddress() + ":"
+ socketAddr.getPort() + ", recv body length: " + pkg_len + " < 0!");
}
pkg_len = ProtoCommon.buff2long(header, 0);
if (pkg_len < 0) {
throw new IOException("recv body length: " + pkg_len + " < 0!");
}
if (expect_body_len >= 0 && pkg_len != expect_body_len) {
throw new IOException("server " + socketAddr.getAddress().getHostAddress() + ":"
+ socketAddr.getPort() + ", recv body length: " + pkg_len
+ " is not correct, expect length: " + expect_body_len);
}
if (expect_body_len >= 0 && pkg_len != expect_body_len) {
throw new IOException("recv body length: " + pkg_len + " is not correct, expect length: " + expect_body_len);
}
return new RecvHeaderInfo((byte) 0, pkg_len);
return new RecvHeaderInfo((byte)0, pkg_len);
}
/**
@@ -213,31 +227,40 @@ public class ProtoCommon {
* @param expect_body_len expect response package body length
* @return RecvPackageInfo: errno and reponse body(byte buff)
*/
public static RecvPackageInfo recvPackage(InputStream in, byte expect_cmd, long expect_body_len) throws IOException {
RecvHeaderInfo header = recvHeader(in, expect_cmd, expect_body_len);
if (header.errno != 0) {
return new RecvPackageInfo(header.errno, null);
}
byte[] body = new byte[(int) header.body_len];
int totalBytes = 0;
int remainBytes = (int) header.body_len;
int bytes;
while (totalBytes < header.body_len) {
if ((bytes = in.read(body, totalBytes, remainBytes)) < 0) {
break;
public static RecvPackageInfo recvPackage(InputStream in, InetSocketAddress socketAddr,
byte expect_cmd, long expect_body_len) throws IOException
{
RecvHeaderInfo header = recvHeader(in, socketAddr, expect_cmd, expect_body_len);
if (header.errno != 0) {
return new RecvPackageInfo(header.errno, null);
}
totalBytes += bytes;
remainBytes -= bytes;
}
byte[] body = new byte[(int) header.body_len];
int totalBytes = 0;
int remainBytes = (int) header.body_len;
int bytes = 0;
if (totalBytes != header.body_len) {
throw new IOException("recv package size " + totalBytes + " != " + header.body_len);
}
while (totalBytes < header.body_len) {
if ((bytes = in.read(body, totalBytes, remainBytes)) < 0) {
break;
}
return new RecvPackageInfo((byte) 0, body);
totalBytes += bytes;
remainBytes -= bytes;
}
if (totalBytes != header.body_len) {
String msg = "server " + socketAddr.getAddress().getHostAddress()
+ ":" + socketAddr.getPort() + " connection broken";
if (totalBytes == 0) {
throw new IOException(msg);
} else {
throw new IOException(msg + ", recv length: " + totalBytes
+ ", expect length: " + header.body_len);
}
}
return new RecvPackageInfo((byte)0, body);
}
/**
@@ -320,7 +343,8 @@ public class ProtoCommon {
header = packHeader(FDFS_PROTO_CMD_ACTIVE_TEST, 0, (byte) 0);
sock.getOutputStream().write(header);
RecvHeaderInfo headerInfo = recvHeader(sock.getInputStream(), TRACKER_PROTO_CMD_RESP, 0);
InetSocketAddress socketAddr = new InetSocketAddress(sock.getInetAddress(), sock.getPort());
RecvHeaderInfo headerInfo = recvHeader(sock.getInputStream(), socketAddr, TRACKER_PROTO_CMD_RESP, 0);
return headerInfo.errno == 0 ? true : false;
}
@@ -656,7 +656,7 @@ public class StorageClient {
out.write(wholePkg);
ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.STORAGE_PROTO_CMD_RESP, -1);
connection.getInetSocketAddress(), ProtoCommon.STORAGE_PROTO_CMD_RESP, -1);
this.errno = pkgInfo.errno;
if (pkgInfo.errno != 0) {
return null;
@@ -801,7 +801,7 @@ public class StorageClient {
}
ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.STORAGE_PROTO_CMD_RESP, -1);
connection.getInetSocketAddress(), ProtoCommon.STORAGE_PROTO_CMD_RESP, -1);
this.errno = pkgInfo.errno;
if (pkgInfo.errno != 0) {
return null;
@@ -907,7 +907,7 @@ public class StorageClient {
}
ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.STORAGE_PROTO_CMD_RESP, 0);
connection.getInetSocketAddress(), ProtoCommon.STORAGE_PROTO_CMD_RESP, 0);
this.errno = pkgInfo.errno;
if (pkgInfo.errno != 0) {
return this.errno;
@@ -1004,7 +1004,7 @@ public class StorageClient {
}
ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.STORAGE_PROTO_CMD_RESP, 0);
connection.getInetSocketAddress(), ProtoCommon.STORAGE_PROTO_CMD_RESP, 0);
this.errno = pkgInfo.errno;
if (pkgInfo.errno != 0) {
return this.errno;
@@ -1040,7 +1040,7 @@ public class StorageClient {
try {
this.send_package(ProtoCommon.STORAGE_PROTO_CMD_DELETE_FILE, group_name, remote_filename, connection);
ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.STORAGE_PROTO_CMD_RESP, 0);
connection.getInetSocketAddress(), ProtoCommon.STORAGE_PROTO_CMD_RESP, 0);
this.errno = pkgInfo.errno;
return pkgInfo.errno;
@@ -1122,7 +1122,7 @@ public class StorageClient {
out.write(wholePkg);
ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.STORAGE_PROTO_CMD_RESP, 0);
connection.getInetSocketAddress(), ProtoCommon.STORAGE_PROTO_CMD_RESP, 0);
this.errno = pkgInfo.errno;
return pkgInfo.errno;
} catch (IOException ex) {
@@ -1171,7 +1171,7 @@ public class StorageClient {
this.send_download_package(group_name, remote_filename, file_offset, download_bytes, connection);
pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.STORAGE_PROTO_CMD_RESP, -1);
connection.getInetSocketAddress(), ProtoCommon.STORAGE_PROTO_CMD_RESP, -1);
this.errno = pkgInfo.errno;
if (pkgInfo.errno != 0) {
@@ -1232,7 +1232,7 @@ public class StorageClient {
this.send_download_package(group_name, remote_filename, file_offset, download_bytes, connection);
InputStream in = connection.getInputStream();
header = ProtoCommon.recvHeader(in, ProtoCommon.STORAGE_PROTO_CMD_RESP, -1);
header = ProtoCommon.recvHeader(in, connection.getInetSocketAddress(), ProtoCommon.STORAGE_PROTO_CMD_RESP, -1);
this.errno = header.errno;
if (header.errno != 0) {
return header.errno;
@@ -1320,7 +1320,7 @@ public class StorageClient {
this.send_download_package(group_name, remote_filename, file_offset, download_bytes, connection);
InputStream in = connection.getInputStream();
header = ProtoCommon.recvHeader(in, ProtoCommon.STORAGE_PROTO_CMD_RESP, -1);
header = ProtoCommon.recvHeader(in, connection.getInetSocketAddress(), ProtoCommon.STORAGE_PROTO_CMD_RESP, -1);
this.errno = header.errno;
if (header.errno != 0) {
return header.errno;
@@ -1376,7 +1376,7 @@ public class StorageClient {
this.send_package(ProtoCommon.STORAGE_PROTO_CMD_GET_METADATA, group_name, remote_filename, connection);
pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.STORAGE_PROTO_CMD_RESP, -1);
connection.getInetSocketAddress(), ProtoCommon.STORAGE_PROTO_CMD_RESP, -1);
this.errno = pkgInfo.errno;
if (pkgInfo.errno != 0) {
@@ -1467,7 +1467,7 @@ public class StorageClient {
}
pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.STORAGE_PROTO_CMD_RESP, 0);
connection.getInetSocketAddress(), ProtoCommon.STORAGE_PROTO_CMD_RESP, 0);
this.errno = pkgInfo.errno;
return pkgInfo.errno;
@@ -1580,7 +1580,7 @@ public class StorageClient {
out.write(wholePkg);
pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.STORAGE_PROTO_CMD_RESP, -1);
connection.getInetSocketAddress(), ProtoCommon.STORAGE_PROTO_CMD_RESP, -1);
this.errno = pkgInfo.errno;
if (pkgInfo.errno != 0) {
@@ -85,13 +85,13 @@ public class TrackerClient {
connection = trackerServer.getConnection();
} catch (IOException e) {
if (failOver) {
System.err.println("trackerServer get connection error, emsg:" + e.getMessage());
System.err.println("trackerServer get connection error, " + e.getMessage());
} else {
throw e;
}
} catch (MyException e) {
if (failOver) {
System.err.println("trackerServer get connection error, emsg:" + e.getMessage());
System.err.println("trackerServer get connection error, " + e.getMessage());
} else {
throw e;
}
@@ -118,19 +118,19 @@ public class TrackerClient {
}
return trackerServer.getConnection();
} catch (IOException e) {
System.err.println("fail over trackerServer get connection error, failOverCount:" + failOverCount + "," + e.getMessage());
System.err.println("fail over trackerServer get connection error, "
+ "failOverCount: " + failOverCount + ", " + e.getMessage());
if (failOverCount == length - 1) {
throw e;
}
} catch (MyException e) {
System.err.println("fail over trackerServer get connection error, failOverCount:" + failOverCount + ", " + e.getMessage());
System.err.println("fail over trackerServer get connection error, "
+ "failOverCount: " + failOverCount + ", " + e.getMessage());
if (failOverCount == length - 1) {
throw e;
}
}
}
return null;
}
@@ -183,7 +183,7 @@ public class TrackerClient {
}
ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
connection.getInetSocketAddress(), ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
this.errno = pkgInfo.errno;
if (pkgInfo.errno != 0) {
return null;
@@ -275,7 +275,7 @@ public class TrackerClient {
}
ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
connection.getInetSocketAddress(), ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
this.errno = pkgInfo.errno;
if (pkgInfo.errno != 0) {
return null;
@@ -353,7 +353,8 @@ public class TrackerClient {
* @return storage server Socket object, return null if fail
*/
public StorageServer getFetchStorage(TrackerServer trackerServer,
String groupName, String filename) throws IOException, MyException {
String groupName, String filename) throws IOException, MyException
{
ServerInfo[] servers = this.getStorages(trackerServer, ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ONE,
groupName, filename);
if (servers == null) {
@@ -372,7 +373,8 @@ public class TrackerClient {
* @return storage server Socket object, return null if fail
*/
public StorageServer getUpdateStorage(TrackerServer trackerServer,
String groupName, String filename) throws IOException, MyException {
String groupName, String filename) throws IOException, MyException
{
ServerInfo[] servers = this.getStorages(trackerServer, ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_UPDATE,
groupName, filename);
if (servers == null) {
@@ -391,7 +393,8 @@ public class TrackerClient {
* @return storage servers, return null if fail
*/
public ServerInfo[] getFetchStorages(TrackerServer trackerServer,
String groupName, String filename) throws IOException, MyException {
String groupName, String filename) throws IOException, MyException
{
return this.getStorages(trackerServer, ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ALL,
groupName, filename);
}
@@ -400,14 +403,17 @@ public class TrackerClient {
* query storage server to download file
*
* @param trackerServer the tracker server
* @param cmd command code, ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ONE or
* ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_UPDATE
* @param cmd command code, values list:
* ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ONE
* ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ALL
* ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_UPDATE
* @param groupName the group name of storage server
* @param filename filename on storage server
* @return storage server Socket object, return null if fail
*/
protected ServerInfo[] getStorages(TrackerServer trackerServer,
byte cmd, String groupName, String filename) throws IOException, MyException {
protected ServerInfo[] getStorages(TrackerServer trackerServer, byte cmd,
String groupName, String filename) throws IOException, MyException
{
byte[] header;
byte[] bFileName;
byte[] bGroupName;
@@ -439,7 +445,7 @@ public class TrackerClient {
out.write(wholePkg);
ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
connection.getInetSocketAddress(), ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
this.errno = pkgInfo.errno;
if (pkgInfo.errno != 0) {
return null;
@@ -454,33 +460,32 @@ public class TrackerClient {
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)
(ProtoCommon.FDFS_IPV6_SIZE - 1 + ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE) == 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);
(ProtoCommon.FDFS_IPV6_SIZE - 1 + ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE);
} else if ((pkgInfo.body.length - ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_IPV4_BODY_LEN) %
(ProtoCommon.FDFS_IPV4_SIZE - 1) == 0)
(ProtoCommon.FDFS_IPV4_SIZE - 1 + ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE) == 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);
(ProtoCommon.FDFS_IPV4_SIZE - 1 + ProtoCommon.FDFS_PROTO_PKG_LEN_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();
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;
int offset = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN;
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, ip_size - 1).trim(), port);
for (int i = 0; i < server_count; i++) {
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;
servers[i] = new ServerInfo(ip_addr, port);
}
return servers;
@@ -560,7 +565,7 @@ public class TrackerClient {
out.write(header);
ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
connection.getInetSocketAddress(), ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
this.errno = pkgInfo.errno;
if (pkgInfo.errno != 0) {
return null;
@@ -668,7 +673,7 @@ public class TrackerClient {
out.write(wholePkg);
ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
connection.getInetSocketAddress(), ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
this.errno = pkgInfo.errno;
if (pkgInfo.errno != 0) {
return null;
@@ -749,7 +754,7 @@ public class TrackerClient {
out.write(wholePkg);
ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
ProtoCommon.TRACKER_PROTO_CMD_RESP, 0);
connection.getInetSocketAddress(), ProtoCommon.TRACKER_PROTO_CMD_RESP, 0);
this.errno = pkgInfo.errno;
return pkgInfo.errno == 0;
} catch (IOException e) {
@@ -893,9 +898,8 @@ public class TrackerClient {
System.arraycopy(bs, 0, wholePkg, header.length, bs.length);
out.write(wholePkg);
ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(
connection.getInputStream(),
ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(connection.getInputStream(),
connection.getInetSocketAddress(), ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
this.errno = pkgInfo.errno;
if (pkgInfo.errno != 0) {
return null;
@@ -97,6 +97,7 @@ public class Connection {
}
return isConnected;
}
public boolean isAvaliable() {
if (isConnected()) {
if (sock.getPort() == 0) {
@@ -119,6 +120,10 @@ public class Connection {
return false;
}
public boolean isClosed() {
return this.sock == null;
}
public boolean isNeedActiveTest() {
return needActiveTest;
}
@@ -23,7 +23,8 @@ public class ConnectionFactory {
sock.connect(socketAddress, ClientGlobal.g_connect_timeout);
return new Connection(sock, socketAddress);
} catch (Exception e) {
throw new MyException("connect to server " + socketAddress.getAddress().getHostAddress() + ":" + socketAddress.getPort() + " fail, emsg:" + e.getMessage());
throw new MyException("connect to server " + socketAddress.getAddress().getHostAddress()
+ ":" + socketAddress.getPort() + " fail, emsg: " + e.getMessage());
}
}
}
@@ -20,11 +20,6 @@ public class ConnectionManager {
*/
private AtomicInteger totalCount = new AtomicInteger();
/**
* free connection count
*/
private AtomicInteger freeCount = new AtomicInteger();
/**
* lock
*/
@@ -50,10 +45,11 @@ public class ConnectionManager {
try {
Connection connection = null;
while (true) {
if (freeCount.get() > 0) {
freeCount.decrementAndGet();
connection = freeConnections.poll();
if (!connection.isAvaliable() || (System.currentTimeMillis() - connection.getLastAccessTime()) > ClientGlobal.g_connection_pool_max_idle_time) {
connection = freeConnections.poll();
if (connection != null) {
if (!connection.isAvaliable() || (System.currentTimeMillis() - connection.getLastAccessTime()) >
ClientGlobal.g_connection_pool_max_idle_time)
{
closeConnection(connection);
continue;
}
@@ -62,7 +58,8 @@ public class ConnectionManager {
try {
isActive = connection.activeTest();
} catch (IOException e) {
System.err.println("send to server[" + inetSocketAddress.getAddress().getHostAddress() + ":" + inetSocketAddress.getPort() + "] active test error ,emsg:" + e.getMessage());
System.err.println("send to server " + inetSocketAddress.getAddress().getHostAddress()
+ ":" + inetSocketAddress.getPort() + " active test error, emsg: " + e.getMessage());
isActive = false;
}
if (!isActive) {
@@ -72,7 +69,9 @@ public class ConnectionManager {
connection.setNeedActiveTest(false);
}
}
} else if (ClientGlobal.g_connection_pool_max_count_per_entry == 0 || totalCount.get() < ClientGlobal.g_connection_pool_max_count_per_entry) {
} else if (ClientGlobal.g_connection_pool_max_count_per_entry == 0 ||
totalCount.get() < ClientGlobal.g_connection_pool_max_count_per_entry)
{
connection = ConnectionFactory.create(this.inetSocketAddress);
totalCount.incrementAndGet();
} else {
@@ -81,10 +80,17 @@ public class ConnectionManager {
//wait single success
continue;
}
throw new MyException("connect to server " + inetSocketAddress.getAddress().getHostAddress() + ":" + inetSocketAddress.getPort() + " fail, wait_time > " + ClientGlobal.g_connection_pool_max_wait_time_in_ms + "ms");
throw new MyException("connections reach max_count_per_entry: "
+ ClientGlobal.g_connection_pool_max_count_per_entry + ", "
+ "await connection for server " + inetSocketAddress.getAddress().getHostAddress()
+ ":" + inetSocketAddress.getPort() + " timeout, wait_time > "
+ ClientGlobal.g_connection_pool_max_wait_time_in_ms + " ms");
} catch (InterruptedException e) {
e.printStackTrace();
throw new MyException("connect to server " + inetSocketAddress.getAddress().getHostAddress() + ":" + inetSocketAddress.getPort() + " fail, emsg:" + e.getMessage());
throw new MyException("connection full, await connection for server "
+ inetSocketAddress.getAddress().getHostAddress()
+ ":" + inetSocketAddress.getPort() + " fail, emsg: " + e.getMessage());
}
}
return connection;
@@ -98,50 +104,51 @@ public class ConnectionManager {
if (connection == null) {
return;
}
lock.lock();
try {
connection.setLastAccessTime(System.currentTimeMillis());
freeConnections.add(connection);
freeCount.incrementAndGet();
condition.signal();
} finally {
lock.unlock();
}
}
public void closeConnection(Connection connection) {
if (connection == null) {
return;
}
try {
if (connection != null) {
if (!connection.isClosed()) {
totalCount.decrementAndGet();
connection.closeDirectly();
}
} catch (IOException e) {
System.err.println("close socket[" + inetSocketAddress.getAddress().getHostAddress() + ":" + inetSocketAddress.getPort() + "] error ,emsg:" + e.getMessage());
e.printStackTrace();
System.err.println("close socket[" + inetSocketAddress.getAddress().getHostAddress()
+ ":" + inetSocketAddress.getPort() + "] error, emsg: " + e.getMessage());
}
}
public void setActiveTestFlag() {
if (freeCount.get() > 0) {
lock.lock();
try {
for (Connection freeConnection : freeConnections) {
freeConnection.setNeedActiveTest(true);
}
} finally {
lock.unlock();
lock.lock();
try {
for (Connection freeConnection : freeConnections) {
freeConnection.setNeedActiveTest(true);
}
} finally {
lock.unlock();
}
}
@Override
public String toString() {
return "ConnectionManager{" +
"ip:port='" + inetSocketAddress.getAddress().getHostAddress() + ":" + inetSocketAddress.getPort() +
", totalCount=" + totalCount +
", freeCount=" + freeCount +
", freeCount=" + freeConnections.size() +
", freeConnections =" + freeConnections +
'}';
}
@@ -43,7 +43,6 @@ public class ConnectionPool {
} else {
connection.closeDirectly();
}
}
public static void closeConnection(Connection connection) throws IOException {
@@ -64,7 +63,7 @@ public class ConnectionPool {
if (socketAddress == null) {
return null;
}
return String.format("%s:%s", socketAddress.getAddress().getHostAddress(), socketAddress.getPort());
return String.format("%s-%s", socketAddress.getAddress().getHostAddress(), socketAddress.getPort());
}
@Override