텍스트가 아닌 파일 형태로 클라이언트가 서버에게 파일 전송하기 - Java~!!

안녕하세요

오늘도 자바 포스팅을 써봅니다.

지금까지 에코 서버/클라이언트, 실시간 채팅 모두 다 텍스트로만 데이터를 전송했습니다

이번 시간에는 텍스트 뿐만 아니라 파일을 전송할 수 있는 예제를 올려봅니다.

자 그럼 잘 봐주세요~!!


서버.java

=========================================================


//3 - FTPServer 자체가 스레드되게 바로 스레드 상속
public class FTPServer extends Thread {

private ServerSocket server;
private Socket sock;
private String upDir="C:/MyJava/Upload";
private ObjectInputStream ois; // 파일명, 파일 등을 받을 수 있는 스트림
private FileOutputStream fos; // 파일로 내보내는 스트림 - (동영상, 이미지) 파일 형태는 1바이트 기반이 적합 / 문자 형태는 2바이트 기반

public FTPServer(){
try {
server=new ServerSocket(7788);
} catch (Exception e) {
e.printStackTrace();
}

}

public void run(){
out.println("FTPServer Started...");
try {
while(true){
sock=server.accept();
out.println(sock.getInetAddress()+"가 접속해옴");
ois=new ObjectInputStream(sock.getInputStream());
//서버가 파일명을 보내오는 것을 받자
String fileName=ois.readUTF(); // 문자열을 받기 위해 readUTF 사용
out.println(fileName);
String path=upDir+"/"+fileName; // 절대경로 지정
fos=new FileOutputStream(path); // 절대경로에 파일을 내보내어 생성한다.

//서버가 파일을 보내오는 것을 받자
int input=0, count=0; // count는 파일 크기 측정하기 위해
byte[] data=new byte[1024]; // 1kb씩. 빠르게 하려면 값을 더 크게 줘도 된다

//C:/MyJava/Upload 경로에 파일을 내보내기
while((input=ois.read(data))!=-1){
fos.write(data, 0, input);
fos.flush();
count+=input;
out.println(count+"byte 업로드중...");
}

if(fos!=null) fos.close();
if(ois!=null) ois.close();
if(sock!=null) sock.close();
}

} catch (Exception e) {
e.printStackTrace();
}

}

public static void main(String[] args) {

FTPServer fserver=new FTPServer();
fserver.start();
}
}


=========================================================


클라이언트.java



=========================================================


package net.day2;

import java.io.*;
import java.net.*;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

//3
//192.168.10.3
public class FileUploadGUI extends javax.swing.JFrame {

Socket sock;
     ObjectOutputStream oos;
     FileInputStream fis;
     File file1;
     PrintWriter pw;

    public FileUploadGUI() {
        initComponents();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                        
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        tfHost = new javax.swing.JTextField();
        tfFile = new javax.swing.JTextField();
        btFile = new javax.swing.JButton();
        btUpload = new javax.swing.JButton();
        lb = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("FileUpload");

        jPanel1.setBorder(new javax.swing.border.MatteBorder(null));

        tfHost.setText("localhost");
        tfHost.setBorder(javax.swing.BorderFactory.createTitledBorder("업로드 할 서버 IP 주소"));

        tfFile.setBorder(javax.swing.BorderFactory.createTitledBorder("업로드 할 파일명"));

        btFile.setText("파일찾기");
        btFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btFileActionPerformed(evt);
            }
        });

        btUpload.setText("Upload");
        btUpload.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btUploadActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(tfFile)
                    .addComponent(tfHost, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(btFile, javax.swing.GroupLayout.DEFAULT_SIZE, 92, Short.MAX_VALUE)
                    .addComponent(btUpload, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(tfHost, javax.swing.GroupLayout.DEFAULT_SIZE, 54, Short.MAX_VALUE)
                    .addComponent(btUpload, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(btFile, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(tfFile, javax.swing.GroupLayout.DEFAULT_SIZE, 55, Short.MAX_VALUE))
                .addContainerGap(25, Short.MAX_VALUE))
        );

        lb.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(lb, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(lb, javax.swing.GroupLayout.PREFERRED_SIZE, 331, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(26, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                      

    JFileChooser fileDial=new JFileChooser("C:/MyJava/"); // 기준 경로 지정
    private void btFileActionPerformed(java.awt.event.ActionEvent evt) {                                      
       
    //파일 다이얼로그를 띄워 업로드할 파일을 선택한다
    fileDial.showOpenDialog(this);
    File selFile=fileDial.getSelectedFile();
    tfFile.setText(selFile.getAbsolutePath());
    String filename=selFile.getName();
    //파일이 이미지 파일이면 lb에 미리보기를 해주자
    filename=filename.toLowerCase(); // 파일 이름을 전부 소문자로 바꾸기
    if(filename.endsWith(".jpg")||filename.endsWith(".png")||filename.endsWith(".gif")){
    lb.setIcon(new ImageIcon(selFile.getAbsolutePath()));
    lb.setText("");
    lb.setHorizontalAlignment(JLabel.CENTER);
    }
    }                                    

    private void btUploadActionPerformed(java.awt.event.ActionEvent evt) {                                        
       
    // 파일을 서버에 전송하는 스레드 생성 및 동작
    SenderThread tr=new SenderThread();
    tr.start();
    }
   
    class SenderThread extends Thread{
   
    public void run(){
    // ftpserver에 접속하자(아이피, 포트번호)
    String serverip=tfHost.getText();
    int port=7788;
    if(serverip==null||serverip.trim().isEmpty()){
    JOptionPane.showMessageDialog(lb, "서버의 IP 주소를 입력하세요");
    tfHost.requestFocus();
    return;
    }//if------

    try{
    // 소켓 생성
    sock = new Socket(serverip, port);
    // 타이틀에 연결 결과 출력
    setTitle("##서버와 접속됨");
    //소켓 출력스트림=>ObjectOutputStream 필터링
    //클라이언트(OjbectInputStream)에게 파일을 보낸다
    oos = new ObjectOutputStream(sock.getOutputStream());
    //파일 입력스트림=>FileInputStream
    //File chooser에서 선택한 파일을 읽어들인다
    file1 = fileDial.getSelectedFile();
    fis = new FileInputStream(file1);
    //파일명을 서버에 전송한다.
    String fname = file1.getName();
    pw = new PrintWriter(sock.getOutputStream(),true);
    oos.writeUTF(fname);
    oos.flush();
    //파일을 읽으면서 소켓출력 스트림을 통해 파일 데이터를 내보낸다.
    int input=0, count=0;
    byte[] data = new byte[1024];
    while((input=fis.read(data))!=-1){
    oos.write(data, 0, input);
    oos.flush();
    count+=input;
    System.out.println(count+"바이트 전송중...");
    }
   
    if(pw!=null) pw.close();
    if(oos!=null) oos.close();
    if(fis!=null) fis.close();
    if(sock!=null) sock.close();
    JOptionPane.showMessageDialog(lb, "업로드 완료!");
    }catch(Exception e){
    System.out.println("예외: "+e);
    }
    }
    }

    public static void main(String args[]) {
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(FileUploadGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(FileUploadGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(FileUploadGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(FileUploadGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new FileUploadGUI().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                    
    private javax.swing.JButton btFile;
    private javax.swing.JButton btUpload;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JLabel lb;
    private javax.swing.JTextField tfFile;
    private javax.swing.JTextField tfHost;
    // End of variables declaration                  
}



=========================================================


실행 결과 화면은 다음과 같습니다



서버를 실행하고 클라이언트를 실행하면 위와 같은 창이 나옵니다.





저는 제가 좋아하는 설현 움짤을 업로드 했습니다.

그리고 업로드 할 서버 IP 주소(자신의 IP) 주소를 적고

업로드 버튼을 누르면..




업로드가 완료됩니다.





이때 클라이언트, 서버 창에는 그동안 몇바이트를 업로드 했는지가 출력이 됩니다

위의 소스를 실행하기 위해서 반드시 'Upload' 라는 폴더가 있어야 합니다

그 폴더를 안만들고 백날 실행해봐야 되지 않습니다.

이 점 유의하시면서 이상 포스팅을 마칩니다


댓글 없음:

댓글 쓰기