android和PC(Python)通过USB(adb模式)基于Socket传输图像(视频)

由于在实验室做项目的需要,参考了博客上的各种代码,然后自己写写改改搞了十几天,今天终于有点模样了,然后分享出来也算是笔记又可以给后面的兄弟分享经验。(可能一时间不会太完善我会一直修改完善,后面工程会分享到我的GitHub,毕竟现在的博客会员太贵)

还是先上代码吧。不过我做的是android作为服务器端(接收显示图像),PC端作为客户端(发送图像)。

1、android服务器端(开发平台是androidstudio):

①权限设置。socket通信是TCP/IP方式,相当于局域网,必须获取网络权限

<uses-permission android:name="android.permission.INTERNET" />

②部分关键代码。关键代码就是一个线程,因为通信的连接是阻塞机制(开始我也不懂,后来一想也挺简单的,你android端是服务器端,就像你想从别人那儿通过电话得到你中了大奖的消息,此刻别人还没打来电话你就只能坐着干等,一直等就形成了阻塞,等到别人打来电话,电话响了你接通电话就建立了通信。如果主线程也来这样等的话就是让大老板等手下浪费资源,就派一个小弟去等就行了于是建立一个子线程去等),子线程程序(绿色为关键代码,而且服务器端代码和客户端代码颜色对应):

public class SocketServerPictureThread extends Thread {
    public String Length;   //用来放客户端发过来图像的长度
    private Socket socket;  
    private int offset=0;   
    private BufferedOutputStream output;    //输出流
    private BufferedInputStream input;      //输入流
    @Override
    public void run() {
        try {
            ServerSocket serverSocket = new ServerSocket(9000);  //服务器端端口,数据就是在这个端口上
            while (true) {
                socket = serverSocket.accept();                  //他就是阻塞,没电话来就一直等,下面都执行不了
                                                                 //电话一来就建立连接,开始执行下面代码
                output=new BufferedOutputStream(socket.getOutputStream());
                input=new BufferedInputStream(socket.getInputStream());
                Length=readMsgFromSocket(input);                //对面发来了图像大小,我好准备空间
                send_msg.post(new Runnable() {
                    @Override
                    public void run() {
                        send_msg.setText(Length);              //这是为了看到图像大小,线程中必须这样才能显示到UI界面
                    }
                });                                        
                SendMsg("123");                                //随便发送的,让对面知道我收到了长度
                byte[] bitmapBuff=new byte[Integer.valueOf(Length)];      //分配放图片的空间
                while (offset<Integer.valueOf(Length))
                {
                    int len=input.read(bitmapBuff,offset,Integer.valueOf(Length)-offset);//读取图像数据放空间里
                    offset+=len;
                }
                Length="";
                final Bitmap bitmap=BitmapFactory.decodeByteArray(bitmapBuff,0,offset);   //解压图像文件
                image.post(new Runnable() {                             
                    @Override
                    public void run() {
                        image.setImageBitmap(bitmap);                                 //将图片在UI上显示出来
                    }
                });
                SendMsg("12");                                   //告诉客户端这边图像已经接收完,我们可以挂了
                socket.close();                                   //我先挂了电话先
                offset=0;                                        //这点比较坑,参考的博客都没有写,让我调了几天,为什么第一张传了第二张就出问题了呢,原因是offset没复位为 0 ,第二个开始还是前面的值,一张完了就开始从新建立连接接收下一张图片了
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public String readMsgFromSocket(InputStream in) {                   //读取客户端发过来的文本数据
        String msg = "";
        byte[] tempbuffer = new byte[1024];
        try {
            int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);
            msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return msg;
    }

    public void SendMsg(String msg) {                                  //发送文本数据给客户端
        String msg_1 = msg;
        try {
            output.write(msg_1.getBytes("UTF-8"));
            output.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2、PC客户端(pycharm平台):

①客户端就简单了,前面不是在等消息嘛,我这边只要给他打电话就行,他那边可能等得有点久了,直接全部代码:

# -*- coding: utf-8 -*-
import _thread
import socket
import os

def server_picture_socket():
   
    picture_number = 1         //第几张图像
    current_picture_dir = os.path.dirname(os.path.abspath(__file__))    //读取图像的文件地址
    while True:
        client_address = ('127.0.0.1', 5000)
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   //这个就是“拨打电话”了
        client_socket.connect(client_address)
        print("准备发送")
        if picture_number>3://我一共连续传了3张图,如果多来个几百张就是视频了
            picture_number=1
        server_picture_path = os.path.join(current_picture_dir, str(picture_number) + ".jpg")
        print(server_picture_path)
        while os.path.exists(server_picture_path):
            server_picture_open = open(server_picture_path, 'rb')
            file_size = os.stat(server_picture_path).st_size
            x = str(file_size)
            client_socket.send(x.encode("UTF-8"))                         //接通了电话,告诉服务器端你可能要接收                                                                                                                                           //                                                   的图像大小,让他可以分配放图像空间的大小了,为我准备好包间
            eee= client_socket.recv(1024).decode()           //晓得服务器端接收到了长度
            length = 0
            while length != file_size:
                pictrue_data = server_picture_open.read(1024)
                client_socket.sendall(pictrue_data)                       //发送图像数据给服务器端
                length += len(pictrue_data)
            server_picture_open.close()
            picture_number += 1
            re = client_socket.recv(1024).decode()                        //对面发过来消息他已经接收完图像
            client_socket.close()                             //接收完了呀,你挂了我也挂吧,还有消息就再给你打电话了
            break
        print("发送完毕")

if __name__ == '__main__':
    server_picture_socket()

3、通过USB是android的一个adb,所以要配置端口和adb环境的添加:

环境添加就先在androidstudio的setting中找到SDK文件地址,里面有个adb文件,再在环境变量中添加就行:可百度;

cmd键入 adb 出现该图就添加好了,然后就是端口的匹配:

接着键入 adb forward tcp:5000 tcp:9000 (端口程序中有)

啊,写了接近2个小时,毕竟我的水平有限,不然的话我两天就搞定这个垃圾程序了

后面传到github上,目前觉得有用的可以直接联系我发工程

 

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值