Contoh lengkap transfer file berdasarkan Java Socket Protocol, diselesaikan berdasarkan komunikasi TCP.
Selain transfer file biner berbasis TCP, beberapa keterampilan pemrograman Java Swing, Program Demo
Fungsi utama diimplementasikan sebagai berikut:
Pertama, mari kita lihat hubungan antara seluruh kelas kubah:
Berikut ini adalah penjelasan terperinci tentang fungsi dan implementasi kode dari setiap kelas sesuai dengan gambar di atas:
Sisi server:
Fungsi kelas filetransferserver pertama kali membuat soket server di port 9999 dan
Mulailah mendengarkan koneksi. Kode yang relevan adalah sebagai berikut:
private void starterver (int port) {coba {serversocket = new Serverersocket (port); System.out.println ("Server dimulai di port:" + port); while (true) {socket client = serversocket.accept (); // diblokir & menunggu soket pendapatan.out.println ("Just Connected To" + Client.GetRemoteSocketAddress ()); Tugas filereceivetask = filereceivetask baru (klien); bar.setValue (0); // Atur ulang sekarang Task.AddPropertyChangeListener (New PropertyChangeListener () {public void PropertyChange (PropertyChangeEvent evt) {if ("progress" .Equals (evt.getPropertyname ())) {bar.setValue ((integer) evt.getnewvalue ()) {Bar.setValue ((integer) evt.getnewvalue ()))))))))))))))))))))))))))))))))) Task.execute (); }} catch (ioException e) {E.PrintStackTrace (); }}Tentang PropertyChangeListener, Java menyediakan kelas alat yang sangat kuat untuk memantau perubahan data dalam model kacang apa pun. Program mengimplementasikan
SwingWorker's Progress Properti Perubahan Nilai Properti Perubahan Acara, lalu Perbarui JProgressbar
Objek instan, mewujudkan penyegaran UI. Kode Sumber Lengkap Kelas FileTransferServer adalah sebagai berikut:
paket com.gloomyfish.socket.tutorial.filetransfer; impor java.awt.borderlayout; impor java.awt.flowlayout; impor java.awt.event.actionevent; impor java.awt.event.actionlistener; impor java.beans.propertychangeEvent; impor java.beans.propertychangelistener; impor java.io.ioException; impor java.net.serversocket; impor java.net.socket; impor javax.swing.boxlayout; impor javax.swing.jbutton; impor javax.swing.jframe; impor javax.swing.joptionpane; impor javax.swing.jpanel; impor javax.swing.jprogressbar; Public Class FileTransFerServer memperluas JFRame mengimplementasikan ActionListener { / ** * * / String statis akhir publik start_svr = "start"; string statis final publik shut_down_svr = "shut down"; string statis akhir publik end_flag = "eof"; private static final long serialversionuid = 1L; server server private server; Private Jbutton Startbtn; bar jprogressbar pribadi; public filetransferserver () {super ("file server"); initComponent (); setuplistener (); } private void setuplistener () {startbtn.addactionListener (ini); } private void initComponent () {startbtn = new jbutton (start_svr); Jpanel progressPanel = jpanel baru (); ProgressPanel.setLayout (boxLayout baru (ProgressPanel, boxlayout.y_axis)); bar = JProgressBar baru (); bar.setMinimum (0); Bar.setMaximum (100); ProgressPanel.Add (bar); getContentPane (). setLayout (borderlayout baru ()); Jpanel btnpanel = jpanel baru (flowlayout baru (flowlayout.right)); btnpanel.add (startbtn); getContentPane (). Add (btnpanel, borderlayout.south); getContentPane (). Tambah (ProgressPanel, BorderLayout.Center); } private void starterver (int port) {coba {serversocket = new serverersocket (port); System.out.println ("Server dimulai di port:" + port); while (true) {socket client = serversocket.accept (); // diblokir & menunggu soket pendapatan.out.println ("Just Connected To" + Client.GetRemoteSocketAddress ()); Tugas filereceivetask = filereceivetask baru (klien); bar.setValue (0); // Atur ulang sekarang Task.AddPropertyChangeListener (New PropertyChangeListener () {public void PropertyChange (PropertyChangeEvent evt) {if ("progress" .Equals (evt.getPropertyname ())) {bar.setValue ((integer) evt.getnewvalue ()) {Bar.setValue ((integer) evt.getnewvalue ()))))))))))))))))))))))))))))))))) Task.execute (); }} catch (ioException e) {E.PrintStackTrace (); }} public void menunjukkancuccess () {bar.setValue (100); JOPTIONPANE.SHOWMESSADEIALOG (ini, "File diterima dengan sukses!"); } @Override public void actionPerformed (actionEvent e) {if (start_svr.equals (e.getactionCommand ())) {thread startThread = new thread (runnable baru () {public void run () {starterver (9999);}}); startThread.start (); startbtn.setenabled (false); } else if (shut_down_svr.equals (e.getactionCommand ())) {} else {// tidak melakukan apa -apa ...}} public static void main (string [] args) {filetransferserver server = new filetransferserver (); server.setDefaultCloseOperation (jframe.exit_on_close); server.setsize (400, 400); server.setresizable (false); server.setVisible (true); }} Filereceivetask adalah kelas penerimaan file di sisi server:
Pertama, dapatkan nama file dan ukuran file dari aliran TCP yang ditetapkan, dan kemudian mulai menerima byte konten file
Dan menulis ke aliran objek file yang dibuat, dan akhirnya memverifikasi apakah ukuran file sama dengan aliran byte tertulis
Akhirnya, kirim pesan ke pengirim file untuk memberi tahu pihak lain bahwa transfer file selesai dan aliran TCP dapat ditutup.
Kode sumber lengkap dari kelas ini adalah sebagai berikut:
paket com.gloomyfish.socket.tutorial.filetransfer; impor java.io.bufferedoutputStream; impor java.io.bufferedoutputStream; impor java.io.datainputstream; impor java.io.file; impor java.io.fileoutputStream; impor java.io.outputStreamWriter; impor java.net.socket; impor javax.swing.swingworker; kelas publik filereceivetask memperluas swingworker <integer, objek> {private socket _msocket; public filereceivetask (klien soket) {this._msocket = klien; } @Override Protected Integer doInbackground () melempar Exception {// Dapatkan informasi file meta DataInputStream input = new DataInputStream (_msocket.getInputStream ()); String filename = input.readutf (); int filelength = (int) input.readlong (); // Jumlah file byte total file = file baru ("c: // user // fish // download" + file.separator + filename); BufferedOutputStream output = baru bufferedOutputStream (FileOutputStream baru (file)); System.out.println ("Nama file yang diterima =" + nama file); System.out.println ("Menerima ukuran file =" + FileLength/1024 + "KB"); // Mulailah menerima konten file dan tuliskan byte [] konten = byte baru [2048]; int offset = 0; int numreadbytes = 0; while (offset <filelength && (numreadbytes = input.read (content))> 0) {output.write (konten, 0, numreadbytes); float precent = 100.0f * ((float) offset)/((float) filelength); setProgress ((int) precent); offset += numreadbytes; } System.out.println ("numreadbytes =" + numreadbytes); if (offset <filelength) {numreadbytes = input.read (content); System.out.println ("numreadbytes =" + numreadbytes); System.out.println ("Kesalahan konten file di sisi server"); } else {System.out.println ("Tugas menerima file telah dilakukan dengan benar"); } setProgress (100); // Beri tahu klien untuk menutup soket sekarang, kami sudah berhasil menerima file tersebut !! BufferedWriter BufferedWriter = BufferedWriter baru (outputStreamWriter baru (_msocket.getoutputStream ())); bufferedwriter.write ("selesai/r/n"); bufferedwriter.flush (); // tutup file dan soket output.close (); _msocket.close (); mengembalikan 100; }} Klien:
FiletransferClient adalah kelas UI klien yang mengimplementasikan koneksi ke server dan kemudian memilih
File yang akan ditransfer (gambar, PDF, dokumen Word, dll.). Jika tidak
Masukkan informasi server dan prompt akan muncul. Port telah ditentukan sebagai: 9999
Tombol [Kirim File] akan membuka kotak pemilihan file. Setelah pengguna memilih file yang akan ditransfer, buat
FileTransFertask Thread dan mulailah menjalankan transfer file. Kode UI Klien adalah sebagai berikut:
paket com.gloomyfish.socket.tutorial.filetransfer; impor java.awt.borderlayout; impor java.awt.flowlayout; impor java.awt.gridlayout; impor java.awt.event.actionevent; impor java.awt.event.actionlistener; impor java.beans.propertychangeEvent; impor java.beans.propertychangelistener; impor java.io.file; impor java.net.inetsocketaddress; impor java.net.socketaddress; impor javax.swing.borderfactory; impor javax.swing.boxlayout; impor javax.swing.jbutton; impor javax.swing.jfilechooser; impor javax.swing.jframe; impor javax.swing.jlabel; impor javax.swing.joptionpane; impor javax.swing.jpanel; impor javax.swing.jprogressbar; impor javax.swing.jtextfield; /*** Saya biasanya menulis komentar bahasa Inggris, dan kadang -kadang saya juga menulis komentar Cina, tetapi saya pikir menulis komentar bahasa Inggris* lebih disatukan dengan kode, dan tidak ada yang lain. */ kelas publik FileTransferClient memperluas jframe mengimplementasikan ActionListener {/ ** * */ private static final long serialversionuid = 1l; string statis akhir publik send_cmd = "kirim file"; minimum int statis final publik = 0; Maksimum int statis final publik = 100; // string statis akhir publik connect_cmd = "connect"; Private Jbutton SendFilebtn; Private JTextField Serverfield; Private JTextfield Portfield; bar jprogressbar pribadi; public filetransferclient () {super ("klien transfer file"); initcomponents (); } private void initComponents () {getContentPane (). setLayout (borderlayout baru ()); Jpanel progressPanel = jpanel baru (); ProgressPanel.setLayout (boxlayout baru (ProgressPanel, boxlayout.y_axis); bar = new jprogressbar (); progressPanel.add (bar); bar.setminimum (minimum); bar.setmaximum (maksimum); serverpanel jpanelpanel = new jpanel (new jpanel (jpaning); jpanelpanel. jpanel = jpanel new jpanel (jpanelpanel = jpanel (jpanel New. GridLayout (2,2,5,5)); ServerSettingPanel.Add (Jlabel baru ("Port Server:")); btnpanel.add (sendFileBTN); @Override void ActionPerformed (ActionEvent e) {command string = e.getactionCommand () status int = chooser.showopendialog (null); Task.AddPropertyChangelistener (PropertyChangeListener baru () {public voidChange (PropertyChangeEvent EVT) {if ("progress" .Sequals (evt.getPropertyname ()) {Bar.setValue (integer) evt.getNewValue ()); Eksekusi}} else {// Do Nothing}} public void menunjukkan () {bar.setValue (100); Integer.parseint (portfield.getText (). Trim ()); port.length () == 0) {return true; client.setDefaultCloseOperation (jFrame.exit_on_close); Fungsi utama yang diimplementasikan oleh FiletransFertask adalah:
Kode sumber lengkap dari kelas ini adalah sebagai berikut:
paket com.gloomyfish.socket.tutorial.filetransfer; impor java.io.bufferedInputStream; impor java.io.bufferedReader; impor java.io.datainputstream; impor java.io.dataoutputStream; impor java.io.file; impor java.io.fileInputStream; impor java.io.ioException; impor java.io.inputStreamReader; impor java.net.socket; impor java.net.socketaddress; impor javax.swing.swingworker; Public Class FileTransFertask memperluas SwingWorker <Integer, Object> {Private File SelectedFile; soket pribadi msocket; alamat socketaddress pribadi; orang tua filetransferclient pribadi; public filetransfertask (file file, alamat socketaddress, pemilik filetransferclient /*, jProgressBar progress* /) {this.address = alamat; this.selectedFile = file; msocket = soket baru (); this.parent = pemilik; } @Override Doinbackground Integer yang Dilindungi () Melempar Exception {// Dapatkan ukuran file panjang file = selectedFile.length (); if (length> integer.max_value) {lempar ioException baru ("tidak dapat sepenuhnya membaca file" + selectedFile.getName () + "karena terlalu panjang (" + panjang + "byte, max didukung" + integer.max_value + ")"); } msocket.connect (alamat); // Buat array byte untuk menahan data file msocket.setsolinger (true, 60); DataOutputStream dout = DataOutputStream baru (msocket.getoutputStream ()); // Sekarang kita mulai mengirim info meta file. dout.writeutf (selectedFile.getName ()); dout.writelong (panjang); dout.flush (); // Akhiri Komentar FileDataPackage PDATA = new FileDataPackage (); DataInputStream adalah = DataInputStream baru (FileInputStream baru (SelectedFile)); byte [] bytes = byte baru [2048]; // Baca dalam byte int offset = 0; int numread = 0; int fsize = (int) panjang; while (offset <fsize && (numread = is.read (bytes, 0, bytes.length))> = 0) {pdata.setData (bytes, numread); dout.write (pdata.getPackagedata (), 0, pdata.getPackagedata (). Panjang); dout.flush (); offset += numread; float precent = 100.0f * ((float) offset)/((float) fsize); setProgress ((int) precent); } System.out.println ("Total kirim bytes =" + offset); // Pastikan semua byte telah dibaca di if (offset <fsize) {lempar ioException baru ("tidak dapat sepenuhnya mentransfer file" + selectedFile.getName ()); } msocket.shutdownoutput (); // menerima pesan transfer berhasil dari koneksi bufferedInputStream streamReader = baru bufferedInputStream (msocket.getInputStream ()); BufferedReader bufferedReader = baru bufferedReader (inputStreamReader baru (streamReader)); String donemsg = bufferedreader.readline (); if ("done" .Equals (donemsg)) {parent.showsuccess (); } // tutup aliran input file setProgress (100); // dout.close (); msocket.close (); is.close (); System.out.println ("Tutup sekarang ..."); mengembalikan 100; }}Kelas paket adalah sebagai berikut, tidak dijelaskan!
paket com.gloomyfish.socket.tutorial.filetransfer; / ** * Ini adalah protokol transfer file yang sangat sederhana melalui soket tcp */ kelas publik fileDataPackage {private int datalength; // panjang data dalam paket, dua byte byte private byte []; // Data maksimum dalam paket, jumlah maksimum MEICI tidak melebihi 2048 byte byte statis akhir publik [] eof = byte baru [] {'e', 'o', 'f'}; public filedApApackage () {DataLength = 0; basis data = byte baru [2048]; } public byte [] getPackagedata () {byte [] pdata = byte baru [panjang data]; // end Comment System.ArrayCopy (databuff, 0, pdata, 0, panjang data); mengembalikan pdata; } public void setData (byte [] data, int bSize) {datalength = bSize; untuk (int i = 0; i <databuff.length; i ++) {if (i <bsize) {databuff [i] = data [i]; } else {databuff [i] = ''; }}}}Jumlah maksimum byte yang dikirim per waktu adalah 2048 byte. Efek terakhir dari program ini adalah sebagai berikut (Win7 + JDK6U30):
Di atas adalah semua tentang artikel ini, saya harap ini akan membantu untuk pembelajaran semua orang.