TCP(可靠)链接

服务端(接收方)

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Logger;

public class TCPServer{
    private static final Logger log = Logger.getLogger("TCPServer");

    /**
     * 设置数据包大小
     */
    private static int TCP_SIZE = 1024;

    /**
     * 文件保存路径
     */
    private String path = "";

    /**
     * 端口号
     */
    private int port = 10086;

    /**
     * 服务器
     */
    private ServerSocket serverSocket = null;

    /**
     * 初始化并启动服务器
     * @return
     */
    public void start(){
        if(!"".equals(path)){
            if(path.charAt(path.length()-1)!='\\'&&path.charAt(path.length()-1)!='/')path+="\\";
        }
        if(serverSocket==null) {
            try {
                serverSocket = new ServerSocket(port);
            } catch (IOException e) {
                log.severe("服务器启动初始化失败。错误信息:"+e.getMessage());
            }
        }
        try{
            while(true){
                Socket accept = serverSocket.accept();
                Thread thread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        long st = System.currentTimeMillis();
                        InputStream inputStream = null;
                        byte[] bytes = new byte[TCP_SIZE];
                        int bytes_len = TCP_SIZE;
                        //创建文件路径
                        File writePath = new File(path+Thread.currentThread().getName()+"\\");
                        if(writePath.mkdirs())log.info("创建系统文件"+Thread.currentThread().getName()+"路径");
                        //创建写入文件
                        File writeFile = null;
                        FileOutputStream fileOutputStream = null;

                        String fileNameUrl = null; //文件完整保存路径
                        try {


                            inputStream = accept.getInputStream();

                            while ((bytes_len = inputStream.read(bytes,0,TCP_SIZE)) != -1) {
                                if(writeFile==null){ //获取文件名
                                    fileNameUrl = path+Thread.currentThread().getName()+"\\"+getFileName(bytes);
                                    writeFile = new File(fileNameUrl);
                                    if(!writeFile.exists())
                                        writeFile.createNewFile();
                                    fileOutputStream = new FileOutputStream(writeFile);
                                    log.info("获取文件名成功");
                                } else {//写入文件中
                                    fileOutputStream.write(bytes, 0, bytes_len);
                                    log.info("接收数据包:len="+bytes_len);
                                }
                            }
                            //接收成功,并反馈
                            accept.getOutputStream().write("success".getBytes());
                            accept.shutdownOutput();
                        } catch (FileNotFoundException e){
                            log.severe(e.getMessage());
                        }catch (IOException e) {
                            log.severe("获取客户端输出流失败,错误信息:" + e.getMessage());
                            e.printStackTrace();
                        } finally {
                            try {

                                fileOutputStream.flush();
                                fileOutputStream.close();
                                inputStream.close();
                                accept.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        log.info("接收来自 "+accept.getInetAddress().getHostAddress()+" 的文件成功,用时:"+((System.currentTimeMillis()-st)/1000)+",存储:"+fileNameUrl);
                    }
                    private String getFileName(byte[] bytes) {
                        int len = bytes[0];
                        if(len<=0 || len>=Math.min(TCP_SIZE-1,127)){
                            return null;
                        }
                        return new String(bytes,1,len);
                    }

                });
                thread.setDaemon(true);
                thread.start();
            }
        }catch (IOException e){
            log.severe("获取客户端失败,错误信息:"+e.getMessage());
        }

    }

    public void setPath(String path) {
        if(path==null)return;
        this.path = path;
    }

    public void setPort(int port) {
        if(port<=0)return;
        this.port = port;
    }

    /**
     * 程序入口,启动服务器
     * @param args args[0]: port端口号(默认:10086) args[1]: path存储路径(默认:./)
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        TCPServer tcpServer = new TCPServer();
        if(args.length>=1)tcpServer.setPort(Integer.parseInt(args[0]));
        if(args.length>=2)tcpServer.setPath(args[1]);
        tcpServer.start();
    }

}

客户端(发送方)

import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
import java.util.logging.Logger;

class TCPClient{

    private static final Logger log = Logger.getLogger("TCPClient");
    /**
     * 设置数据包大小
     */
    private static int TCP_SIZE = 1024;

    /**
     * 端口号
     */
    private int port = 10086;

    /**
     * 客户端
     */
    private Socket socket = null;
    /**
     * 服务器 ip 地址
     */
    private String ip;

    public TCPClient(String ip,int port){
        this.port = port;
        this.ip = ip;
        try {
            socket = new Socket(ip,port);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public TCPClient(String ip){
        this.ip = ip;
        try {
            socket = new Socket(ip,port);
        } catch (IOException e) {
            log.severe(e.getMessage());
        }
    }

    /**
     * 向服务器发送文件
     * @param fileName 文件全路径名
     * @return
     */
    public boolean sendFile(String fileName){

        OutputStream outputStream = null;
        FileInputStream fileInputStream = null;
        try {
            long st = System.currentTimeMillis();
            //发送文件名
            outputStream = socket.getOutputStream();
            outputStream.write(buildFileName(fileName));
            log.info("发送文件名:"+fileName);
            outputStream.flush();
            //打开文件
            fileInputStream = new FileInputStream(fileName);
            //创建文件缓冲区
            byte[] write = new byte[TCP_SIZE];
            int write_len = TCP_SIZE;
            //发送文件
            while((write_len = fileInputStream.read(write,0,TCP_SIZE))!=-1){
                outputStream.write(write,0,write_len);
                log.info("发送数据包:len="+write_len);
            }
            //关闭tcp output链接
            outputStream.flush();
            socket.shutdownOutput();

            log.info("文件发送完毕,用时:"+((System.currentTimeMillis()-st)/1000));
            //接收反馈信息
            socket.getInputStream().read(write);

            return new String(write).contains("success");


        } catch (IOException e) {
            log.severe(e.getMessage());
        } finally {
            try {
                if(fileInputStream!=null)fileInputStream.close();
                if(outputStream!=null)outputStream.close();
                if(socket!=null)socket.close();
            } catch (IOException e) {
                log.severe(e.getMessage());
            }

        }
        return false;

    }

    /**
     * 文件名转换为字节码
     * @param fileName
     * @return byte[0] : 文件名长度,
     */
    private byte[] buildFileName(String fileName){

        byte[] bytes1 = getLastFileName(fileName).getBytes();
        byte[] res = new byte[bytes1.length+1];
        res[0] = (byte) bytes1.length;
        for(int i = 0;i<res[0];i++){
            res[i+1] = bytes1[i];
        }
        return res;

    }
    /**
     * 获取文件名
     * @param fileName 文件全路径名
     * @return 文件名
     */
    private String getLastFileName(String fileName){
        int i = fileName.lastIndexOf("\\");
        int j = fileName.lastIndexOf("/");
        if(i>=0&&i<fileName.length())return fileName.substring(i+1);
        if(j>=0&&j<fileName.length())return fileName.substring(j+1);
        log.severe("获取文件名失败");
        System.exit(0);
        return null;
    }
    /**
     * 程序入口,启动服务器
     * @param args args[0]: 服务器ip地址  args[1]: 端口号
     *             -1 [发送的文件路径]
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {


        int ports = 10086;
        String ips = "127.0.0.1";
        switch (args.length) {

            case 0:
                log.severe("需要参数 【服务器ip地址】 【端口号(10086)】");
                System.exit(0);
            case 2:
                ports = Integer.parseInt(args[1]);
            case 1:
                ips = args[0];


        }
        TCPClient tcpClient = new TCPClient(ips,ports);
        Scanner scanner = new Scanner(System.in);
        String s;
        while((s = scanner.nextLine())!=null){
            if ("exit".equals(s)) {
                System.exit(0);
            }
            String[] s1 = s.split(" ");
            if(s1.length<2) {
                System.out.println("error:\n  -1 [发送的文件路径] \n  -2 [...]");
                continue;
            }
            if("-1".equals(s1[0])){
                System.out.println(s1[1]);

                tcpClient.sendFile(s1[1]);
            }
        }
    }

}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务