TL; DR:どのように(1つの接続で)ファイル、そのサイズと名前を送信しますか。インターネットのすべての例では、ファイルを単独で送信します。ソケット経由でファイルを送信する - バッファサイズ
サーバー:
public class Server {
private static int PORT = 6667;
private ServerSocket serverSocket;
public void run() throws IOException {
System.out.println("Opening server");
serverSocket = new ServerSocket(PORT);
while(true) {
try(Socket incomingSocket = serverSocket.accept()) {
System.out.println("Accepted connection: " + incomingSocket);
incomingSocket.setSoTimeout(2000); // Don't let scanner block the thread.
InputStream inputStream = incomingSocket.getInputStream();
Scanner scanner = new Scanner(inputStream);
String command = "";
if(scanner.hasNextLine())
command = scanner.nextLine();
if(command.equals("update")) {
File file = new File("abc.txt");
sendFile(incomingSocket, file);
}
else {
// ...
System.out.println("Another command");
}
}
}
}
private void sendFile(Socket socket, File file) throws IOException {
byte[] bytes = new byte[(int)file.length()];
FileInputStream fileInputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedInputStream.read(bytes, 0, bytes.length);
OutputStream outputStream = socket.getOutputStream();
PrintWriter writer = new PrintWriter(outputStream, true);
writer.println(file.length());
writer.println(file.getName());
System.out.println("Sending " + file.getName() + "(" + bytes.length + " bytes) to " + socket);
outputStream.write(bytes, 0, bytes.length);
outputStream.flush();
System.out.println("File sent");
}
public void stopRunning() {
try {
serverSocket.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
クライアント:
public class Client {
private static String HOST = "localhost";
private static int PORT = 6667;
public void run() throws IOException {
Socket socket = new Socket(HOST, PORT);
System.out.println("Connecting...");
OutputStream outputStream = socket.getOutputStream();
PrintWriter writer = new PrintWriter(outputStream, true);
writer.println("update"); // Example command which will determine what server sends back
receiveFile(socket);
socket.close();
}
private void receiveFile(Socket socket) throws IOException {
InputStream inputStream = socket.getInputStream();
int size = 16384;
String name = "example.txt";
Scanner scanner = new Scanner(inputStream);
size = Integer.parseInt(scanner.next());
name = scanner.next();
FileOutputStream fileOutputStream = new FileOutputStream(name);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
byte[] buffer = new byte[size];
int bytesRead, totalRead = 0;
while ((bytesRead = inputStream.read(buffer, 0, buffer.length)) != -1) {
totalRead += bytesRead;
bufferedOutputStream.write(buffer, 0, bytesRead);
}
bufferedOutputStream.flush();
System.out.println("File " + name + " received. " + totalRead + " bytes read");
bufferedOutputStream.close();
fileOutputStream.close();
}
は、私は私のサーバーがクライアントにファイルを送信したいです。また、ファイルの名前とサイズも含める必要があります。名前は非常に重要でサイズが大きいので、私は巨大なサイズのハードコードされたバッファを作りたくないからです。
上記のコードで試してみてください。クライアントの「スキャナ部」
Scanner scanner = new Scanner(inputStream);
size = Integer.parseInt(scanner.next());
name = scanner.next();
は正常ですが、ファイルは受信されません。 inputStream.read(buffer、0、buffer.length)は、ストリームから残りのバイトを読み取ることはありません。
私はスキャナ部をコメントアウトした場合は、バイトがそう正しく
(サイズと名前の情報+ファイル自体を)読んでいる、問題は、私は、単一の接続でそれを送信しないか、でしょうか?または、2つの別々の接続を作成する必要があります。まず最初にサイズとファイル名を尋ね、2番目のファイルにファイルを送信しますか?
素晴らしい、ありがとう。ストリームを正しく処理する方法について少しお読みください:) – MrGrzyboo