socket简介及通信实例Android(客户端)与AlibabaCloud(服务器)收发文件

socket定义


    socket通常也称作"套接字",实现服务器和客户端之间的物理连接,并进行数据传输,主要有UDP和TCP两个协议。Socket处于网络协议的传输层。下面通过具体的例子来说明socket的一些常见用法。(下载请见底部)

Android客户端/java客户端

代码:

package com.example.eric.mylibrary;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.Socket;

/**
 * 发送文件
 * Created by Eric_ on 2018/7/22.
 */

public class SocketDemo {
    public static void main(String[] a){
        final String path = "xxxx";//文件路径
        final String fileName = "xxxx";//文件名称
        final String ipAddress = "xxxx";//服务器ip地址
        final int port = xxxx;//服务器开放端口
        Thread sendThread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(FileSend(fileName, path, ipAddress, port));
            }
        });
        sendThread.start();
    }
    public static String FileSend(String fileName, String path, String ipAddress, int port){
        try {
            Socket socket = new Socket(ipAddress, port);//设置socket,并进行连接connect
            int bufferSize = 8192;
            byte[] buf = new byte[bufferSize];//数据存储
            // 选择进行传输的文件
            File file = new File(path + fileName);
            System.out.println("文件长度:" + (int) file.length());
            DataInputStream input = new DataInputStream(new FileInputStream(path + fileName));
            DataOutputStream output = new DataOutputStream(socket.getOutputStream());//将socket设置为数据的传输出口
            DataInputStream getAck = new DataInputStream(socket.getInputStream());//设置socket数据的来源
            //将文件名传输过去
            output.writeUTF(file.getName());
            output.flush();
            //将文件长度传输过去
            output.writeLong((long) file.length());
            output.flush();

            int readSize = 0;

            while(true)
            {
                if(input != null)
                {
                    readSize = input.read(buf);
                }
                if(readSize == -1)
                    break;

                output.write(buf, 0, readSize);

                if(!getAck.readUTF().equals("OK"))
                {
                    System.out.println("服务器"+ ipAddress + ":" + port + "失去连接!");
                    break;
                }
            }
            output.flush();// 注意关闭socket链接,不然客户端会等待server的数据过来,// 直到socket超时,导致数据不完整。
            input.close();
            output.close();
            socket.close();
            getAck.close();
            System.out.println("文件传输完成");
            return fileName + " 发送完成";
        } catch (Exception e) {
            return "发送错误:\n" + e.getMessage();
        }
    }
}

服务器:

代码:

package com.example.eric.mylibrary;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;


/**
 * 服务端,接受文件
 * Created by Eric_ on 2018/7/22.
 */

public class AcceptSocketFile {
    static boolean isEnable;
    private static ServerSocket server;
    static int port = xxxx;
    public static void main(String[] a) {
        final String path = "xxxx"; //接受文件路径
//         服务器端用于监听Socket的线程
        Thread listener = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    server = new ServerSocket(port);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (server != null) {
                    while (true) {
                        ReceiveFile(path);
                    }
                }
            }
        });
        listener.start();
    }
    public static String ReceiveFile(String path) {
        try {
            Socket socket = server.accept();
            System.out.println("客户端"+ socket.getInetAddress() +"已连接");
            int bufferSize = 8192;
            byte[] buf = new byte[bufferSize];//数据存储
            long donelen = 0;//传输完成的数据长度
            long filelen = 0;//文件长度
            //将socket数据作为数据输入流
            DataInputStream input = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
            //以客户端的IP地址作为存储路径
            String fileDir = path + "\\" + socket.getInetAddress().toString().substring(1, socket.getInetAddress().toString().length());;
            File file = new File(fileDir);
            //判断文件夹是否存在,不存在则创建
            if(!file.exists())
            {
                file.mkdir();
            }

            String fileName = input.readUTF();//读取文件名

            //设置文件路径
            String filePath = fileDir + "\\" + fileName;


            file = new File(filePath);

            if(!file.exists())
            {
                file.createNewFile();
            }

            DataOutputStream fileOut = new DataOutputStream(
                    new BufferedOutputStream(new FileOutputStream(file)));


            filelen = input.readLong();//读取文件长度

            System.out.println("文件的长度为:" + filelen + "\n");
            System.out.println("开始接收文件!" + "\n");
            DataOutputStream ack = new DataOutputStream(socket.getOutputStream());

            while (true) {
                int read = 0;
                if (input != null) {
                    read = input.read(buf);
                    ack.writeUTF("OK");//结束到数据以后给client一个回复
                }

                if (read == -1) {
                    break;
                }
                donelen += read;
                // 下面进度条本为图形界面的prograssBar做的,这里如果是打文件,可能会重复打印出一些相同的百分比
                System.out.println("文件接收了" + (donelen * 100 / filelen)
                        + "%\n");
                fileOut.write(buf, 0, read);
            }

            if(donelen == filelen)
                System.out.println("接收完成,文件存为" + file + "\n");
            else
            {
                System.out.printf("IP:%s发来的%s传输过程中失去连接\n",socket.getInetAddress(),fileName);
                file.delete();
            }
            ack.close();
            input.close();
            fileOut.close();
            return fileDir+"接受完成";
        } catch (Exception e) {
            return "接收错误:\n" + e.getMessage();
        }
    }
}

备注:如果是租的服务器,最好通过官网来开启端口,通过Linux指令开启的端口,在某些平台上有限制。文件传输的格式没有要求。

Ecplise项目下载地址:https://github.com/zhangyupy/SocketTest

版权声明:--------------------------------------------博文可随意转载,但请注明出处,谢谢!-------------------------------------------- https://blog.csdn.net/weixin_42474261/article/details/81182375

猜你喜欢

转载自blog.csdn.net/weixin_42474261/article/details/81196944