com.ibm.as400.access.FTPThread Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jt400 Show documentation
Show all versions of jt400 Show documentation
The Open Source version of the IBM Toolbox for Java
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: FTPThread.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 2004-2010 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
import java.net.*;
import java.io.*;
import java.util.*;
class FTPThread implements Runnable
{
static long threadCount = 0;
static Object threadCountLock = new Object();
private FTP ftp_;
private int port_;
private Socket socket_;
private boolean running_ = false;
private final Object runLock_ = new Object();
private InetAddress localAddress_;
FTPThread(FTP ftp)
{
ftp_ = ftp;
}
// This must be called before the thread is started.
public void setLocalAddress(InetAddress localAddress)
{
localAddress_ = localAddress;
if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "FTP thread's local address set to: "+localAddress_.toString());
}
public void waitUntilStarted()
{
try
{
while (!running_)
{
synchronized (runLock_)
{
if (!running_) runLock_.wait();
}
}
}
catch (Exception e)
{
Trace.log(Trace.ERROR, "Error while waiting for FTP thread to start.", e);
}
}
public int getLocalPort()
{
return port_;
}
public Socket getSocket()
{
if (socket_ == null)
{
try
{
synchronized(this)
{
if (socket_ == null) wait(60000); // Wait 60 seconds to prevent hanging.
}
}
catch (Exception e)
{
Trace.log(Trace.ERROR, "Error while getting socket from FTP thread.", e);
return null;
}
}
Socket s = socket_;
socket_ = null;
if (Trace.traceOn_)
{
Trace.log(Trace.DIAGNOSTIC, "FTP thread returned previously accepted socket.");
if (s == null) Trace.log(Trace.DIAGNOSTIC, "FTPThread.getSocket() is returning null.");
}
return s;
}
public void issuePortCommand() throws IOException
{
String addr = localAddress_.getHostAddress();
// Try the extended port command.
String response = ftp_.issueCommand("EPRT |" + (addr.indexOf(':') == -1 ? "1" : "2") + "|" + addr + "|" + port_ + "|");
if (response.startsWith("200")) return;
// System may not support EPRT, fallback to the port command.
StringTokenizer st = new StringTokenizer(addr, ".");
StringBuffer cmd = new StringBuffer("PORT ");
while (st.hasMoreTokens())
{
cmd.append(st.nextToken());
cmd.append(",");
}
cmd.append(port_/256);
cmd.append(",");
cmd.append(port_ % 256);
response = ftp_.issueCommand(cmd.toString());
// A "successful" response will begin with 200.
if (!response.startsWith("200"))
{
Trace.log(Trace.ERROR, "Unexpected response to " + cmd + ": " + response);
}
}
public void run()
{
synchronized (threadCountLock) {
try {
Thread.currentThread().setName("FTPThread-"+threadCount);
threadCount++;
} catch (Exception e) {
// Just ignore any thread naming issues
}
}
ServerSocket ss = null;
try
{
if (ftp_.isReuseSocket())
{
if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "FTP thread will reuse socket if multiple transfers.");
ss = new ServerSocket(0, 50, localAddress_);
port_ = ss.getLocalPort();
while (true)
{
if (Trace.traceOn_)
{
Trace.log(Trace.DIAGNOSTIC, "FTP thread waiting for new active mode socket.");
}
if (!running_)
{
running_ = true;
synchronized (runLock_)
{
runLock_.notifyAll();
}
}
socket_ = ss.accept();
if (Trace.traceOn_)
{
Trace.log(Trace.DIAGNOSTIC, "FTP thread accepted active mode socket: "+socket_);
}
synchronized (this)
{
notifyAll();
}
}
}
else // don't reuse socket
{
if (Trace.traceOn_) Trace.log(Trace.DIAGNOSTIC, "FTP thread create new socket if multiple transfers.");
while (true)
{
if (ss == null)
{
ss = new ServerSocket(0, 1, localAddress_);
port_ = ss.getLocalPort();
}
if (!running_)
{
running_ = true;
synchronized (runLock_)
{
runLock_.notifyAll();
}
}
if (Trace.traceOn_)
{
Trace.log(Trace.DIAGNOSTIC, "FTP thread waiting for new active mode socket.");
}
socket_ = ss.accept();
if (Trace.traceOn_)
{
Trace.log(Trace.DIAGNOSTIC, "FTP thread accepted active mode socket: "+socket_);
}
synchronized (this)
{
notifyAll();
}
// Get a new server socket each time to avoid bug on AIX.
// We create the server socket with only 1 connection in the backlog
// so any other incoming requests will have to wait until we can get them
// a new server socket. This bottlenecks a multi-threaded client that is
// sharing an FTP object across threads, but they shouldn't be doing that anyway.
ss.close();
ss = null;
}
}
}
catch (Throwable e)
{
Trace.log(Trace.ERROR, "Exception in FTP thread.", e);
}
finally
{
if (socket_ != null) {
try { socket_.close(); }
catch (Throwable e) { Trace.log(Trace.ERROR, e); }
}
if (ss != null) {
try { ss.close(); }
catch (Throwable e) { Trace.log(Trace.ERROR, e); }
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy