欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-01 08:02:30
...

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指令开启的端口,在某些平台上有限制。文件传输的格式没有要求。

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