Java отправка и получение файла (byte[]) через сокеты
Я пытаюсь разработать очень простой клиент / сервер, где клиент преобразует файл в байты, отправляет его на сервер, а затем преобразует байты обратно в файл.
в настоящее время программа просто создает пустой файл. Я не фантастический Разработчик Java, поэтому любая помощь очень ценится.
это серверная часть, которая получает то, что клиент посылает.
ServerSocket serverSocket = null;
serverSocket = new ServerSocket(4444);
Socket socket = null;
socket = serverSocket.accept();
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
byte[] bytes = new byte[1024];
in.read(bytes);
System.out.println(bytes);
FileOutputStream fos = new FileOutputStream("C:test2.xml");
fos.write(bytes);
а вот и клиентская часть
Socket socket = null;
DataOutputStream out = null;
DataInputStream in = null;
String host = "127.0.0.1";
socket = new Socket(host, 4444);
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
File file = new File("C:test.xml");
//InputStream is = new FileInputStream(file);
// Get the size of the file
long length = file.length();
if (length > Integer.MAX_VALUE) {
System.out.println("File is too large.");
}
byte[] bytes = new byte[(int) length];
//out.write(bytes);
System.out.println(bytes);
out.close();
in.close();
socket.close();
6 ответов:
правильный способ копирования потока в Java выглядит следующим образом:
int count; byte[] buffer = new byte[8192]; // or 4096, or more while ((count = in.read(buffer)) > 0) { out.write(buffer, 0, count); }
жаль, что у меня не было доллара за каждый раз, когда я опубликовал это на форуме.
Спасибо за помощь, мне удалось заставить его работать сейчас, поэтому я подумал, что опубликую, чтобы другие могли им помочь.
сервер
public class Server { public static void main(String[] args) throws IOException { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(4444); } catch (IOException ex) { System.out.println("Can't setup server on this port number. "); } Socket socket = null; InputStream in = null; OutputStream out = null; try { socket = serverSocket.accept(); } catch (IOException ex) { System.out.println("Can't accept client connection. "); } try { in = socket.getInputStream(); } catch (IOException ex) { System.out.println("Can't get socket input stream. "); } try { out = new FileOutputStream("M:\test2.xml"); } catch (FileNotFoundException ex) { System.out.println("File not found. "); } byte[] bytes = new byte[16*1024]; int count; while ((count = in.read(bytes)) > 0) { out.write(bytes, 0, count); } out.close(); in.close(); socket.close(); serverSocket.close(); } }
и клиент
public class Client { public static void main(String[] args) throws IOException { Socket socket = null; String host = "127.0.0.1"; socket = new Socket(host, 4444); File file = new File("M:\test.xml"); // Get the size of the file long length = file.length(); byte[] bytes = new byte[16 * 1024]; InputStream in = new FileInputStream(file); OutputStream out = socket.getOutputStream(); int count; while ((count = in.read(bytes)) > 0) { out.write(bytes, 0, count); } out.close(); in.close(); socket.close(); } }
вот сервер Откройте поток в файл и отправьте его по сети
import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class SimpleFileServer { public final static int SOCKET_PORT = 5501; public final static String FILE_TO_SEND = "file.txt"; public static void main (String [] args ) throws IOException { FileInputStream fis = null; BufferedInputStream bis = null; OutputStream os = null; ServerSocket servsock = null; Socket sock = null; try { servsock = new ServerSocket(SOCKET_PORT); while (true) { System.out.println("Waiting..."); try { sock = servsock.accept(); System.out.println("Accepted connection : " + sock); // send file File myFile = new File (FILE_TO_SEND); byte [] mybytearray = new byte [(int)myFile.length()]; fis = new FileInputStream(myFile); bis = new BufferedInputStream(fis); bis.read(mybytearray,0,mybytearray.length); os = sock.getOutputStream(); System.out.println("Sending " + FILE_TO_SEND + "(" + mybytearray.length + " bytes)"); os.write(mybytearray,0,mybytearray.length); os.flush(); System.out.println("Done."); } catch (IOException ex) { System.out.println(ex.getMessage()+": An Inbound Connection Was Not Resolved"); } }finally { if (bis != null) bis.close(); if (os != null) os.close(); if (sock!=null) sock.close(); } } } finally { if (servsock != null) servsock.close(); } } }
вот клиент Получить файл, отправляемый по сети
import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.Socket; public class SimpleFileClient { public final static int SOCKET_PORT = 5501; public final static String SERVER = "127.0.0.1"; public final static String FILE_TO_RECEIVED = "file-rec.txt"; public final static int FILE_SIZE = Integer.MAX_VALUE; public static void main (String [] args ) throws IOException { int bytesRead; int current = 0; FileOutputStream fos = null; BufferedOutputStream bos = null; Socket sock = null; try { sock = new Socket(SERVER, SOCKET_PORT); System.out.println("Connecting..."); // receive file byte [] mybytearray = new byte [FILE_SIZE]; InputStream is = sock.getInputStream(); fos = new FileOutputStream(FILE_TO_RECEIVED); bos = new BufferedOutputStream(fos); bytesRead = is.read(mybytearray,0,mybytearray.length); current = bytesRead; do { bytesRead = is.read(mybytearray, current, (mybytearray.length-current)); if(bytesRead >= 0) current += bytesRead; } while(bytesRead > -1); bos.write(mybytearray, 0 , current); bos.flush(); System.out.println("File " + FILE_TO_RECEIVED + " downloaded (" + current + " bytes read)"); } finally { if (fos != null) fos.close(); if (bos != null) bos.close(); if (sock != null) sock.close(); } } }
чтобы избежать ограничений размера файла , который может вызвать исключение
java.lang.OutOfMemoryError
выбрасывается при создании массива размера файлаbyte[] bytes = new byte[(int) length];
, вместо этого мы могли бы сделатьbyte[] bytearray = new byte[1024*16]; FileInputStream fis = null; try { fis = new FileInputStream(file); OutputStream output= socket.getOututStream(); BufferedInputStream bis = new BufferedInputStream(fis); int readLength = -1; while ((readLength = bis.read(bytearray)) > 0) { output.write(bytearray, 0, readLength); } bis.close(); output.close(); } catch(Exception ex ){ ex.printStackTrace(); } //Excuse the poor exception handling...
Новичок, если вы хотите написать файл на сервер по сокету, как насчет использования fileoutputstream вместо dataoutputstream? dataoutputstream больше подходит для чтения и записи на уровне протокола. это не очень разумно для вашего кода в байтах чтения и записи. цикл для чтения и записи необходим в java io. а также, вы используете буфер способ. смывать необходимо. вот пример кода: http://www.rgagnon.com/javadetails/java-0542.html
добавление ответа EJP; используйте это для большей текучести. Убедитесь, что вы не помещаете его код внутри более крупной попытки поймать с большим количеством кода между ними .прочитайте и блок catch, он может вернуть исключение и перейти полностью к внешнему блоку catch, самая безопасная ставка-разместить цикл ejps while внутри try catch, а затем продолжить код после него, например:
int count; byte[] bytes = new byte[4096]; try { while ((count = is.read(bytes)) > 0) { System.out.println(count); bos.write(bytes, 0, count); } } catch ( Exception e ) { //It will land here.... } // Then continue from here
EDIT: ^это случилось со мной, потому что я не понял, что вам нужно поставить сокет.shutDownOutput() если это клиент-сервер стрим!
надеюсь, что этот пост решит любую из ваших проблем