通过socket编程将png图像文件从服务器(桌面)发送到客户端(android)

2024-03-17

我创建了一个 Android 应用程序,其中 Android 应用程序充当客户端,服务器驻留在桌面上。我正在使用套接字编程进行通信。我已成功在客户端和服务器之间传输消息,但我不知道如何传输图像。我需要将图像文件从服务器发送到客户端,不是从客户端到服务器

任何人都可以帮我解决从服务器向客户端发送 png 图像的解决方案吗?

到目前为止,这是我的代码:

客户端

private int SERVER_PORT = 9999;
class Client implements Runnable {
            private Socket client;
            private PrintWriter out;
            private Scanner in;

            @Override
            public void run() {
                try {
                    client = new Socket("localhost", SERVER_PORT);
                    Log.d("Client", "Connected to server at port " + SERVER_PORT);
                    out = new PrintWriter(client.getOutputStream());
                    in = new Scanner(client.getInputStream());
                    String line;

                    while ((line = in.nextLine()) != null) {
                        Log.d("Client", "Server says: " + line);
                        if (line.equals("Hello client")) {
                            out.println("Reply");
                            out.flush();
                        }
                    }

                } catch (UnknownHostException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }

服务器类

class ServerThread implements Runnable {
        private ServerSocket server;

        @Override
        public void run() {
            try {
                server = new ServerSocket(SERVER_PORT);
                Log.d("Server", "Start the server at port " + SERVER_PORT
                        + " and waiting for clients...");
                while (true) {
                    Socket socket = server.accept();
                    Log.d("Server",
                            "Accept socket connection: "
                                    + socket.getLocalAddress());
                    new Thread(new ClientHandler(socket)).start();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

    class ClientHandler implements Runnable {

        private Socket clientSocket;
        private PrintWriter out;
        private Scanner in;

        public ClientHandler(Socket clietSocket) {
            this.clientSocket = clietSocket;
        }

        @Override
        public void run() {
            try {
                out = new PrintWriter(clientSocket.getOutputStream());
                in = new Scanner(clientSocket.getInputStream());
                String line;
                Log.d("ClientHandlerThread", "Start communication with : "
                        + clientSocket.getLocalAddress());
                out.println("Hello client");
                out.flush();
                while ((line = in.nextLine()) != null) {
                    Log.d("ClientHandlerThread", "Client says: " + line);
                    if (line.equals("Reply")){
                        out.print("Server replies");
                        out.flush();
                    }
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    }

这里有服务器和客户端代码,用于从服务器向客户端发送/接收(图像)文件。 客户端将图像保存在外部存储中,如果您想将其保存在其他地方,请更改它。 客户端函数返回接收到的图像的位图,您也可以通过注释代码中的行来避免这种情况。

要使用这些函数,请使用类似于以下内容的内容:

注意这两个函数必须从主 UI 线程以外的线程调用:

// To receive a file
try
{
    // The file name must be simple file name, without file separator '/'
    receiveFile(myClientSocket.getInputStream(), "myImage.png");
}
catch (Exception e)
{
    e.printStackTrace();
}

// to send a file
try
{
    // The file name must be a fully qualified path
    sendFile(myServerSocket.getOutputStream(), "C:/MyImages/orange.png");
}
catch (Exception e)
{
    e.printStackTrace();
}

接收函数:(复制粘贴到客户端)

/**
 * Receive an image file from a connected socket and save it to a file.
 * <p>
 * the first 4 bytes it receives indicates the file's size
 * </p>
 * 
 * @param is
 *           InputStream from the connected socket
 * @param fileName
 *           Name of the file to save in external storage, without
 *           File.separator
 * @return Bitmap representing the image received o null in case of an error
 * @throws Exception
 * @see {@link sendFile} for an example how to send the file at other side.
 * 
 */
public Bitmap receiveFile(InputStream is, String fileName) throws Exception
{

String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
    String fileInES = baseDir + File.separator + fileName;

    // read 4 bytes containing the file size
    byte[] bSize = new byte[4];
    int offset = 0;
    while (offset < bSize.length)
    {
        int bRead = is.read(bSize, offset, bSize.length - offset);
        offset += bRead;
    }
    // Convert the 4 bytes to an int
    int fileSize;
    fileSize = (int) (bSize[0] & 0xff) << 24 
               | (int) (bSize[1] & 0xff) << 16 
               | (int) (bSize[2] & 0xff) << 8
               | (int) (bSize[3] & 0xff);

    // buffer to read from the socket
    // 8k buffer is good enough
    byte[] data = new byte[8 * 1024];

    int bToRead;
    FileOutputStream fos = new FileOutputStream(fileInES);
    BufferedOutputStream bos = new BufferedOutputStream(fos);
    while (fileSize > 0)
    {
        // make sure not to read more bytes than filesize
        if (fileSize > data.length) bToRead = data.length;
        else bToRead = fileSize;
        int bytesRead = is.read(data, 0, bToRead);
        if (bytesRead > 0)
        {
            bos.write(data, 0, bytesRead);
            fileSize -= bytesRead;
        }
    }
    bos.close();

    // Convert the received image to a Bitmap
    // If you do not want to return a bitmap comment/delete the folowing lines
    // and make the function to return void or whatever you prefer.
    Bitmap bmp = null;
    FileInputStream fis = new FileInputStream(fileInES);
    try
    {
        bmp = BitmapFactory.decodeStream(fis);
        return bmp;
    }
    finally
    {
        fis.close();
    }
}

发送端功能:(复制粘贴到服务器端)

/**
 * Send a file to a connected socket.
 * <p>
 * First it sends file size in 4 bytes then the file's content.
 * </p>
 * <p>
 * Note: File size is limited to a 32bit signed integer, 2GB
 * </p>
 * 
 * @param os
 *           OutputStream of the connected socket
 * @param fileName
 *           The complete file's path of the image to send
 * @throws Exception
 * @see {@link receiveFile} for an example how to receive file at other side.
 * 
 */
public void sendFile(OutputStream os, String fileName) throws Exception
{
    // File to send
    File myFile = new File(fileName);
    int fSize = (int) myFile.length();
    if (fSize < myFile.length())
    {
        System.out.println("File is too big'");
        throw new IOException("File is too big.");
    }

    // Send the file's size
    byte[] bSize = new byte[4];
    bSize[0] = (byte) ((fSize & 0xff000000) >> 24);
    bSize[1] = (byte) ((fSize & 0x00ff0000) >> 16);
    bSize[2] = (byte) ((fSize & 0x0000ff00) >> 8);
    bSize[3] = (byte) (fSize & 0x000000ff);
    // 4 bytes containing the file size
    os.write(bSize, 0, 4);

    // In case of memory limitations set this to false
    boolean noMemoryLimitation = true;

    FileInputStream fis = new FileInputStream(myFile);
    BufferedInputStream bis = new BufferedInputStream(fis);
    try
    {
        if (noMemoryLimitation)
        {
            // Use to send the whole file in one chunk
            byte[] outBuffer = new byte[fSize];
            int bRead = bis.read(outBuffer, 0, outBuffer.length);
            os.write(outBuffer, 0, bRead);
        }
        else
        {
            // Use to send in a small buffer, several chunks
            int bRead = 0;
            byte[] outBuffer = new byte[8 * 1024];
            while ((bRead = bis.read(outBuffer, 0, outBuffer.length)) > 0)
            {
                os.write(outBuffer, 0, bRead);
            }
        }
        os.flush();
    }
    finally
    {
        bis.close();
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过socket编程将png图像文件从服务器(桌面)发送到客户端(android) 的相关文章

  • minHeight 有什么作用吗?

    在附图中 我希望按钮列与图像的高度相匹配 但我也希望按钮列有一个最小高度 它正确匹配图像的高度 但不遵守 minHeight 并且会使按钮向下滑动 我正在为按钮列设置这些属性
  • 带有自定义阵列适配器的微调器不允许选择项目

    我使用自定义阵列适配器作为微调器 但是 当在下拉列表中选择一个项目时 下拉列表保留在那里 并且微调器不会更新 这是错误行为 与使用带有字符串的通用数组适配器相比 这是自定义类 我错过了什么吗 谢谢 public class Calendar
  • 什么是 SO_SNDBUF 和 SO_RCVBUF

    你能解释一下到底是什么吗SO SNDBUF and SO RCVBUF选项 好的 出于某种原因 操作系统缓冲传出 传入数据 但我想澄清这个主题 他们的角色 通 常 是什么 它们是每个套接字的缓冲区吗 传输层的缓冲区 例如 TCP 缓冲区 和
  • Flutter 深度链接

    据Flutter官方介绍深层链接页面 https flutter dev docs development ui navigation deep linking 我们不需要任何插件或本机 Android iOS 代码来处理深层链接 但它并没
  • 从 android 简单上传到 S3

    我在网上搜索了从 android 上传简单文件到 s3 的方法 但找不到任何有效的方法 我认为这是因为缺乏具体步骤 1 https mobile awsblog com post Tx1V588RKX5XPQB TransferManage
  • 反思 Groovy 脚本中声明的函数

    有没有一种方法可以获取 Groovy 脚本中声明的函数的反射数据 该脚本已通过GroovyShell目的 具体来说 我想枚举脚本中的函数并访问附加到它们的注释 Put this到 Groovy 脚本的最后一行 它将作为脚本的返回值 a la
  • 制作java包

    我的 Java 类组织变得有点混乱 所以我要回顾一下我在 Java 学习中跳过的东西 类路径 我无法安静地将心爱的类编译到我为它们创建的包中 这是我的文件夹层次结构 com david Greet java greeter SayHello
  • 如何在不更改手机语言的情况下更改Android应用程序语言?

    我希望用户在应用程序内选择一种语言 选择语言后 我希望字符串使用特定语言 如果我更改手机语言 那么我的应用程序将以设置的语言运行 我无法找到任何在不更改手机语言的情况下设置语言的方法 此外 一旦设置了语言 更改就应该反映出来 有人可以建议一
  • Java直接内存:在自定义类中使用sun.misc.Cleaner

    在 Java 中 NIO 直接缓冲区分配的内存通过以下方式释放 sun misc Cleaner实例 一些比对象终结更有效的特殊幻像引用 这种清洁器机制是否仅针对直接缓冲区子类硬编码在 JVM 中 或者是否也可以在自定义组件中使用清洁器 例
  • org.jdesktop.application 包不存在

    几天以来我一直在构建一个 Java 桌面应用程序 一切都很顺利 但是今天 当我打开Netbeans并编译文件时 出现以下编译错误 Compiling 9 source files to C Documents and Settings Ad
  • 将多模块 Maven 项目导入 Eclipse 时出现问题 (STS 2.5.2)

    我刚刚花了最后一个小时查看 Stackoverflow com 上的线程 尝试将 Maven 项目导入到 Spring ToolSuite 2 5 2 中 Maven 项目有多个模块 当我使用 STS 中的 Import 向导导入项目时 所
  • 使用 SAX 进行 XML 解析 |如何处理特殊字符?

    我们有一个 JAVA 应用程序 可以从 SAP 系统中提取数据 解析数据并呈现给用户 使用 SAP JCo 连接器提取数据 最近我们抛出了一个异常 org xml sax SAXParseException 字符引用 是无效的 XML 字符
  • 当手机旋转(方向改变)时如何最好地重新创建标记/折线

    背景 开发一个使用 Android Google Map v2 的本机 Android 应用程序 使用android support v4 app FragmentActivity 在 Android v2 2 上运行 客观的 在更改手机方
  • Android - 将 ImageView 保存到具有全分辨率图像的文件

    我将图像放入 ImageView 中 并实现了多点触控来调整 ImageView 中的图像大小和移动图像 现在我需要将调整大小的图像保存到图像文件中 我已经尝试过 getDrawingCache 但该图像具有 ImageView 的大小 我
  • 如何在 Maven 中显示消息

    如何在 Maven 中显示消息 在ant中 我们确实有 echo 来显示消息 但是在maven中 我该怎么做呢 您可以使用 antrun 插件
  • Android 如何聚焦当前位置

    您好 我有一个 Android 应用程序 可以在谷歌地图上找到您的位置 但是当我启动该应用程序时 它从非洲开始 而不是在我当前的城市 国家 位置等 我已经在developer android com上检查了信息与位置问题有关 但问题仍然存在
  • Springs 元素“beans”不能具有字符 [children],因为该类型的内容类型是仅元素

    我在 stackoverflow 中搜索了一些页面来解决这个问题 确实遵循了一些正确的答案 但不起作用 我是春天的新人 对不起 这是我的调度程序 servlet
  • 如何修复“sessionFactory”或“hibernateTemplate”是必需的问题

    我正在使用 Spring Boot JPA WEB 和 MYSQL 创建我的 Web 应用程序 它总是说 sessionFactory or hibernateTemplate是必需的 我该如何修复它 我已经尝试过的东西 删除了本地 Mav
  • 无法将 admob 与 firebase iOS/Android 项目链接

    我有两个帐户 A 和 B A 是在 Firebase 上托管 iOS Android unity 手机游戏的主帐户 B 用于将 admob 集成到 iOS Android 手机游戏中 我在尝试将 admob 分析链接到 Firebase 项
  • JAVA - 如何从扫描仪读取文件中检测到“\n”字符

    第一次海报 我在读取文本文件的扫描仪中读取返回字符时遇到问题 正在读取的文本文件如下所示 test txt start 2 0 30 30 1 1 90 30 0 test txt end 第一行 2 表示两个点 第二行 位置索引 0 xp

随机推荐

  • 将列表打印为表格数据

    我对 Python 还很陌生 现在我正在努力如何很好地格式化我的数据以进行打印输出 我有一个用于两个标题的列表 以及一个应该是表格内容的矩阵 就像这样 teams list Man Utd Man City T Hotspur data n
  • 在 Mac 上安装 xgboost - ld: 未找到库

    我正在尝试在我的 Mac 上安装支持 OpenMP 的 xgboost 我安装了gcc没有问题 brew install gcc without multilib 然后克隆 git 存储库 git clone recursive https
  • 在 Python 中使用 for 循环从外部文件打印列表中的每一项

    我正在编写一个从 txt 文件读取 2D 列表的程序 我试图循环遍历该列表 并打印其中的每个项目 我使用了 for 循环来遍历列表中的每个项目 txt 文件中二维列表的内容为 1 10 Hello World 这是我到目前为止打开文件 读取
  • Bokeh - 堆叠和分组图表

    是否可以在散景中创建一个既堆叠又分组的图 有点像http www highcharts com demo column stacked and grouped http www highcharts com demo column stac
  • Datastax java 驱动程序 3.0.0 未找到枚举注释

    希望我能很好地阅读文档 http docs datastax com en developer java driver 3 0 java driver reference crudOperations html http docs data
  • 如何使用 glide 加载圆形 appcompat 操作栏徽标

    到目前为止 我已经完成了以下操作 如果我省略圆形图像创建部分 它可以正常工作 但我必须在操作栏中显示圆形图像 这是我到目前为止所尝试过的 任何帮助将不胜感激 Glide with mContext load doctorDetailsLis
  • 使用 Android SDK 3.0 登录 Facebook 导致 ANR 或根本无法工作

    为了让用户在 Android 应用程序中登录 Facebook 我尝试使用以下代码 用户登录后 应获取其所有朋友的位置 不幸的是 此代码有时会导致 ANR 如 Google Play 开发者控制台中报告的那样 有时甚至不起作用 如果我删除
  • 访问 iframe 中的表

    i have a website login email protected cdn cgi l email protection pas 12345678 log in and go to the drivers section left
  • 代码签名错误:身份“iPhone Developer”与默认钥匙串中的任何有效证书/私钥对不匹配

    我正在尝试创建我的应用程序的临时发行版以发送给同事 尝试存档我的项目以供分发时出现以下错误 代码签名错误 身份 iPhone 开发者 与任何有效的不匹配 中的证书 私钥对 默认钥匙串 这些是我遵循的步骤 我已在配置门户中注册了该设备 我已在
  • Vulkan命令执行顺序

    引用Vulkan 1 0规范文档 chapter 5 Command Buffers 第4段 除非另有说明 并且没有显式同步 否则通过命令缓冲区提交到队列的各种命令可以按相对于彼此的任意顺序执行 和 或同时执行 在第2 1 1章 队列操作
  • LDADD 和 LIBADD 有什么区别?

    我正在尝试设置一个混合使用 libtool 库和可执行文件的 automake 项目 并且我很难理解 automake 文档 尤其是 as 涉及告诉编译器进行链接 那么有人可以解释一下之间的区别吗LDADD and LIBADD 像 什么时
  • 如何将 cv::Mat 转换为 QImage 或 QPixmap?

    我尝试环顾四周并尝试了我发现的所有内容 但尚未找到解决此问题的方法 我正在尝试通过单击按钮来更新 QT 应用程序中的图像 在构造函数中 我成功地显示了图像 cv Mat temp cv Mat this gt cv size CV 8UC3
  • “推送通知”-反馈、卸载应用

    Apple 推送通知 反馈服务 您如何知道用户何时卸载您的应用程序 这样您就可以从推送服务器中删除他们的设备令牌 你根本不知道 您可以获取对于同一应用程序令牌字符串可能相同的设备标识字符串 并跟踪特定设备的令牌是否已更改 因此 您可以使用新
  • Web Essentials 2017 和 TypeScript 定义生成

    刚刚从 Visual Studio 市场安装了 Web Essentials 2017 但似乎缺少从 C 类创建 TypeScript 定义的功能 在 Web Essentials 2015 中 我将鼠标右键悬停在 C 类文件上 将会出现一
  • JavaScript 对象字面量和数组

    我有以下 JavaScript 代码 oCoord x null y null var aStack oCoord x 726 oCoord y 52 aStack push oCoord oCoord x 76 oCoord y 532
  • file_get_contents 失败并显示“getaddrinfo 失败:没有与主机名关联的地址”

    我正在尝试从另一台主机获取该页面 我按照 hph 手册所述 page file get contents http www example com echo page 但它失败了 在 apache 日志中我得到以下内容 Mon Oct 12
  • 为什么scss/css中文件名前面要加“_”或“_”?

    Why put scss 中文件名前面 filename scss 为什么需要 下划线 是 scss 的部分内容 这意味着样式表将被导入 import 到主样式表 即 styles scss 使用部分的优点是您可以使用多个文件来组织代码 并
  • 教义 2 中的关系

    我完全没有理解教义中的关联 我想知道单向和双向关系有什么区别 学说2中的正方和反方是什么 双向和单向关系 双向和单向与 PHP 对象中的引用有关 如你看到的here http www doctrine project org docs or
  • 使用 CGMutablePath 创建路径会创建指向错误 CGPoint 的线

    我打算在屏幕上用 2D 箭头显示 AR 对象的信息 所以我用了projectPoint获取物体在屏幕中对应的位置 我有这个函数返回将节点的 3D 位置转换为 2D 并CGPoint显示信息文本 func getPoint sceneView
  • 通过socket编程将png图像文件从服务器(桌面)发送到客户端(android)

    我创建了一个 Android 应用程序 其中 Android 应用程序充当客户端 服务器驻留在桌面上 我正在使用套接字编程进行通信 我已成功在客户端和服务器之间传输消息 但我不知道如何传输图像 我需要将图像文件从服务器发送到客户端 不是从客