pc端(JAVA)和Android通过tcp连续传输图片并显示

长连接(连续传输)的tcp传图在网上的博客和资源寥寥无几,所以写下这篇博客记录一下


一、TCP基础通信程序

这是PC端(C++,JAVA)和Android端的测试程序
TCP通信(PC作为Server,安卓手机作为Client)

二、长连接与连续通信

长连接

长连接就是保持一个心跳信号,过一段时间就连接一次,告诉对面自己还在

连续通信

连续通信是在一个端口上进行持续不断的传输,这个时候相比简单的传输而言,需要保持tcp端口连接

三、程序

PC端(JAVA)程序:
在主程序中加入javanew SocketTest2();即可

package com.company;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.channels.FileChannel;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

public class SocketTest2 {
    private ScheduledThreadPoolExecutor mScheduledThreadPoolExecutor = null;
    private Runnable mRunnable = null;
    private ScheduledFuture<?> mScheduledFuture = null;
    private Socket mSocket = null;
    int i=0;
    private Logger mLogger = Logger.getLogger(SocketTest2.class.getName());

    private void session() {
        FileInputStream dis = null;
        OutputStream dos = null;
        try {
            while (true) {
                dis =new FileInputStream("C:\\Users\\S\\Desktop\\Gray_coat\\"+i+".jpg");
                System.out.println(dis.available());

                FileChannel fc = dis.getChannel();
                mLogger.info(String.valueOf(fc.size()));
                dos = mSocket.getOutputStream();
                mLogger.info("准备");
                String data = "PC时间:" + System.currentTimeMillis();
                byte[] buf = new byte[1024];
                int len =0;
                while((len=dis.read(buf))!=-1) {
                    dos.write(buf, 0, len);
                }
                //dos.flush();
                mLogger.info("传完");
                i++;
                Thread.sleep(500);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                mSocket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

            mSocket = null;
        }
    }

    public SocketTest2() {
        mScheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);

        mRunnable = new Runnable() {
            @Override
            public void run() {
                if (mSocket == null || !mSocket.isConnected()) {
                    mLogger.info("尝试建立连接...");
                    try {
                        mSocket = new Socket("localhost", 7778);
                        mLogger.info("建立新连接:" + mSocket.toString());

                        CompletableFuture.runAsync(new Runnable() {
                            @Override
                            public void run() {
                                session();
                            }
                        });
                    } catch (Exception e) {
                        mLogger.info("连接异常");
                    }
                } else {
                    mLogger.info("连接心跳检测:当前已经建立连接,无需重连");
                }
            }
        };

        // 每隔3秒周期性的执行心跳检测动作。
        mScheduledFuture = mScheduledThreadPoolExecutor.scheduleAtFixedRate(mRunnable, 0, 1, TimeUnit.SECONDS);
    }
}

Android端程序:

package com.example.tongxin;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ImageView;
import android.widget.Toast;





import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import android.widget.TextView;


import android.os.Bundle;
import android.util.Log;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;


public class MainActivity extends AppCompatActivity {
    private String TAG = "Android端";
    static boolean Flag = false;
    ImageView image = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        image = (ImageView) findViewById(R.id.image);
        new ServerThread().start();
    }

    private class ServerThread extends Thread {

        @Override
        public void run() {
            ServerSocket serverSocket = null;
            try {
                serverSocket = new ServerSocket(7777);
                while (true) {
                    Socket socket = serverSocket.accept();
                    Log.d(TAG, "接受连接");

                    try {
                        System.out.println("开始接受图片时间" + System.currentTimeMillis());
                        InputStream bis = socket.getInputStream();
                        System.out.println(bis.available());
                        System.out.println("图片解码前时间" + System.currentTimeMillis());
                        Bitmap bitmap = BitmapFactory.decodeStream(bis);
                        System.out.println("关闭流前时间" + System.currentTimeMillis());
                        bis.close();
                        System.out.println("输出图片前时间" + System.currentTimeMillis());
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                //更新UI
                                image.setImageBitmap(bitmap);
                                System.out.println("输出图片后时间" + System.currentTimeMillis());
                            }

                        });

                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            //socket.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (serverSocket != null) {
                    try {
                        //serverSocket.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}


再在layout中加入一个imageview:

<ImageView
        android:id="@+id/image"
        android:layout_width="320dp"
        android:layout_height="520dp"
        tools:ignore="MissingConstraints"/>

注意:在java中可以直接用mSocket.getOutputStream().write()发送数据,用socket.getInputStream()接收数据,这是一一对应的,如果使用c++平台的tcp通信,就需要添加代码进行适配。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
可以通过以下步骤接收客户端发送的TCP报文: 1. 创建一个ServerSocket对象并绑定端口号。 2. 调用ServerSocket的accept()方法,等待客户端连接请求。 3. 当有客户端连接请求时,accept()方法会返回一个Socket对象,该对象表示与客户端的通信连接。 4. 通过Socket对象的getInputStream()方法获取输入流,可以读取客户端发送的TCP报文。 5. 通过Socket对象的getOutputStream()方法获取输出流,可以向客户端发送TCP报文。 下面是一个简单的Java TCP服务器端的示例代码: ```java import java.io.*; import java.net.*; public class Server { public static void main(String[] args) throws IOException { int port = 8888; ServerSocket serverSocket = new ServerSocket(port); System.out.println("Waiting for client connection..."); Socket clientSocket = serverSocket.accept(); System.out.println("Client connected: " + clientSocket); BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println("Received message from client: " + inputLine); out.println("Server received message: " + inputLine); } in.close(); out.close(); clientSocket.close(); serverSocket.close(); } } ``` 在上面的示例代码中,我们创建了一个ServerSocket对象,并绑定了端口号8888。然后调用accept()方法等待客户端连接请求。当有客户端连接时,我们获取客户端Socket对象,并通过Socket对象获取输入流和输出流。在while循环中,我们不断读取客户端发送的消息,并向客户端发送回复。最后,我们关闭输入流、输出流和Socket对象,并关闭ServerSocket对象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值