精华内容
下载资源
问答
  • 本文以SimpleBLECentral工程为例,介绍CC2541作为主机时是如何获取从机广播包数据

    本篇博文最后修改时间:2017年01月06日,11:06。


    一、简介

    本文以SimpleBLECentral工程为例,介绍CC2541作为主机时是如何获取从机广播包数据的。

    注:本篇中的“广播包”包含“广播包数据”和“扫描应答数据”。


    二、实验平台

    协议栈版本:BLE-CC254x-1.4.0

    编译软件:IAR 8.20.2

    硬件平台:Smart RF(主芯片CC2541


    三、版权声明

    博主:甜甜的大香瓜

    声明:喝水不忘挖井人,转载请注明出处。

    原文地址:http://blog.csdn.NET/feilusia

    联系方式:897503845@qq.com

    香瓜BLE之CC2541群:127442605

    香瓜BLE之CC2640群:557278427

    香瓜BLE之Android群:541462902

    香瓜单片机之STM8/STM32群:164311667
    甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i

    四、实验前提
    1、在进行本文步骤前,请先阅读以下博文:
    暂无

    2、在进行本文步骤前,请先实现以下博文:
    暂无


    五、基础知识

    1、广播包是什么?

    答:广播包是从机端发出的数据包。


    2、广播包的格式是如何的?

    答:

    1)SimpleBLEPeripheral工程中的广播数据包格式如下:

    // GAP - Advertisement data (max size = 31 bytes, though this is
    // best kept short to conserve power while advertisting)
    static uint8 advertData[] =
    {
      // Flags; this sets the device to use limited discoverable
      // mode (advertises for 30 seconds at a time) instead of general
      // discoverable mode (advertises indefinitely)
      0x02,   // length of this data
      GAP_ADTYPE_FLAGS,
      DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
    
      // service UUID, to notify central devices what services are included
      // in this peripheral
      0x03,   // length of this data
      GAP_ADTYPE_16BIT_MORE,      // some of the UUID's, but not all
      LO_UINT16( SIMPLEPROFILE_SERV_UUID ),
      HI_UINT16( SIMPLEPROFILE_SERV_UUID ),
    
    };


    2)SimpleBLEPeripheral工程中的扫描应答数据包格式如下:

    // GAP - SCAN RSP data (max size = 31 bytes)
    static uint8 scanRspData[] =
    {
      // complete name
      0x14,   // length of this data
      GAP_ADTYPE_LOCAL_NAME_COMPLETE,
      0x53,   // 'S'
      0x69,   // 'i'
      0x6d,   // 'm'
      0x70,   // 'p'
      0x6c,   // 'l'
      0x65,   // 'e'
      0x42,   // 'B'
      0x4c,   // 'L'
      0x45,   // 'E'
      0x50,   // 'P'
      0x65,   // 'e'
      0x72,   // 'r'
      0x69,   // 'i'
      0x70,   // 'p'
      0x68,   // 'h'
      0x65,   // 'e'
      0x72,   // 'r'
      0x61,   // 'a'
      0x6c,   // 'l'
    
      // connection interval range
      0x05,   // length of this data
      GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
      LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),   // 100ms
      HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),
      LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),   // 1s
      HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),
    
      // Tx power level
      0x02,   // length of this data
      GAP_ADTYPE_POWER_LEVEL,
      0       // 0dBm
    };

    广播数据包和扫描应答数据包的数据格式,都是由多个“数据长度+数据类型+数据”组成。

    因此,我们可以通过判断数据类型,来获取这个类型的数据。

    六、实验步骤

    1、添加一个获取广播数据段的函数Get_Adtype_Data

    1)定义一个获取广播数据段的函数Get_Adtype_Data(SimpleBLECentral.c中)

    //******************************************************************************
    //name:		        Get_Adtype_Data
    
    //introduce:            获取广播数据或扫描应答数据中adType对应的数据
    
    //input parameter:      adType:数据类型
    //                      pData:广播包或扫描应答包
    //                      dataLen:广播包或扫描应答包的数据长度
    
    //output parameter:     adTypeData_index:对应的adType类型数据的偏移值
    //                      adTypeData_len:对应的adType类型数据的长度
    
    //return:	        TRUE:找到adType类型的数据
    //                      FALSE:没找到adType类型的数据
    //******************************************************************************
    static bool Get_Adtype_Data( uint8 adType, uint8 *pData, uint8 dataLen, uint8 *adTypeData_index, uint8 *adTypeData_len)
    {  
      (void)adTypeData_index;       //防止编译报错
      (void)adTypeData_len;         //防止编译报错
      
      uint8 adLen;                  //对应数据段的长度
      uint8 *pCurrent;              //当前位置的指针
      uint8 *pEnd;                  //尾指针
        
      pEnd = pData + dataLen - 1;   //指向包尾
        
      pCurrent = pData;             //当前指针指向包头
      
      while ( pCurrent < pEnd )     //判断当前指针是否还未到包尾
      {
        adLen = *pCurrent++;        //获取本段数据段的长度
        
        if ( adLen > 0 )
        {      
          if ( adType == *pCurrent )                        //如果找到了adType
          {        
            *adTypeData_index = (pCurrent + 1) - pData;     //数据段在数据包中的偏移值
            *adTypeData_len = adLen - 1;                    //数据段长度
            
            return TRUE;                                    //返回TRUE
          }
          else                                              //没找到adType则指向下一个数据段
          {
            pCurrent += adLen;
          }
        }
      } 
      
      return FALSE;         //本数据串中没有找到adType
    }

    该函数是香瓜参考simpleBLEFindSvcUuid写出来的,通过这个函数可以找出某个类型的数据段位置。


    2)声明函数Get_Adtype_Data(SimpleBLECentral.c中)

    static bool Get_Adtype_Data( uint8 adType, uint8 *pData, uint8 dataLen, uint8 *adTypeData_index, uint8 *adTypeData_len);

    2、定义一个十六进制转字符串的函数Hex_To_Str(SimpleBLECentral.c中)

    //**************************************************  
    //name:         Hex_To_Str  
    //input:        十六进制进制转字符串  
    //return:       修改后的字符串  
    //**************************************************  
    char* Hex_To_Str( uint8 *pHex )  
    {   
      char        hex[] = "0123456789ABCDEF";  
      static char str[100];  
      char        *pStr = str;  
      
      for ( uint8 i = 0; i < sizeof(pHex); i++ )  
      {  
        *pStr++ = hex[*pHex >> 4];  
        *pStr++ = hex[*pHex++ & 0x0F];  
      }  
      
      return str;  
    }  
    这里字符串大小我定了100个字节,也就是最多只能转50个十六进制。将就用吧。


    3、声明函数Hex_To_Str(SimpleBLECentral.c中)

    char *Hex_To_Str( uint8 *pHex );

    4、分别获取广播数据与扫描应答数据的举例

    1)使用举例一——获取广播数据中的数据段

    ①代码修改(SimpleBLECentral.c中)

        case GAP_DEVICE_INFO_EVENT:
          {                
            // if filtering device discovery results based on service UUID
            if ( DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE )
            {
              if ( simpleBLEFindSvcUuid( SIMPLEPROFILE_SERV_UUID,
                                         pEvent->deviceInfo.pEvtData,
                                         pEvent->deviceInfo.dataLen ) )
              {
                simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType );
    
                {
                  //读广播包或扫描应答包的某个数据段
                  uint8 adType = GAP_ADTYPE_FLAGS;  //需要扫描的类型数据
                  uint8 adTypeData_index = 0;       //数据段在数据包中的偏移值
                  uint8 adTypeData_len = 0;         //数据段的长度
                  bool status = FALSE;
                  
                  status = Get_Adtype_Data( adType, 
                                            pEvent->deviceInfo.pEvtData,
                                            pEvent->deviceInfo.dataLen,
                                            &adTypeData_index,
                                            &adTypeData_len);
                  if(status == TRUE)
                  {
                    NPI_PrintString("GAP_ADTYPE_FLAGS:");   
                    NPI_WriteTransport((uint8 *)(Hex_To_Str(pEvent->deviceInfo.pEvtData + adTypeData_index)),
                                                 adTypeData_len*2);         
                    NPI_PrintString("\r\n");            
                    NPI_PrintValue("size:", adTypeData_len, 10);            
                    NPI_PrintString("\r\n");
                  }
                } 
    /* 
                 {
                  //读广播包或扫描应答包的某个数据段
                  uint8 adType = GAP_ADTYPE_16BIT_MORE;  //需要扫描的类型数据
                  uint8 adTypeData_index = 0;       //数据段在数据包中的偏移值
                  uint8 adTypeData_len = 0;         //数据段的长度
                  bool status = FALSE;
                  
                  status = Get_Adtype_Data( adType, 
                                            pEvent->deviceInfo.pEvtData,
                                            pEvent->deviceInfo.dataLen,
                                            &adTypeData_index,
                                            &adTypeData_len);
                  if(status == TRUE)
                  {
                    NPI_PrintString("GAP_ADTYPE_16BIT_MORE:");   
                    NPI_WriteTransport((uint8 *)(Hex_To_Str(pEvent->deviceInfo.pEvtData + adTypeData_index)),
                                                 adTypeData_len*2);         
                    NPI_PrintString("\r\n");            
                    NPI_PrintValue("size:", adTypeData_len, 10);            
                    NPI_PrintString("\r\n");
                  }
                }  */         
              }
            }
            
    
    
          }
          break;

    在GAP_DEVICE_INFO_EVENT事件中会有广播数据包和扫描应答数据包进来,因此本段代码先判断了UUID来确认此数据包是“广播数据包”。

    然后再通过Get_adType_Data去获取GAP_ADTYPE_FLAGS数据段的数据。

    注:注释部分是获取GAP_ADTYPE_16BIT_MORE数据段的代码,由于串口同一时间打印太多会不好使,所以我分开来编译GAP_ADTYPE_FLAGS数据段和GAP_ADTYPE_16BIT_MORE数据段的代码。


    ②实验结果

    其中,GAP_ADTYPE_FLAGS数据段获取结果


    其中,GAP_ADTYPE_16BIT_MORE数据段获取结果



    2)使用举例二——获取扫描应答数据包的设备名称段

    ①代码修改(SimpleBLECentral.c中)

        case GAP_DEVICE_INFO_EVENT:
          { 
                {
                  //读广播包或扫描应答包的某个数据段
                  uint8 adType = GAP_ADTYPE_LOCAL_NAME_COMPLETE;  //需要扫描的类型数据
                  uint8 adTypeData_index = 0;       //数据段在数据包中的偏移值
                  uint8 adTypeData_len = 0;         //数据段的长度
                  bool status = FALSE;
                  
                  status = Get_Adtype_Data( adType, 
                                            pEvent->deviceInfo.pEvtData,
                                            pEvent->deviceInfo.dataLen,
                                            &adTypeData_index,
                                            &adTypeData_len);
                  if(status == TRUE)
                  {
                    //NPI_PrintValue("GAP_ADTYPE_FLAGS:", *p_adTypedata, 10);
                    NPI_PrintString("GAP_ADTYPE_LOCAL_NAME_COMPLETE:");   
                    NPI_WriteTransport((uint8 *)(Hex_To_Str(pEvent->deviceInfo.pEvtData + adTypeData_index)),
                                                 adTypeData_len*2);         
                    NPI_PrintString("\r\n");            
                    NPI_PrintValue("size:", adTypeData_len, 10);            
                    NPI_PrintString("\r\n");
                  }
                }  

    ②实验结果


    串口输出结果不太好用,只输出了设备名的前两个字节“0x53(S)”和“0x69(i)”。

    (群友指出上面只显示2个字节的原因是:16进制转字符串的函数中,“sizeof(pHex)”只是取指针大小,因为指针是2字节大小,所以只输出了2个字节)。


    所以在仿真中直接查看设备名是否有被获取到:


    对照下面这个设备名,可见设备名已经存在于pEvent->deviceInfo.pEvtData中了,并且首地址是“pEvent->deviceInfo.pEvtData + adTypeData_index”,长度是adTypeData_len的0x13个(19个)。

      0x53,   // 'S'
      0x69,   // 'i'
      0x6d,   // 'm'
      0x70,   // 'p'
      0x6c,   // 'l'
      0x65,   // 'e'
      0x42,   // 'B'
      0x4c,   // 'L'
      0x45,   // 'E'
      0x50,   // 'P'
      0x65,   // 'e'
      0x72,   // 'r'
      0x69,   // 'i'
      0x70,   // 'p'
      0x68,   // 'h'
      0x65,   // 'e'
      0x72,   // 'r'
      0x61,   // 'a'
      0x6c,   // 'l'


    因此,实验成功。


    展开全文
  • java实现远程连接,在控制台输入命令,发送命令到远程主机执行,并获取响应数据测试代码 public static void main(String [] args) throws IOException { connect("192.168.8.102", 80); //即可在控制台输入命令,...
    
        ad1.jpg
    

    全栈工程师开发手册 (作者:栾鹏)
    java教程全解

    java实现socket连接,向指定主机指定端口发送socket数据,并获取响应数据

    测试代码

    	public static void main(String [] args) throws IOException {
    		connect("192.168.8.102", 80);
    		//即可在控制台输入命令,回车后会发送命令到远程主机,并在控制台打印响应数据
    	}
    

    远程连接函数

    //远程连接
    	public static void connect(String host,int port){
    		try {
    			Socket sock = new Socket(host, port);
    			// 创建一个写线程
    			new TelnetWriter(sock.getOutputStream()).start();
    			// 创建一个读线程
    			new TelnetReader(sock.getInputStream()).start();
    		} catch (Exception e) {
    			// TODO: handle exception
    		}
    	}
    

    从控制台读取用户输入命令 线程类的实现

    class TelnetWriter extends Thread {
    	private PrintStream out;
    
    	public TelnetWriter(OutputStream out) {
    		this.out = new PrintStream(out);
    	}
    	public void run() {
    		try {
    			// 包装控制台输入流
    			BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    			// 反复将控制台输入写到Telnet服务程序
    			while (true)  
    				out.println(in.readLine());
    		} catch (IOException exc) {
    			exc.printStackTrace();
    		}
    	}
    }
    

    将响应数据打印到控制台 线程类的实现

    class TelnetReader extends Thread {
    	private InputStreamReader in;
    
    	public TelnetReader(InputStream in) {
    		this.in = new InputStreamReader(in);
    	}
    	public void run() {
    		try {
    			// 反复将Telnet服务程序的反馈信息显示在控制台屏幕上
    			while (true) {
    				// 从Telnet服务程序读取数据
    				int b = in.read();
    				if (b == -1)  
    					System.exit(0);
    				// 将数据显示在控制台屏幕上
    				System.out.print((char) b);
    			}
    		} catch (IOException exc) {
    			exc.printStackTrace();
    		}
    	}
    }
    
    
    展开全文
  • 目录 ...Qt中有2个方式可以实现HTTP协议的发送,一个是使用QNetworkAccessManager,这个是非常常见的,另外是使用QTcpSocket自己构造HTTP格式,也是可以的。   演示 web程序运行如下: 输入...

    目录

     

    背景

    演示

    搭建Java Web环境

    QTcpSocket获取服务器数据

    QNetworkAccessManager获取服务器数据


     

    背景

    Qt中有2个方式可以实现HTTP协议的发送,一个是使用QNetworkAccessManager,这个是非常常见的,另外是使用QTcpSocket自己构造HTTP格式,也是可以的。

     

    演示

    web程序运行如下:

    输入10086后:

     

    使用telnet获取web网站数据:

    发送命令以及接收如下:

     

    使用QNetworkAccessManager获取服务器数据:

    使用QTcpSocket获取数据:

     

    搭建Java Web环境

    java源码结构如下:

     

    源码如下:

    DataSource.java

    package my;
     
    import java.util.ArrayList;
     
    public class DataSource {
     
    	
    	ArrayList<Record> m_records = new ArrayList<Record>();
    	
    	public DataSource(){
    		
    		m_records.add(new Record("XiaoMing", "10086"));
    		m_records.add(new Record("XiaoHong", "10087"));
    		m_records.add(new Record("XiaoGang", "10088"));
    	}
    	
    	public Record query(String qq){
    		
    		for(Record e : m_records){
    			
    			if(e.qq.equals(qq)){
    				
    				return e;
    			}
    		}
    		
    		return null;
    	}
     
    	public class Record {
    		
    		public String name = "";
    		public String qq = "0000";
    		
    		public Record(String name, String qq){
    			
    			this.name = name;
    			this.qq = qq;
    		}
    	}
    }

    index.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
     
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'index.jsp' starting page</title>
    	<meta http-equiv="pragma" content="no-cache">
    	<meta http-equiv="cache-control" content="no-cache">
    	<meta http-equiv="expires" content="0">    
    	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    	<meta http-equiv="description" content="This is my page">
    	<!--
    	<link rel="stylesheet" type="text/css" href="styles.css">
    	-->
      </head>
      
      <body>
      
        <form method="get" action="query.jsp" >
        	
        	输入QQ号
        	 
        	<input type="text"  name="qq" /> 
        	
        	<input type="submit" value="提交" />
        
        </form>
        
        
      </body>
    </html>

    query.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
     
     
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
     
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'query.jsp' starting page</title>
        
    	<meta http-equiv="pragma" content="no-cache">
    	<meta http-equiv="cache-control" content="no-cache">
    	<meta http-equiv="expires" content="0">    
    	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    	<meta http-equiv="description" content="This is my page">
    	<!--
    	<link rel="stylesheet" type="text/css" href="styles.css">
    	-->
     
      </head>
      
      <body>
     
        
        <%@ page import="my.*" %>
        
        <%
     
        	String qq = request.getParameter("qq");
        	
     
        	DataSource db = new DataSource();
        	DataSource.Record result = db.query(qq);
        	
        	
        	if(result == null)
        	{
        		out.print("<p> 不存在此记录 </p> ");
        	}    	
        	else
        	{
        		out.print("<p> 姓名: " + result.name + ", QQ: " + result.qq + "</p>");
        	}
         %>
         
      </body>
    </html>
    

     

    QTcpSocket获取服务器数据

    程序结构如下:

    widget.ui如下:

    源码:

    widget.h

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    
    QT_BEGIN_NAMESPACE
    class QTcpSocket;
    QT_END_NAMESPACE
    
    namespace Ui {
    class Widget;
    }
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = 0);
        ~Widget();
    
    protected slots:
        void btnClicked();
        void onConnect();
        void onReadyRead();
    
    private:
        Ui::Widget *ui;
        QTcpSocket *m_socket;
    };
    
    #endif // WIDGET_H

    main.cpp

    #include "widget.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.show();
    
        return a.exec();
    }
    

    widget.cpp

    #include "widget.h"
    #include "ui_widget.h"
    #include <QMessageBox>
    #include <QTcpSocket>
    #include <QDebug>
    
    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
    
        this->setWindowTitle("QTcpSocket");
        m_socket = new QTcpSocket(this);
        connect(m_socket, SIGNAL(connected()), this, SLOT(onConnect()));
        connect(m_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
        connect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(btnClicked()));
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    void Widget::btnClicked()
    {
        m_socket->connectToHost("47.101.40.99", 8080);
    }
    
    void Widget::onConnect()
    {
        m_socket->write("GET /GetPostDemo/query.jsp?qq=10086\r\n"
                        "Host: 47.101.40.99\r\n\r\n");
    }
    
    void Widget::onReadyRead()
    {
        qDebug() << QString::fromUtf8(m_socket->readAll());
    }
    

     

    QNetworkAccessManager获取服务器数据

    程序结构如下:

    widget.ui是这样的:

    源码如下:

    widget.h

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    
    QT_BEGIN_NAMESPACE
    class QNetworkAccessManager;
    class QNetworkReply;
    QT_END_NAMESPACE
    
    namespace Ui {
    class Widget;
    }
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit Widget(QWidget *parent = 0);
        ~Widget();
    
    protected slots:
        void btnClicked();
        void replyFinished(QNetworkReply *reply);
    
    private:
        Ui::Widget *ui;
        QNetworkAccessManager *m_manager;
    };
    
    #endif // WIDGET_H
    

    main.cpp

    #include "widget.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.show();
    
        return a.exec();
    }

    widget.cpp

    #include "widget.h"
    #include "ui_widget.h"
    #include <QNetworkAccessManager>
    #include <QNetworkReply>
    #include <QUrl>
    
    Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
        this->setWindowTitle("QNetworkAccessManager");
        m_manager = new QNetworkAccessManager(this);
        connect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(btnClicked()));
        connect(m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    void Widget::btnClicked()
    {
        m_manager->get(QNetworkRequest(QUrl("http://47.101.40.99:8080/GetPostDemo/query.jsp?qq=10086")));
    }
    
    void Widget::replyFinished(QNetworkReply *reply)
    {
        qDebug() << QString::fromUtf8(reply->readAll());
    }
    

     

     

     

    展开全文
  • 主机A首先查找其ARP高速缓存内的映射表中是否有主机B的IP地址,如果有,则查找出其对应的硬件地址,并将该硬件地址写入MAC帧,通过局域网将该MAC帧发送主机B。如果ARP高速缓存内没有主机B的IP地址,则运行ARP,按...

    主机A首先查找其ARP高速缓存内的映射表中是否有主机B的IP地址,如果有,则查找出其对应的硬件地址,并将该硬件地址写入MAC帧,通过局域网将该MAC帧发送给主机B。如果ARP高速缓存内没有主机B的IP地址,则运行ARP,按以下步骤寻找主机B的硬件地址

    1,主机A首先在本局域网中广播发送一个ARP请求分组,其内容可以形象描述为:“我的IP地址是A,硬件地址是a,我想知道IP地址为B的主机硬件地址”。本局域网中的所有运行ARP的主机都会收到该ARP请求分组。

    2,主机B收到该ARP请求分组后。发现其中询问的IP地址与自己的IP地址一致,则收下该分组,并且将主机A的硬件地址和IP地址信息写入自己的ARP高速缓存中,以方便以后向主机A发送IP数据报,其他主机发现与ARP请求分组中询问的IP地址与自己收下的IP地址不一致,则丢弃该分组。主机B收下ARP分组请求分组后,创建一个ARP响应分组,并将自己的硬件地址写入该响应分组。然后将这个分组直接发送给主机A

    3,主机A收到主机B的ARP响应分组后,将其中所携带的主机B的硬件地址写入ARP高速缓存中的地址映射表

    展开全文
  • 主机一直在重复发送数据,我要实时读取,并从数据中截取控制信号源的命令,我直接用socket读取吗?read()读取的是实时的吗,我如何把这些数据存下来解析?有点乱。。。求各位大神指点,谢谢
  • 网络主机发送IP数据包过程

    千次阅读 2020-05-24 11:27:44
    当一个拥有公网IP的主机给其它主机发送IP数据包时,首先在IP首部封装自身IP地址(源IP)和目的主机的IP地址(目的IP),实现网络层数据的封装。接下来进行数据链路层封装,数据链路层数据帧的源MAC地址是本机MAC地址...
  • 如下获取百度网页GET、POST时Host: 119.75.217.109后面回车空一行;...这样格式发送数据才会有效。 POST http://119.75.217.109/ HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 18 H...
  • 项目中有使用到,Java利用socket连接到一台主机并向主机发送文件。也就是说有两台服务器a和b,要让a去主动连接b并且给b发送一个文件。 用到了socket和java io的知识。记录一下。 分为服务器端和客户端。这里服务器...
  • VC++实现获取本地主机网卡信息

    千次阅读 2012-09-04 18:10:03
    我们在进行网络编程的时候,经常需要获取本地主机,网卡的信息,我们代码实现如下。#include "../common/initsock.h" #include #include #include #include "protoutils.h" #include "ProtoPacket.h" #pragma...
  • UDP的接收端使用函数 recvfrom接收数据,这个函数在winsock.h中定义如下: [cpp] view plaincopyprint? int recvfrom( __in SOCKET s, __out char* buf, __in int len, __in int flags, __out ...
  • 创建HTTP服务器 在Node.js中,可以很方便地创建一个HTTP服务器,只需调用http模块中的create Server方法即可 var server=http.createServer([requestListener]) 在createServer方法中,可以使用一个可选参数,参数...
  • C#获取当前主机硬件信息

    万次阅读 2015-04-01 20:03:16
    获取计算机的相关硬件信息,CPU序列号、MAC地址、内外网ip、主机序列号等。
  • 不过在发送了从设备获取数据的命令后。我发现设备是完成了数据发送的(进入了XFRC中断,说明数据已经发送完成)。但是从主机这边却没有受到数据。 其中端点1的FIFO设为了0xFF0。 以下是我主机这边获取数据的代码...
  • IP数据报的发送和转发过程

    千次阅读 2020-08-03 17:33:40
    过程:主机发送IP数据报 + 路由器转发IP数据报 前提假设:为将重点放在TCP/IP协议栈的网际层发送和转发IP数据报的过程上,在之后的举例中,我们忽略使用ARP协议来获取目的主机或路由器接口的MAC地址的过程以及...
  • docker容器内抓取宿主机物理网卡包

    千次阅读 2019-10-28 19:57:01
    docker容器内抓取宿主机物理网卡 需求描述: 在docker容器内,实现对宿主机物理网卡的抓 OS: Ubuntu server 18.04 x64 1. 宿主机安装docker功能 # 下载docker chenzd@ubuntu:~# wget -qO- ...
  • Wireshark数据分析之HTTP协议

    千次阅读 2019-07-06 11:46:53
    先在服务器上配置HFS,获取HTTP的GET数据和POST数据 右键以管理员身份运行hfs,打开界面如下: 配置端口8080 在虚拟文件系统区域,右键,选择“从磁盘添加目录”,选择一个真实存在的目...
  • STM32 MPU6050数据获取数据处理

    千次阅读 多人点赞 2020-08-20 22:56:33
    2.4 STM32 MPU6050数据获取(IIC + DMP) 本篇文章主要针对廉价的MPU6050模块。我们这里完成了MPU6050的数据获取、零偏自动设置、温漂抑制。这里提供源码工程文件,供大家下载,在公众号:小白学移动机器人,发送:...
  • 每天早上七点三十,准时推送干货Hello,大家好,五一小长假结束,今天开始上班!不过想想,再过三天就又周末,想想还是有点小激动,嘿嘿!前几天的文章,阿粉教了大家如何爬取豆瓣短评数据。爬取...
  • Python3 urllib(网络数据获取 模块)

    万次阅读 2017-04-10 02:22:00
    Python3 urllib(网络数据获取 模块) 本文由 Luzhuo 编写,转发请保留该信息. 原文: http://blog.csdn.net/Rozol/article/details/69941511 以下代码以Python3.6.1为例 Less is more! #coding=utf-8 ...
  • 蓝牙主机和从机之间传输数据说明

    万次阅读 2017-07-29 09:40:46
    转自:...在BLE协议栈中进行数据发送分为两个方面,一个事GATT的client主动向service发送数据,另一个是GATT的service主动向client发送数据 我们暂且简单的分为主机向从机发送
  • struct hostent *gethostbyname(const char ... 这个函数的传入值是域名或者主机名,例如"www.google.cn"等等。传出值,是一个hostent的结构。如果函数调用失败,将返回NULL。 struct hostent { char *h_name; cha
  • 我们知道,内网的主机将向外网发送数据可以通过NAT获取一个合法的ip,进而向外部发送数据。 我疑惑的是,当外部向该主机返回数据时,因为目的IP是NAT分配的,必然数据会发送给NAT,那么NAT如何确定该数据包应该返回...
  • 主机向HID设备读数据的过程

    千次阅读 2016-10-12 15:06:00
    中 断 或 轮询 USB_INTSTS 的 方 式 来 监 测 USB 传输 ,在 USB 传输 发 生 时 ,USB_INTSTS由硬件设置,并向CPU发送中断请求(如果相关中断使能),在没有使能中断时,用户可以轮询USB_INTSTS来获取事件,...
  • APK网络数据工具(Fiddler)简析

    千次阅读 2017-01-13 12:37:40
    Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,设置断点,查看所有的“进出”Fiddler的数据。 Fiddler 要比其他的网络调试器要更加简单,因为它不仅仅暴露http通讯还...
  • API-网络编程(网络概述,Socket通信机制,UDP协议发送和接收数据,TCP协议发送和接收数据)
  • WinPcap实战(一)——发送ARP

    千次阅读 2015-09-17 17:00:09
    ARP格式:物理帧头(14B)——ARP帧结构(28B)——填充数据(18B)——CRC(4B)。这里给出一张图(图中没有18字节的填充数据和4字节的校验位): 物理帧头(14B):目的MAC (6B) ——源MAC(6B) ——类型(2B, ARP...
  • udp中recvfrom获取发送方的地址IP\port

    千次阅读 2019-01-18 08:37:25
    sin_port和sin_addr都必须是网络字节序(NBO),一般可视化的数字都是主机字节序(HBO)。 三、总结 二者长度一样,都是16个字节,即占用的内存大小是一致的,因此可以互相转化。二者是并列结构,指向sockaddr...
  • SI4438可变长包数据收发

    千次阅读 2018-05-27 00:04:43
    最近在项目止采用SI4438作为无线通信。...由于数据发送较为频繁,即使主机发送7字节数据,从机也会进入5次RX_FIFO_FULL中断,已经影响到了从机其它任务的正常运行。经分析,此问题存在的根源是,从机每次均...
  • 蓝牙协议栈主从机之间发送数据

    千次阅读 2017-07-29 17:52:27
    然后是从机给主机发送数据。 1.Initialize GATT attributes (初始化GATT属性表) SimpleProfile_AddService( GATT_ALL_SERVICES ); // Simple GATT Profile ----> 2.注册属性列表 and 回调函数 simpleProfileCBs

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 232,115
精华内容 92,846
关键字:

获取主机发送的http包的数据