精华内容
下载资源
问答
  • 非常好用的stm32USBHID双向通信代码DEMO,共享给大家,解决大家的难题,本人使用非常稳定,随时双向通信
  • 介绍中低速磁浮交通运行控制...浮列车车地双向通信、绝对定位和相对位置校正,构建基于对称交叉感应环线车地双向通信的MATC 系统,MATC系统已在唐山运行试验示范线完成基于移动闭塞的中低速磁浮列车的运行控制试验。
  • hid设备双向通信.rar

    2019-08-07 15:33:13
    STM32F407 USB HID DEVICE双向通信源码,可实现双向通信,与主机连接收发功能已测试
  • Android设备和PC设备在有线USB连接情况下能否双向通信,如何实现? 测试代码 PC端代码实现 import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io....

    预研目标

    Android设备和PC设备在有线USB连接情况下能否双向通信,如何实现?

    测试代码

    PC端代码实现

    import java.io.BufferedReader;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.nio.charset.StandardCharsets;
    
    public class Test {
    	public static void main(String[] args) {
            try {
            	//adb 的路径
            	String adbHome = "/Users/yinhaide/Library/Android/sdk/platform-tools/adb ";
            	//adb查看版本号
                String versionCmd = adbHome + "--version";
                //pc和手机的端口转发命令,可参考:https://blog.csdn.net/u013553529/article/details/80036227
                //不执行转发的话会出现:Connection refused 异常,pc或者手机端任意一端执行都可以
                String forwardCmd = adbHome + "forward tcp:8004 tcp:8004";
                //pc和手机的端口转发,两边端口号可一样也可以不一样,自行定义,不执行的话两边无法通信
                exec(forwardCmd);
                //测试读取adb版本号
                System.out.println("versionCmd: " + exec(versionCmd));
                //连接adb服务器,本地ip,也就是通过有线方式,需要手机端先开启服务器监听来自pc的socket连接
                Socket socket = new Socket("127.0.0.1", 8004);
                //socket的输出流,用来给手机端写数据
                //DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
                OutputStream writer = socket.getOutputStream();
                //writer.write("WXU138|0|1.0.0|{\"action\":\"pay_success\",\"cardid\":\"1245444\",\"userid\":\"haideyin\",\"total\":1,\"order_time\":126548951}|01a09092c13a58dd288f0e9bd7b641d7\r\n".getBytes());
                writer.write("WXU69|12|1.0.0|{\"action\":\"pay\",\"total\":1}|cc3d4f642efb68525ea4a7d21ff5ad7e\r\n".getBytes());
                //writer.write("WXU65|18|1.0.0|{\"action\":\"heartbeat\"}|153e2de52b54c5138f75112217138d47\r\n".getBytes());
                //writer.write("WXU62|19|1.0.0|{\"action\":\"cancel\"}|767f0c839210383786b371bd10094ea3\r\n".getBytes());
                //writer.write("WXC83|1|{\"action\":\"cancel\",\"errmsg\":\"哈哈哈哈\",\"errcode\":0}|2dc2f47c203b1a62d02031de9f5211ac\r\n".getBytes());
                writer.flush();
                //给手机端发送数据
                //dos.writeUTF("我是来自pc端的数据");
                //拿到socket的输入流,也就是手机端发来的数据流
                InputStream inputStream = socket.getInputStream();
                while (true) {
                	final int MLEN = 1024;
                    byte[] buff = new byte[MLEN];
                    int size = inputStream.read(buff); 
                    //读取来自手机端的数据
                    if (size >= 0) { // 包超缓冲
                        String data = new String(buff, StandardCharsets.UTF_8);
                        System.out.println("收到来自手机端的数据:"+ data);
                    }
                }
                
                //dos.writeUTF("我是来自pc端的数据222");
                //最后关闭socket
                //socket.close();
            } catch (IOException ex) {
                System.out.println(ex.getMessage());
            }
        }
    	
    	/**
    	 * 执行adb指令
    	 * @param cmd adb指令
    	 * @return 返回执行结果的字符串
    	 */
    	public static String exec(String cmd){
            Process process;
            try {
                process=Runtime.getRuntime().exec(cmd);
                return InputStream2String(process.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
    	}
    	
    	/**
    	 * adb指令的InputStream转成字符串输出
    	 * @param inputStream adb指令inputStream
    	 * @return 返回执行结果的字符串
    	 */
    	public static String InputStream2String(InputStream inputStream){
            String result="";
            BufferedReader br=new BufferedReader(new InputStreamReader(inputStream));
            try {
                String temp="";
                while ((temp=br.readLine())!=null){
                    result+=temp+"\n";
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return result;
        }
    }
    
    • Android端代码实现
    package com.example.myapplication;
    
    import android.util.Log;
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    class AndroidServer extends Thread {
    
        @Override
        public void run() {
            //如果出现端口占用  请参考解决方案:https://www.cnblogs.com/mantti/p/5262902.html
            ServerSocket serverSocket = null;
            try {
                //建立socket服务器,监听手机8004端口,这的端口与pc端的端口不属于同个端口,需要adb forward指令去关联转换才能通信
                serverSocket = new ServerSocket(8004);
                while (true) {
                    //接受客户端连接
                    Socket socket = serverSocket.accept();
                    //读取连接的输入流,也就是pc端发来的数据
                    DataInputStream inputStream = new DataInputStream(socket.getInputStream());
                    //拿到pc端发来的数据
                    String msg = inputStream.readUTF();
                    Log.d("AndroidServer", "收到来自pc端的数据: " + msg);
                    //拿到socket的输出流,给pc端写数据
                    DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
                    //给pc端写数据
                    outputStream.writeUTF("我是来自手机端的数据");
                    //关闭单次连接的socket
                    socket.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (serverSocket != null) {
                    try {
                        serverSocket.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

    测试步骤

    测试前提是pc端已经安装好adb驱动,正常情况下要跟手机设备通信都是需要adb驱动的

    • 1、Android端启动socket服务,监听8004端口
    new AndroidServer().start();
    
    • 2、pc端执行adb端口转发指令
    adb forward tcp:8004 tcp:8004
    
    • 3、pc端发起socket连接本地服务器的8004端口
    Socket socket = new Socket("127.0.0.1", 8004);
    
    • 4、双方进行数据传输
    //读取数据
    DataInputStream inputStream = new DataInputStream(socket.getInputStream());
    String msg = inputStream.readUTF();
    //写入数据
    DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
    outputStream.writeUTF("我是来自手机端的数据");
    

    测试结果

    • pc代码执行结果
    versionCmd: Android Debug Bridge version 1.0.41
    Version 30.0.2-6538114
    Installed as /Users/yinhaide/Library/Android/sdk/platform-tools/adb
    
    收到来自手机端发来的数据: 我是来自手机端的数据
    
    • 手机代码执行结果
    2020-06-20 14:14:41.755 6923-6973/com.example.myapplication D/AndroidServer: 收到来自pc端的数据: 我是来自pc端的数据
    

    测试结论

    方案可行,在有线连接下借助adb驱动和socket即可实现双向通信。

    展开全文
  • 基于STM32F103VC 与上位机双向通信的例子!请注意:本例是由网上例子修改并精简的,使用的是3.2的库。
  • 通过自定义HID设备实现PC与STM32之间灵活的双向通信
  • 首先展示Android设备和PC端的界面:     步骤: 首先,PC端按下“接收”按钮,使PC端进入接收状态; 此时,Android端输入框输入数据后,按下“发送”,可以将输入框上的数据发送到PC端。 接着,在PC端...

    首先展示Android设备和PC端的界面:

     

     

    步骤:

    首先,PC端按下“接收”按钮,使PC端进入接收状态;

    此时,Android端输入框输入数据后,按下“发送”,可以将输入框上的数据发送到PC端。

    接着,在PC端上方的发送框输入数据,按下发送,可以将数据发送到Android端,数据显示在LogCat日志上。

     

    有关发送的原理,我在我的上一篇博客里已经简单说明啦,所以在此不做介绍,把代码拿出来,说明几个需要注意的地方。

    上一篇链接:怎样实现UDP通信,使Android设备上的数据成功发送到PC机上?

    Android端代码如下:

    
    
    public class SendActivity extends Activity {
    
    	DatagramSocket Socket;
    	int DuanKouShou = 3013;        //用来接收数据的端口,假设端口号为3013
    	int DuanKouFa = 4013;            //用来发送的端口,假设端口号为4013
    /*
    值得注意的是:要想把数据发送和接收无误,
        Android端用于接收的端口,与PC端用于发送的端口,端口号要一致 ;
        Android端用于发送的端口,与PC端用于接收的端口,端口号要一致。 
    */
    
    	Thread TSend;  //发送线程,相当于建立一个Android端用于发送数据的平台
    	Thread threadRece;	//接收线程,同上
    	
    	
    
    	
        @Override
        //发送方是“手机”
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_send);
            
            Button Bt1 = (Button)this.findViewById(R.id.bt1);
            Button Bt2 = (Button)this.findViewById(R.id.bt2);
            final EditText et = (EditText)this.findViewById(R.id.eT1);
            //创建好界面图标,并与程序连接
            Bt1.setOnClickListener(new OnClickListener(){
    			
    			//当按下按钮时,执行以下方法
    			public void onClick(View v) {
    				// TODO Auto-generated method stub
    			 TSend = new Thread(){
    					
    					public void run(){
    						
    
    						String str = et.getText().toString();//获取输入框的信息
    
    						Log.v("fist","可以发送:"+ str);
    						SendMsg(str);   //只要一按按钮,就发送数据
    						if(Socket!=null)
    							Socket.close();
    				}
    				};
    				TSend.start();
    				Log.v("fist","线程执行完啦!");
    			}
            });          
            
    
            
            Bt2.setOnClickListener(new OnClickListener(){
    
    			//当按下“接收”按钮后,开始执行接收操作
    			
    			public void onClick(View v) {
    							
    				new Thread(){
    					public void run(){
    				
    						try {	
                //接收方法在此调用哟
    							receiveMsg();							
    						} catch (Exception e) {
    							// TODO Auto-generated catch block
    							e.printStackTrace();
    							Log.v("fist","是手机接受异常!" + e);
    							
    						}
    					}
    				}.start();
    				
    			}
        });
        }
       
    
    
        private void receiveMsg() throws Exception{
            //Android端的接收方法
    
    		Log.v("fist", "手机数据接收开始");
    		//Toast.makeText(this, "登录成功", Toast.LENGTH_LONG).show();
    		
    		try {
    
    			Socket = new DatagramSocket(DuanKouFa);
    
    			byte[]  data=new byte[1024];
    
    			DatagramPacket pack = new DatagramPacket(data, data.length);
    
    			Socket.receive(pack);			//关键问题: 在这里卡住了!收不到消息
    
    			int len = pack.getLength();
    
    			
    			byte[] tong = new byte[len];
    			for(int i = 0 ; i < len ; i++ )
    				tong[i] = data[i];	
    			
    			String str=new String(tong);
    //			
    			Log.v("fist", "接收成功,消息为: "  + str );
    //			Socket.close();
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			Log.v("fist", " 接收异常 ,异常为 :   "  + e +"\n"+e.getLocalizedMessage());
    //			Toast.makeText(this, "接收异常" + e, Toast.LENGTH_LONG).show();
    		}
        } 
            
        
        
    	    private void SendMsg(String msg){
    	    	//Android端的发送方法
    
    	    	Log.v("fist", "开始发送!");
    	    	try {
    	    		
    	    		Socket = new DatagramSocket(DuanKouFa);
    				InetAddress serverAddress = InetAddress.getByName("192.168.43.84");
    				byte data[] = msg.getBytes();//把要发送的数据转化为Byte形式
    				
    				DatagramPacket package1 = new DatagramPacket(data,data.length,
    						serverAddress,DuanKouShou);//设置一个发送包(相当于快递,写了快递的地址和编号)
    				
    				Socket.send(package1);//发送快递
    				Log.v("fist", "发送成功!");
    
    			} catch (Exception e) {
    				// TODO Auto-generated catch block
    				Log.v("fist", "发送异常"+ e);
    				e.printStackTrace();
    			}
    	    }
        
    
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.send, menu);
            return true;
        }
            
            }
        
        

     

    PC端代码:

    public class UDPServer extends JFrame{
    
    	DatagramSocket socket ;  //这个类的快递员
    	final int DuanKouFa = 4013; //这个站点的“发送”端口
    	final int DuanKouShou = 3013;  //这个站点用来接收的端口;
    	
    	
    	public void init(){
    		this.setTitle("发送接受器");
    		this.setSize(400,400);
    		this.setDefaultCloseOperation(3);
    		this.setLocationRelativeTo(null);
    		
    		FlowLayout fl = new FlowLayout();
    		this.setLayout(fl);
    		
    		final JTextField Tx = new JTextField();
    		Tx.setPreferredSize(new Dimension(300,50));
    		this.add(Tx);
    		
    		JButton bt1 = new JButton("发送");
    		this.add(bt1);
    		
    		bt1.addActionListener(new ActionListener(){
    			public void actionPerformed(ActionEvent e) {
    				String name = e.getActionCommand();
    				System.out.println("输出信息:" + name);
    				new Thread()//当下这个线程已经没问题了
    					{
    					public void run(){
    						
    						String str = Tx.getText();
    						SendMsg(str);
    						System.out.println("数据发送成功:  " + str);
    										
    					}
    					}.start();
    					if(socket!=null)
    					socket.close();
    					System.out.println("端口关闭? " + socket.isClosed());//这里也可以执行到
    			}
    		});
    		
    		final JTextField Tx2 = new JTextField();
    		Tx2.setPreferredSize(new Dimension(300,50));
    		this.add(Tx2);
    		
    		JButton bt2 = new JButton("接收");
    		this.add(bt2);
    		
    		bt2.addActionListener(new ActionListener(){
    
    			public void actionPerformed(ActionEvent arg0) {
    				String name = arg0.getActionCommand();
    				System.out.println("输出信息:" + name);
    				names = "接收";
    				new Thread()
    				{
    				public void run(){
    					try {
    						
    							receiveMsg();
    							if(socket != null)
    								socket.close();
    						
    					} catch (Exception e) {
    						// TODO Auto-generated catch block
    						e.printStackTrace();
    						System.out.println("接收异常: "  + e);
    					}
    					}				
    				}.start();
    				
    			}				
    		});
    		this.setVisible(true);
    	}
    	
    	
    	private int Ip;
    	private InetAddress Ipt;
    	private String names = "";
    	private String St = "";
    	private void SendMsg(String msg){
        	System.out.println(" ");
        	System.out.println("电脑开始发送!");
        	try {
        		
        			socket = new DatagramSocket(DuanKouFa);
    				
    				byte data[] = msg.getBytes();//把要发送的数据转化为Byte形式
    			
    				DatagramPacket package1 = new DatagramPacket(data,data.length,
    						Ipt,Ip);//设置一个发送包(相当于快递,写了快递的地址和编号)
    				System.out.println("发送端口号为: "  + Ip);
    				System.out.println("发送Ip地址为: "  + Ipt);
    				socket.send(package1);//发送快递
    			
    				System.out.println("发送成功!");
    				
    				
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			System.out.println("发送异常,异常为:  " + e);
    			e.printStackTrace();
    		}//设置端口号,
        }
    	
    	
    	private void receiveMsg() throws Exception{
    		System.out.println("数据接受开始!!!!"  );
    		
    		try {
    			socket = new DatagramSocket(DuanKouShou);
    			byte[]  data=new byte[1024];
    			DatagramPacket pack = new DatagramPacket(data, data.length);
    			socket.receive(pack);			
    			int len = pack.getLength();
    			
    			byte[] tong = new byte[len];
    			for(int i = 0 ; i < len ; i++ )
    				tong[i] = data[i];	
    			Ip = pack.getPort();
    			Ipt = pack.getAddress();
    			System.out.println("获取的端口号为:" +Ip );
    			System.out.println("获取的IP地址为:" +Ipt );
    			
    			String str=new String(tong);
    			
    			System.out.println("收到信息: "+ str);
    
    		} catch (SocketException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			System.out.println("接收异常!  "+ e);
    		} 			
    	}
    		
    	
    	public static void main(String[] args)throws Exception {
    		
    		UDPServer UDps = new UDPServer();
    		
    		UDps.init();		
    	
    		}

    几个值得注意的地方:

    1、要想成功发送和接收数据,Android端用于发送的端口与PC端用于接收的端口,端口号要一致;Android端用于接收的端口与PC端用于发送的端口,端口号要一致;

    2、满足上条后,还要满足:Android端用于发送的IP地址与PC端用于接收的IP地址一致;Android端用于接收的IP地址与PC端用于发送的IP地址一致;

    3、由于Android端发送数据所用的IP地址与端口号事先不明,因此,在PC端设置2个变量: 

        private int Ip;      
        private InetAddress Ipt; 

    先从Android端获取数据,获取数据的同时,用变量Ip获取Android端发送的端口号;用变量Ipt获取Android端发送用的IP地址。

    此时,从PC端发送数据到Android端。

     

     

    展开全文
  • 程序分二份,, 这只是PLC1的程序 , PLC2的此下载文件中,另行下载
  • 我正在尝试通过蓝牙插座在2个RPI之间创建双向通信。我需要在主机上运行主程序,同时等待连接,然后有能力在任何时候从任何设备推送消息,并中断主线程在任何时候收到。收到的消息将对另一个RPi执行操作。E、 g.打开主机...

    我正在尝试通过蓝牙插座在2个RPI之间创建双向通信。我需要在主机上运行主程序,同时等待连接,然后有能力在任何时候从任何设备推送消息,并中断主线程在任何时候收到。收到的消息将对另一个RPi执行操作。E、 g.打开主机将根据从主机发送到从设备的信息打开从设备上的LED,反之亦然。我正在处理这个小步骤,目前正在等待连接,在这一点上只使用连接发送/接收输入。

    非常感谢你为解决这一挑战而提出的任何想法。

    这是圆周率大师的密码。奴隶连接良好。我的server_程序函数是基本的发送/接收握手,当进程中没有运行连接时,它工作得很好。错误发生在“data=连接接收(1024).decode(),因为未定义'conn'。

    我一直在玩多处理器管理器和值,但它们似乎不能处理套接字的连接。

    from multiprocessing import Pool

    import socket

    #----------- Processes -----------

    def WaitSlaveConnection():

    print("Waiting for slave")

    hostMACAddress = 'XX:XX:XX:XX:XX:XX' # The MAC address of a Bluetooth adapter on the server.

    port = 3

    size = 1024

    server_socket = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)

    server_socket.bind((hostMACAddress,port))

    server_socket.listen(1)

    conn, address = server_socket.accept() # accept new connection

    print("Connection from: " + str(address))

    return "Connected"

    #############################

    ########### Main ###########

    #############################

    def server_program():

    while True:

    data = conn.recv(1024).decode()

    if not data:

    # if data is not received break

    break

    print("from connected user: " + str(data))

    data = input(' -> ')

    conn.send(data.encode()) # send data to the client

    conn.close() # close the connection

    if __name__ == '__main__':

    app_pool = Pool(processes=20)

    slave_conn = app_pool.apply_async(WaitSlaveConnection)

    while True:

    if slave_conn.get(timeout=None) == "Connected":

    print("Yes")

    server_program()

    else:

    print("Waiting for Slave")

    展开全文
  • USB双向通信上位机VC++程序

    热门讨论 2010-10-01 19:54:35
    用于Usb双向通信的VC++程序 一个靠USB设置的VID、PID、PVN来查找设备 并进行设备进行读写操作的示例
  • 本文提出了一种双向通信电路系统设计方案。具有低功耗、微型化、接口丰富、可靠性高等特点,可提供船舶定位、海上通信、遇险求救等多种功能服务,可提升安全防范能力,因而对相关行业主管部门具有重要意义。  ARM9...
  • 双向放大转发协议辅助的设备通信中断性能
  • 双向解码转发中继辅助的设备通信中断分析
  • Android WiFi直连 双向通信

    千次阅读 2018-09-02 16:32:51
    本文主要说一下,Android通过WIFi直连的方式实现图片双向传输(图片可以传输,也可以把它修改下传输聊天信息了)。 WiFi直连概述 WiFi直连也就是WiFi设备点对点连接(WiFi P2P),它允许具有适当硬件的Android ...

    原文地址https://blog.csdn.net/VNanyesheshou/article/details/82316436
    DEMO下载:http://www.demodashi.com/demo/13965.html
    本文主要说一下,Android通过WiFi直连的方式实现图片双向传输(图片可以传输,也可以把它修改下传输聊天信息了)。

    1 WiFi直连概述

    WiFi直连也就是WiFi设备点对点连接(WiFi P2P),它允许具有适当硬件的Android 4.0(API级别14)或更高版本的设备通过Wi-Fi直接相互连接,而无需中间接入点。使用这些API,您可以发现并连接到其他设备(前提是每个设备支持Wi-Fi P2P),然后通过比蓝牙连接更长的距离快速连接进行通信。这对于在用户之间共享数据的应用程序很有用,例如多人游戏或照片共享应用程序。

    Wi-Fi P2P API包含以下主要部分:
    允许您发现,请求和连接到对等的方法在WifiP2pManager类中定义。
    允许您通知WifiP2pManager方法调用成功或失败的监听器。调用WifiP2pManager方法时,每个方法都可以接收作为参数传入的特定侦听器。
    通知您Wi-Fi P2P框架检测到的特定事件的意图,例如断开的连接或新发现的对等体。
    您经常将API的这三个主要组件一起使用。例如,您可以提供WifiP2pManager.ActionListener呼叫discoverPeers(),以便您可以使用ActionListener.onSuccess()和ActionListener.onFailure() 方法通知您。


    2 Demo

    demo
    注意事项:

    2.1 搜索不到可用设备

    1. 确保对端设备处于搜索状态;
    2. 对端设备异常,可尝试重启WLAN开关,重新搜索。
    3. 自身设备异常,可尝试重启WLAN开关,重新搜索。

    2.2 连接失败

    1. 确保对端设备没有与其他设备建立WLAN直连连接。
    2. 确保对端设备接收连接请求。
    3. 对端设备异常,请尝试重新连接。

    3 创建Wi-Fi P2P应用程序

    创建Wi-Fi P2P应用程序涉及为您的应用程序创建和注册广播接收器,发现对等体,连接到对等体以及将数据传输到对等体。以下部分描述了如何执行此操作。

    3.1 初始设置

    1 添加权限

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    
    <uses-feature android:name="android.hardware.wifi.direct" android:required="true"/>

    build.gradle并设置最小版本为14或以上。 minSdkVersion 14

    2 初始化

    获取Wi-Fi P2P框架的实例并注册您的应用程序。

    //获取Wifi P2P服务对象
    mWifiP2pManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
    // 注册应用程序 这一步必须的。
    mChannel = mWifiP2pManager.initialize(this, getMainLooper(), null);

    3 注册监听

    IntentFilter intentFilter = new IntentFilter();
    //监听 Wi-Fi P2P是否开启
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
    //监听 Wi-Fi P2P扫描状态
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
    //监听 可用的P2P列表发生了改变。
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
    //监听 Wi-Fi P2P的连接状态发生了改变
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
    //监听 设备的详细配置发生了变化
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
    
    mReceiver = new WiFiDirectBroadcastReceiver(mWifiP2pManager, mChannel, this);
    //对上述的action 进行注册监听
    registerReceiver(mReceiver, intentFilter);

    3.2 发现设备

    调用discoverPeers()以检测范围内的可用对等方,此函数的调用是异步的。如果您创建了一个WifiP2pManager.ActionListener,则会将成功或失败传递给您的应用程序onSuccess(),onFailure()。该 onSuccess()方法仅通知您发现过程成功,并且未提供有关其发现的实际对等方的任何信息

    mWifiP2pManager.discoverPeers(mChannel, new ActionListener() {
        //启动成功,实际上还没有发现任何服务,因此这种方法通常可以留空。
        @Override
        public void onSuccess() {
            Toast.makeText(MainActivity.this, "Discovery Initiated",
                    Toast.LENGTH_SHORT).show();
        }
    
        //启动失败
        @Override
        public void onFailure(int reasonCode) {
            Toast.makeText(MainActivity.this, "Discovery Failed : " + reasonCode,
                    Toast.LENGTH_SHORT).show();
        }
    });

    如果发现过程成功并检测到对等体,则系统会发送广播WIFI_P2P_PEERS_CHANGED_ACTION,您可以在广播接收器中监听该意图以获得对等体列表。当您的应用程序收到WIFI_P2P_PEERS_CHANGED_ACTION意图时,您可以请求已发现的对等方的列表requestPeers()。以下代码显示了如何设置它:

    PeerListListener peerListListener;
    
    if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
    
        // request available peers from the wifi p2p manager. This is an
        // asynchronous call and the calling activity is notified with a
        // callback on PeerListListener.onPeersAvailable()
        if (mManager != null) {
            mManager.requestPeers(mChannel, peerListListener);
        }
    }

    该requestPeers()方法也是异步的,并且可以在对等列表可用时通知您的活动,该列表onPeersAvailable()在WifiP2pManager.PeerListListener接口中定义。该onPeersAvailable()方法为您提供了一个WifiP2pDeviceList,您可以迭代以查找要连接的对等方。

    3.3 连接

    在获取可用的对等项列表后,如果已找到要连接的设备,请调用该connect()方法以连接到该设备。此方法调用需要一个WifiP2pConfig 包含要连接的设备信息的对象。以下代码显示如何创建与所需设备的连接:

    WifiP2pDevice device;
    WifiP2pConfig config = new WifiP2pConfig();
    //设置地址
    config.deviceAddress = device.deviceAddress;
    mManager.connect(mChannel, config, new ActionListener() {
    
        @Override
        public void onSuccess() {
        }
    
        @Override
        public void onFailure(int reason) {
            //failure logic
        }
    });

    WifiP2pManager.ActionListener中onSuccess()并不能表示成功连接,而是应该通过广播监听

    ConnectionInfoListener infoListener
    if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
        NetworkInfo networkInfo = (NetworkInfo) intent
            .getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
        if (networkInfo.isConnected()) {
            // we are connected with the other device, request connection
            // info to find group owner IP
            manager.requestConnectionInfo(channel, infoListener);
        } else {
            // It's a disconnect
        }
    }

    连接成功后,调用requestConnectionInfo()获取group的相关信息。该操作是异步的,在如下代码涨接收信息:

    @Override
    public void onConnectionInfoAvailable(final WifiP2pInfo info) {
        if (info.groupFormed && info.isGroupOwner) {
            //server 创建ServerSocket
        } else if (info.groupFormed) {
            // The other device acts as the client. In this case, we enable the
            // get file button.
            //连接Server。
        }
    }

    3.4 Socket

    建立连接后,您可以使用套接字在设备之间传输数据。传输数据的基本步骤如下:

    创建一个ServerSocket。此套接字等待来自指定端口上的客户端的连接并阻塞直到它发生,因此在后台线程中执行此操作。
    创建一个客户端Socket。客户端使用服务器套接字的IP地址和端口连接到服务器设备。
    将数据从客户端发送到服务器。当客户端套接字成功连接到服务器套接字时,您可以使用字节流将数据从客户端发送到服务,也可以从服务端发送到客户端。
    服务器套接字等待客户端连接(使用该accept()方法)。此调用将阻塞,直到客户端连接,因此调用它是另一个线程。当连接发生时,服务器设备可以从客户端接收数据。对此数据执行任何操作,例如将其保存到文件或将其呈现给用户。

    group owner创建Server Socket,等待连接

    mServerSocket = new ServerSocket(SOCKET_PORT);
    mClientSocket = mServerSocket.accept();

    非Owner创建Socket,连接Server端。

    mClientSocket = new Socket();
    mClientSocket.connect((new InetSocketAddress(mHostAddress, SOCKET_PORT)), 0);

    3.5 互传图片

    socekt连接成功后,保留outputStream 和inputStream,并进行接收和发送的相关操作。

    //获取输入输出流
    mOutputStream = new DataOutputStream(mClientSocket.getOutputStream());
    mInputStream = new DataInputStream(mClientSocket.getInputStream());
    //不管是server还是client都接收图片。
    while (!mExit) {
        //循环接收图片
        if(!receiveFile(mInputStream))
            break;
    }

    发送图片

    long len = file.length();
    try {
        //发送图片长度
        mOutputStream.writeLong(len);
        //获取文件输入流
        FileInputStream inputStream = new FileInputStream(file);
        byte buf[] = new byte[4096];
        int count;
        //发送图片数据
        while ((count = inputStream.read(buf)) != -1) {
            mOutputStream.write(buf, 0, count);
        }
        inputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

    欢迎大家关注、评论、点赞
    你们的支持是我坚持的动力。
    欢迎关注我的微信公众号

    展开全文
  • 随着嵌入式系统技术的发展,对交互性操作要求越来越迫切,而采用USB双向通信可以很好地解决上述问题。本文介绍一种基于S1C33L11芯片利用嵌入式操作系统的同步机制通过对循环队列及自定义控制包的操作来实现双向通信...
  • AP模式相当于8266是一个热点,由独立的WiFi信号,其它设备可以连接到这个热点上来实现通信,做多支持5个设备接入; STA模式就是8266去连接公用WiFi网络,其他设备通过WiFi网络来实现和8266通信,这种模式下可以进行...
  • stm32 hid 双向通信

    千次阅读 2019-01-08 15:16:21
    STM32CubeMX可以生成下位机初始代码keil工程,然后可以进行自己的一些修改,主要是设备描述符和报告描述符。设备描述符可以不用改,报告描述符要改,然后是数据接收问题。 一、关于报告描述符...
  • 具有双向解码和转发帮助中继的设备通信的Pareto最优功率分配
  • STM32F4中USB与PC双向通信

    万次阅读 热门讨论 2016-09-07 11:03:38
    STM32F4系列处理器内部集成了USB-OTG控制器,在不要外部USB IC下就可以实现USB通信,最近两天看了下如何利用STM32的USB实现通信,记录下关键步骤: 1. 从http://www.stmcu.org/document/list/index/category-524...
  • TCP是一个全双工协议,数据通信允许数据同时在两个方向上传输,因此全双工是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。我们来做一个简单的实现 Server端 public class ...
  • 双向通信之socket.io

    2019-06-05 03:32:37
    是一个WebSocket库,包括了客户端的js和服务器端的nodejs,它的目标是构建可以在不同浏览器和移动设备上使用的实时应用. 特点 易用性:socket.io封装了服务端和客户端,使用起来非常简单方便。 跨平台:socket.io...
  • 那就是在上家公司,公司要求做一个APP进程间的通信的功能,并不是APP对APP的直接跨进程通信,而是通过一个服务中心,做接收,然后,再转发,避免应用之间耦合性高,不然的话,新增一个APP,其他APP也要进行升级更新...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,374
精华内容 549
关键字:

双向通信设备