Java小例:Socketによるファイルの送受信


これは、送信側と受信側を含む簡単な例である.送信側は受信側にファイル名とファイル内容を送信し、受信側は受信したファイルをディスクに保存する.受信側は、複数の送信側から送信されたファイルを同時に受信することができるが、ファイルが同名である場合を処理しない.
 
この例では簡単なプロトコルを設計した.送信内容は次のとおりです.
ファイル名の長さ(4バイト)—ファイル名—ファイル内容の長さ(4バイト)—ファイル内容.
 
受信側もこの構成に従って解析を行う.Clientクラスを見てから、Serverクラスを見ることをお勧めします.
import java.io.*;  
import java.net.ServerSocket;  
import java.net.Socket;  
   
/** 
 *              
 */  
public class FileTrasmission {  
   
    //      
    public static void main(String[] args) throws Exception {  
        int port = 7788;  
        new Server(port, "c:\\save\\").start();  
        new Client().sendFile("127.0.0.1", port, "c:\\       .txt");  
    }  
}  
   
/** 
 *    。               。                 。 
 */  
class Server {  
   
    private int listenPort;  
   
    private String savePath;  
   
    /** 
     *      
     * 
     * @param listenPort      
     * @param savePath               
     * 
     * @throws IOException            
     */  
    Server(int listenPort, String savePath) throws IOException {  
        this.listenPort = listenPort;  
        this.savePath = savePath;  
   
        File file = new File(savePath);  
        if (!file.exists() && !file.mkdirs()) {  
            throw new IOException("        " + savePath);  
        }  
    }  
   
    //       
    public void start() {  
        new ListenThread().start();  
    }  
   
    //      ,      int。b        4,      4  。  
    public static int b2i(byte[] b) {  
        int value = 0;  
        for (int i = 0; i < 4; i++) {  
            int shift = (4 - 1 - i) * 8;  
            value += (b[i] & 0x000000FF) << shift;  
        }  
        return value;  
    }  
   
   
    /** 
     *      
     */  
    private class ListenThread extends Thread {  
   
        @Override  
        public void run() {  
            try {  
                ServerSocket server = new ServerSocket(listenPort);  
   
                //       
                while (true) {  
                    Socket socket = server.accept();  
                    new HandleThread(socket).start();  
                }  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
   
    /** 
     *             
     */  
    private class HandleThread extends Thread {  
   
        private Socket socket;  
   
        private HandleThread(Socket socket) {  
            this.socket = socket;  
        }  
   
        @Override  
        public void run() {  
            try {  
                InputStream is = socket.getInputStream();  
                readAndSave(is);  
            } catch (IOException e) {  
                e.printStackTrace();  
            } finally {  
                try {  
                    socket.close();  
                } catch (IOException e) {  
                    // nothing to do  
                }  
            }  
        }  
   
        //             
        private void readAndSave(InputStream is) throws IOException {  
            String filename = getFileName(is);  
            int file_len = readInteger(is);  
            System.out.println("    :" + filename + ",  :" + file_len);  
   
            readAndSave0(is, savePath + filename, file_len);  
   
            System.out.println("      (" + file_len + "  )。");  
        }  
   
        private void readAndSave0(InputStream is, String path, int file_len) throws IOException {  
            FileOutputStream os = getFileOS(path);  
            readAndWrite(is, os, file_len);  
            os.close();  
        }  
   
        //     ,     size      
        private void readAndWrite(InputStream is, FileOutputStream os, int size) throws IOException {  
            byte[] buffer = new byte[4096];  
            int count = 0;  
            while (count < size) {  
                int n = is.read(buffer);  
                //        n = -1      
                os.write(buffer, 0, n);  
                count += n;  
            }  
        }  
   
        //        
        private String getFileName(InputStream is) throws IOException {  
            int name_len = readInteger(is);  
            byte[] result = new byte[name_len];  
            is.read(result);  
            return new String(result);  
        }  
   
        //         
        private int readInteger(InputStream is) throws IOException {  
            byte[] bytes = new byte[4];  
            is.read(bytes);  
            return b2i(bytes);  
        }  
   
        //             
        private FileOutputStream getFileOS(String path) throws IOException {  
            File file = new File(path);  
            if (!file.exists()) {  
                file.createNewFile();  
            }  
   
            return new FileOutputStream(file);  
        }  
    }  
}  
   
/** 
 *     
 */  
class Client {  
   
    //      ,  int       
    public static byte[] i2b(int i) {  
        return new byte[]{  
                (byte) ((i >> 24) & 0xFF),  
                (byte) ((i >> 16) & 0xFF),  
                (byte) ((i >> 8) & 0xFF),  
                (byte) (i & 0xFF)  
        };  
    }  
   
    /** 
     *     。         {@link Integer#MAX_VALUE} 
     * 
     * @param hostname         IP    
     * @param port            
     * @param filepath      
     * 
     * @throws IOException             
     */  
    public void sendFile(String hostname, int port, String filepath) throws IOException {  
        File file = new File(filepath);  
        FileInputStream is = new FileInputStream(filepath);  
   
        Socket socket = new Socket(hostname, port);  
        OutputStream os = socket.getOutputStream();  
   
        try {  
            int length = (int) file.length();  
            System.out.println("    :" + file.getName() + ",  :" + length);  
   
            //             
            writeFileName(file, os);  
            writeFileContent(is, os, length);  
        } finally {  
            os.close();  
            is.close();  
        }  
    }  
   
    //         
    private void writeFileContent(InputStream is, OutputStream os, int length) throws IOException {  
        //         
        os.write(i2b(length));  
   
        //         
        byte[] buffer = new byte[4096];  
        int size;  
        while ((size = is.read(buffer)) != -1) {  
            os.write(buffer, 0, size);  
        }  
    }  
   
    //        
    private void writeFileName(File file, OutputStream os) throws IOException {  
        byte[] fn_bytes = file.getName().getBytes();  
   
        os.write(i2b(fn_bytes.length));         //          
        os.write(fn_bytes);    //        
    }  
}