I. Introduction
I am opening and reading from a file, sending chunks of data through a TCP socket as I read.
SENDER CODE
byte[] buffer = new byte[16384];
while ((in.read(buffer)) > 0)
{
SendProtocol(new FileTransfer(sender, receive开发者_运维知识库r, buffer);
}
RECEIVER CODE
if(o instanceOf FileTransfer)
FileTransfer tf = (FileTransfer) o;
out.write(tf.getData);
}
II. Problem
After I send the protocol through the TCP socket, I view the bytes being sent over. They are all unique. BUT at the receiver side, the bytes received is just the same byte[] over and over.
III. Example
SENDER BYTES
[3, 3, 5, -44, 4, 3]
[99, -3, 5, -44, 7, 3]
[-11, 3, 5, -44, 4, 7]
[10, 6, 5, -44, 4, 66]
RECEIVER BYTES
[3, 3, 5, -44, 4, 3]
[3, 3, 5, -44, 4, 3]
[3, 3, 5, -44, 4, 3]
[3, 3, 5, -44, 4, 3]
One problem you have is that you don't check how many bytes you recieved. It may be that you get a full buffer almost every time over loopback, but you are unlikely to get this over a real network. You have to record how many bytes were read into the buffer and use only that amount.
Maybe this test example I did makes it clear what you have missed:
public class Test {
public static void main(String args[]) throws Exception {
Server server = new Server(12345);
Socket s = null;
InputStream fs = null;
try {
s = new Socket("localhost", 12345);
fs = new FileInputStream("test.txt");
OutputStream os = s.getOutputStream();
byte[] bytes = new byte[1024];
int read;
while ((read = fs.read(bytes)) != -1)
os.write(bytes, 0, read);
}
finally {
if (s != null)
s.close();
if (fs != null)
fs.close();
}
server.join();
}
static class Server extends Thread {
ServerSocket serverSocket;
Server(int port) throws IOException {
serverSocket = new ServerSocket(port);
start();
}
@Override
public void run() {
try {
Socket s = serverSocket.accept();
InputStream is = s.getInputStream();
try {
StringBuffer sb = new StringBuffer();
{
byte[] bytes = new byte[1024];
int read;
while ((read = is.read(bytes)) != -1)
sb.append(new String(bytes, 0, read));
}
System.out.println(sb);
}
finally {
if (is != null)
is.close();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
use out.flush()
after writing all the information.
What's FileTransfer, and does its constructor copy the buffer? Is its operation asynchronous? It could be that its buffer gets refilled by the loop before it has been copied to the TCP socket. I.e., you keep queueing up pointers to the same buffer, which you then overwrite in the loop.
Make FileTransfer assume ownership of the buffer parameter, deleting it when sent. Then allocate a fresh one for each trip through the loop and hand it off to the FileTransfer.
精彩评论