Java NIO SocketChannel read() after write()
I have a client/server application where two users write to each other and also can send large files to each other, i used ServerSocket and Socket classes to do this and everything was fine except of slow file transfer, this was the code:
Client side:
public void sendFileRequest(Path filePath) {
try {
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
output.writeUTF("FILE_REQUEST");
output.writeUTF(gui.getFilePath().toFile().getName());
output.writeLong(gui.getFilePath().toFile().length());
} catch (IOException e) {
e.printStackTrace();
}
}
Server side:
DataInputStream codeInput = new DataInputStream(client1.getInputStream());
DataOutputStream codeOutput = new DataOutputStream(client2.getOutputStream());
String code = codeInput.readUTF();
switch (code) {
case "MESSAGE":
String message = codeInput.readUTF();
codeOutput.writeUTF(code);
codeOutput.writeUTF(message);
break;
case "FILE_REQUEST":
String fileName = codeInput.readUTF();
long fileSize = codeInput.readLong();
codeOutput.writeUTF(code);
codeOutput.writeUTF(fileName);
codeOutput.writeLong(fileSize);
break;
Switching from IO to NIO(the problem)
After "output.writeUTF("FILE_REQUEST");" at clients side, the client waited until "codeInput.readUTF();" was called on the server, then the client continued. The problem is that when i replaced ServerSocket with ServerSocketChannel, Socket with SocketChannel etc. and started using java NIO, it goes like this:
client:write - client:write - client:write - server:read
what i need is this
client:write - server:read - client:write - server:read - client:write - server:read
In case of a FILE_REQUEST, when i read the code on the server side, for some reason it reads only the first write operation of the client but when i try to read on the server side for the second time, it reads the bytes of the second message along with the bytes of the long value i'm sending
Here is the new code:
Client side:
//im using ByteBuffer
public void sendFileRequest(Path filePath) {
try {
writeString("FILE_REQUEST");
//Here i need the code to wait until the string was read
writeString(gui.getFilePath().toFile().getName());
//Here i need the code to wait until the string was read
writeLong(gui.getFilePath().toFile().length());
} catch (IOException e) {
e.printStackTrace();
}
}
private void writeString(String s) throws IOException {
buffer.put(s.getBytes());
buffer.flip();
channel.write(buffer);
buffer.clear();
}
private void writeLong(long value) throws IOException {
buffer.putLong(value);
buffer.flip();
channel.write(buffer);
buffer.clear();
}
Server side:
public void run() {
String code = readString();
switch (code) {
case "MESSAGE":
String message = readString();
writeString(code);
writeString(message);
break;
case "FILE_REQUEST":
String fileName = readString();
long fileSize = readLong();
writeString(code);
writeString(fileName);
writeLong(fileSize);
break;
}
private String readString() throws IOException {
firstChannel.read(firstBuffer);
firstBuffer.flip();
byte[] bytes = new byte[firstBuffer.remaining()];
firstBuffer.get(bytes);
firstBuffer.clear();
return new String(bytes);
}
private long readLong() throws IOException {
firstChannel.read(firstBuffer);
firstBuffer.flip();
long value = firstBuffer.getLong();
firstBuffer.clear();
return value;
}
I want to use java NIO and either find a way how to send the data separately or send the bytes of the first string, second string and long value together and then check if all the bytes are there and somehow divide them, thanks for any help
链接地址: http://www.djcxy.com/p/34136.html