How much is the standard buffer size of an apache ftp client(ftp downloader)?
int BufferSize;
ftp = new FTPClient();
ftp.setBufferSize(BufferSize);
ftp.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
int reply;
ftp.connect(host);
If you're referring to FTPClient, you can call getBufferSize() to determine this yourself, at runtime. There are other similar functions for specific (send, receieve) buffers.
For what it's worth, I don't use Java, and I've never even heard of FTPClient. I simply Googled for "apache ftp client", clicked the first link, and Ctrl+F searched for "buffer". Learning to answer questions yourself will greatly help you in the long run.
Related
I have simple java-server via sockets.
Server is read from client url of file which need to download.
FileOutputStream outStream= new FileOutputStream(SERVER_PATH + file.getName());
BufferedOutputStream out = new BufferedOutputStream(outStream);
byte buf[] = new byte[BATCH];
int read = 0;
while ((read = in.read(buf,0,BATCH))>=0){
out.write(buf,0,read);
}
how to continue to download file?
Your Question is a little ambiguous .!
After looking at the code, it looks like you are reading from a File in Client machine and Writing the same to the Server URL.
Assuming this situation,
The points that can help you resolve this are,
1. There will an IOException if the connection is lost. That means you have to handle the exception and reconnect to the Socket. May be after waiting for some time (!!)
2. Then you need to open the server File in Append mode and continue with out.write. As the out is not reset or lost with the Disconnection.
Thanks, Sunil
I am creating an android service which is always running and listening messages from socket. But it doesn't work with good performance and i am looking for some nio alternative or tutorial.
What is the best way for listening a socket for all time ?
Does AndroidAsync support standart sockets ? https://github.com/koush/AndroidAsync
Is there anyone used Apache Mina ? I am having character problem with Mina. http://mina.apache.org/
Or how can i do this job with good performance using standart sockets
Waiting for your experiences.
Thanks
The normal way to get decent performance from a socket (for int read() and write(int)) is to use a buffered stream / reader / writer. That reduces the number of system calls and makes byte or character at a time I/O much faster.
I don't expect that using NIO will make a significant difference. If the problem is not buffering, then (IMO) it is probably a network bandwidth and/or latency issue. If that is the case, there is little that you can do in Java that would make much difference.
I have some convenience methods for writing strings with java.nio:
private static Charset charset;
static
{
charset = Charset.forName("UTF-8");
}
public static void writeString(SocketChannel sc, String string) throws IOException {
CharBuffer c = CharBuffer.wrap(string);
ByteBuffer b = charset.encode(c);
b.compact();
b.flip();
sc.write(b);
}
public static String readString(SocketChannel sc) throws IOException {
ByteBuffer bbuf = ByteBuffer.allocate(8096);
sc.read(bbuf);
bbuf.flip();
CharBuffer cbuf = charset.decode(bbuf);
return cbuf.toString();
}
All you need to do is establish your SocketChannel connections and you can use these all you want. java.nio is really not that difficult once you get used to it :)
I'm using Apache Commons Net 3.3 to handle FTP transfers in a Java application.
Downloads seem to work fine, but I'm getting speeds a lot slower than the local internet connection capabilities for uploads.
The code that writes the file data to the stream looks like this:
BufferedOutputStream out = new BufferedOutputStream(ftp.getOutputStream(prt));
BufferedInputStream in = new BufferedInputStream(prov.getInputStream(s));
byte[] buff = new byte[BUFF_SIZE];
int len;
while ((len = in.read(buff)) >= 0 && !prog.isCanceled()) {
out.write(buff, 0, len);
total += len;
prog.setProgress((int) (Math.round((total / combo) * 100)));
}
in.close();
out.close();
BUFF_SIZE = 16kB
I have the FTPClient buffer size also set to 16kB via setBufferSize
The issue isn't with the server or my internet connection because the upload proceeds at a much more reasonable speed using Filezilla as a FTP client.
The issue also seems to occur with Java 6 and 7 JVMs.
Does anyone have any ideas as to why this is happening? Is there a problem with Commons Net or Java? Or is there something I haven't configured correctly?
Same problem - using SDK 1.6 resolve problem, but also try to find better way
UPD: Solved (see comments)
I am working on a chat implementation with Java sockets. I have focused on few functionalities, like authentication, one person chat and a group chat. I was thinking about adding file transfer functionality, and I wonder what's the good practice about this. Should I have separate socket on the server with different port listening just for file transfers? Right now input and output streams that I get from server socket are binded to Scanner and PrintWriter objects respectively, so I find it hard to use that for file transfer.
Any patterns you guys could recommend or give me good recommendations are very appreciated.
Thanks,
ZeKoU
Well, FTP creates a new socket for each file transfer. Note that the connection can be established on the same port as the one used for chat, but with a different initialization dialog.
If you can use a native lib do that, it will be faster. Failing that unless there is a really good reason use a library which will have had all the kinks worked out.
If you really need to send a file in pure Java. Here's one way based on an old project of mine. Note however that there is some serialisation overhead however much of this could be removed via use of the NIO equivalents as discussed here or you could go slightly further and use Zero Copy which lets you tell the OS to copy a file direct to a socket without any intermediary copies. This only works with files though not other data.
You should do this in a separate thread so that the chat still works while the file is transferring. Create a socket and give it some standard port (you can give it port 0 which just chooses the next available port but then you will need to send that information to the other recipient so just using a standard port is easier). Then split your file into blocks and transmit it using the socket:
//Send file (Server)
//Put this in a thread
Socket socket = new Socket(destinationIP, destinationPort);
ObjectOutputStream sender = new ObjectOutputStream(socket.getOutputStream());
sender.writeObject(dataToSend);
//Receive File (Client)
//Kick off a new thread to receive the file to preserve the liveness of the program
ServerSocket serverSocket = new ServerSocket(ListenPort);
socket = new Socket();
while (true) {
new Thread(new TCPReceiver(socket)).start();
}
//Receive file thread TCPReceiver(Socket socket)
//Get the stream where the object is to be sent
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
/* Where type is the type of data you send... String or anything really...
read part of the file into something and send it then at this end use the same data
type to recieve it and it will magically pull the entire object across.
*/
while(fileIsIncomplete){
type recievedData = (type) objectInputStream.readObject();
//Reconstruct file
}
Hope that is enough for you to get a quick file sender up and running :)
Edit: Removed nonsense statement. Added native point and zero copy mention.
I'm trying to write a tcp stream 'tunnel' (similar to the ones SSH handles by default) but with one exception, I have to rewrite certain information as it flows through.
I'm certain there's something similar out there but I have not been able to find it.
I have three main questions:
Is there an easy way to save a tcp stream for observation? (ie using netcat, or a ssh -r/-l/-D, or using some other utility alltogether)
how hard is it to rewrite the stream on the fly?
Edit: The information being rewritten would be just the initial authentication.
A straight pass-through tunnel with logging can be cobbled together from existing (or easily found) utilities.
socat -v -x tcp-l:8080,fork,reuseaddr tcp:localhost:80 2>log
In this example, connecting to http://localhost:8080/ will pass through to http://localhost:80/, and log data transferred to log.
The tool TCPreen is specialized for this exact purpose.
If you have root privileges, there are many analyzers such as tcpdump and tcpflow which can capture packets directly from the network, without having to redirect traffic.
socat can also do some very basic stream modification with the ,cr and ,crnl options, which strip/add/replace \r characters.
In any case, back to the original question… It's been ages since I've written any Java, and this is totally untested, but a tunnel that can modify traffic before retransmitting isn't difficult.
public class ForwardAndChangeCaseThread extends Thread {
private Socket in, out;
public ForwardAndChangeCaseThread(Socket in, Socket out) {
this.in = in; this.out = out;
}
public void run() {
byte[] buf = new byte[4096];
InputStream in = this.in.getInputStream();
OutputStream out = this.out.getOutputStream();
int count;
while ((count = in.read(buf)) > 0) {
for (int i = 0; i < count; i++)
if (buf[i] >= 0x40) buf[i] ^= 0x20;
out.write(buf, 0, count);
}
}
}
public class TcpForwarder {
public static void main(String[] args) {
ServerSocket listen = new ServerSocket(8080, 1);
for (;;) {
Socket local = listen.accept();
Socket remote = new Socket("localhost", 80);
new ForwardAndChangeCaseThread(local, remote).start();
new ForwardAndChangeCaseThread(remote, local).start();
}
}
}
Pretty sure Ettercap supports rewriting of TCP streams.
tcpdump can write out packet captures, which you could then later analyze using Wireshark
If you want to do it programmatically, you could inspect their respective sources to get ideas of where to start.
Not to toot my own horn, but I wrote some code to do exactly this in a framework I wrote a long time ago for asynchronous IO. There are a lot of things about the code that are kind of dated now, but it does work. Here's a link to the web page on it:
The StreamModule System
The thing I wrote that does the tunnel thing you want is called PortForward, and there's also something there that will dump out a TCP stream, but I forgot what I called it. They can be easily combined because of how the framework works.
I'll come back if you want help using it to accomplish that goal. As others have pointed out, it is impossible to re-write an SSL stream on the fly. So if your connection is using encryption and/or MACs (one way this would be true is if it were SSL) you're out of luck.
I'm not sure if this is what you are asking, but ...
You cannot rewrite an SSL stream on the fly unless you have the private key for the server's SSL cert ... or you can intercept it at some point (in the client or server address space) where it is not SSL protected. If you could, SSL would be a waste of time.
Similarly, if you capture the entire contents of an SSL stream (in both directions), it will do you no good, unless you have the relevant private keys.