精华内容
下载资源
问答
  • 针对64位系统 1.将usbcan_e.dll拷贝到 C:\Windows\SysWOW64 目录下。...目录地址:研发资料\win10更新10.0.17134版本后无法发送usbcan_e_u消息解决办法 SVN地址 :https://szsvn.cntotal.com:61010/svn/.

    在这里插入图片描述
    针对64位系统
    1.将usbcan_e.dll拷贝到 C:\Windows\SysWOW64 目录下。
    2.将usbcan_e_64.dll拷贝到 C:\Windows\System32 目录下。

    针对32位系统
    1.将usbcan_e.dll拷贝到 C:\Windows\System32 目录下。

    文件在研发资料下面
    目录地址:研发资料\win10更新10.0.17134版本后无法发送usbcan_e_u消息解决办法
    SVN地址 :https://szsvn.cntotal.com:61010/svn/System_Project/System_Tools/前装项目/大长江电摩项目/研发资料

    展开全文
  • linux网络报文接收流程 netif_rx-->netif_rx_schedule-->...process_backlog-->netif_receive_skb--&...上层发送协议栈组装需发送报文 有队列设备: fun_xmit-->dev_queue_xmit-->qdisc_run-->qdsi

    linux网络报文接收流程

    netif_rx-->netif_rx_schedule-->net_rx_action-->process_backlog-->netif_receive_skb-->上层协议栈处理(ptype_base的HASH表中已注册.type与.func协议处理函数)

    linux网络报文发送流程

    上层发送协议栈组装需发送的报文

    有队列设备:

    fun_xmit-->dev_queue_xmit-->qdisc_run-->qdsic_restart-->net_tx_action-->dev->hard_start_xmit-->发送完成

    无队列设备

    fun_xmit-->dev_queue_xmit-->dev->hard_start_xmit-->发送完成

    添加处理协议

    1 编写接收发送处理函数

    2 注册ptype_base

    对于linux内核来说,网络报文由网络设备来进行接收。设备驱动程序从网络设备中读取报文,通过内核提供的网络接口函数,将报文传递到内核中的网络协议栈。报文经过协议栈的处理,或转发、或丢弃、或被传送给某个进程。
    网络报文的发送与之相反,进程通过系统调用将数据送入网络协议栈,或者由网络协议栈自己发起报文的发送,然后协议栈通过调用网络接口函数来调度驱动程序,使其将报文传送给网络设备,从而发送出去。
    本文讨论的是网络接口层,它是网络设备驱动程序与网络协议栈交互的纽带。见下图中红色部分的netif。

    报文的接收
    网络报文的接收源自网络设备。网络设备在接收到一个报文之后,通过中断告知CPU。网卡驱动程序需要注册对该中断事件的处理函数(参见《linux中断处理浅析》),以处理接收到的报文。
    在中断处理函数中,网络驱动程序有两种方法对报文进行处理(老式的方法,和新式的方法),我们先介绍老式的处理方式。在这种方式下,中断处理函数主要完成以下工作:
    分配一个skb结构(该结构用于保存一个报文)。操作设备,将设备收到的数据拷贝到这个skb结构对应的缓冲区中。设置skb的协议类型skb->protocol,该类型表明了网络协议栈的上层协议(下面我们将会看到)。然后调用内核提供的网络接口函数netif_rx;

    netif_rx(skb);
    netif_rx函数对skb的如时间戳这样的附加信息进行初始化以后,将这个skb结构放入当前CPU的softdate_net结构的input_pkt_queue队列中。netif_rx会根据队列的长度,对设备的拥塞状况进行判断(队列过长则代表报文接收过快,以致于上层来不及处理)。如果设备已陷入拥塞,则收到的报文可能直接被丢弃。
    如果一切正常,netif_rx会调用网络接口函数netif_rx_schedule,以触发对接收报文的进一步处理;

    netif_rx_schedule(dev);
    netif_rx使用softdate_net结构中内嵌的backlog_dev作为dev来调用netif_rx_schedule,后者将其加入到softdate_net结构的poll_list队列中(如果这个dev不在队列中的话),以使其等待被调度。

    相比老式的处理方式,新式的处理方式(称为NAPI)在中断处理函数中仅仅是以对应设备的dev结构为参数调用netif_rx_schedule函数即可。
    最后netif_rx_schedule函数会触发NET_RX_SOFTIRQ软中断,于是接下来对应的软中断处理函数net_rx_action将被调用;

    net_rx_action();
    对于当前CPU对应的softdate_net结构的poll_list队列中的所有dev,调用dev->poll方法。该方法是由对应dev的驱动程序实现的,用于接收及处理报文(前面提到的backlog_dev除外)。
    net_rx_action每次运行都有一定的限度,并不一定要将所有报文都处理完。在处理完一定数量的报文配额、或处理过程超过一定时间后,net_rx_action便会返回。返回前触发一次NET_RX_SOFTIRQ软中断,等待下一次中断到来的时候继续被调度。

    以上过程如图所示(摘自ULNI):

    上面提到的softdate_net结构是用于进行报文收发调度的结构,内核为每个CPU维护一个这样的结构。在报文接收过程中用到了其中的三个成员:
    1、poll_list,网络设备dev的队列。其中的设备接收到了报文,需要被处理;
    2、input_pkt_queue,skb报文结构的队列,保存了已接收并需要被处理的报文;
    3、backlog_dev,一个虚拟的网络设备dev结构;
    后两个成员是专门为支持老式的处理方式而设置的,在这种方式下,接收到的skb被放入input_pkt_queue队列,然后backlog_dev被加入poll_list。而最后,自然backlog_dev->poll函数将对input_pkt_queue队列中的skb进行处理。backlog_dev->poll等于process_backlog函数;

    process_backlog(backlog_dev, budget);
    既然net_rx_action每次运行都有一个配额,它在调用dev->poll时也会传递当前剩余的配额值,即budget。
    process_backlog会遍历input_pkt_queue队列中的skb,调用netif_receive_skb函数对其进行处理。
    process_backlog函数有两种结局,一个是配额到或时间到,直接返回;另一个是处理完input_pkt_queue队列中的所有skb,此时需要将backlog_dev从poll_list中删除。

    新式的NAPI处理方式所要做的事跟老的处理方式其实是很类似的。在其对应的dev->poll函数中,需要分配skb结构、从设备读取报文、调用netif_receive_skb让网络协议栈的上层来处理报文。
    这种方式最大的好处是:在dev->poll函数中,不一定只处理一个报文。具体怎么处理可以由驱动程序灵活控制。比如说,假设现在网络负载非常大,如果网络设备每接收一个报文都通过一次中断来告知内核,这样做效率并不理想。而此时dev->poll可以做一些轮询的工作,如果网络设备已经接收了多个报文,可以一次性都处理了。并且,就算设备此刻所接收到的报文都已经处理完了,驱动程序也可以根据某种方式预判设备在很短的一段时间内还将收到报文,于是依然将自己对应的dev结构留在poll_list中,等待下一次继续被调度。
    当dev仍结构留在poll_list中时,设备驱动程序可以关闭设备接收到报文时的中断通知,因为目前处于轮询状态。而当驱动程序认为在将来的一段时间以内无报文可收时,则可以将其dev从poll_list中移除,然后开启设备接收到报文时的中断通知。等待下一次报文接收的中断到来时,这个dev再重新被放入poll_list。

    netif_receive_skb(skb);
    该函数会将skb提交给抓包程序进行处理、还会触发数据链路层的桥接功能(见《linux网桥浅析》)、然后将报文提交给网络协议栈的上层(网络层)进行处理。
    网络层的协议有IP、ARP等等很多种,在这里怎么知道这个skb该提交给哪种协议呢?在报文的数据链路层报头中保存着三个重要信息,发送者和接收者的Mac地址、和上层协议标识。回想一下之前的流程,在skb接收完成之后我们就已经设置了skb->protocol(从报头中得到),上层协议就由它来指定。比如,0x0800代表IP协议、0x0806代表ARP协议,这是由协议规定的。
    netif_receive_skb并不是用一个switch-case来匹配skb->protocol,以选择网络层处理函数的。系统中有一个名为ptype_base的hash表,各种网络层的协议在其初始化时都会在这个hash表中注册一个类型为packet_type的表项(以协议类型为key),如下图所示(摘自ULNI):


    netif_receive_skb要做的就是在这个hash表中遍历所有type与skb->protocol匹配的packet_type结构(packet_type结构的dev可用于限定skb->dev,NULL表示不限),然后调用其func回调函数。(可见,一个报文有可能被多种协议所处理。)
    至此报文被提交到了网络层,在这里就不继续深入了。

    报文的发送
    报文的发送是由网络协议栈的上层发起的。网络协议栈上层构造一个需要发送的skb结构后(该skb已经包含了数据链路层的报头),调用dev_queue_xmit函数进行发送;

    dev_queue_xmit(skb);
    该函数先会处理一些缓冲区重组、计算校验和之类的杂事,然后开始处理报文的发送。
    发送报文有两种策略,有队列或无队列。这是由网络设备驱动程序在定义其对应的dev结构时指定的,一般的设备都会使用队列。
    dev->qdisc指向一个队列的实例,里面包含了队列本身以及操作队列的方法(enqueue、dequeue、requeue)。这些方法的集合组成了一种队列规则(skb将以某种规则入队、以某种规则出队,并不一定是简单的先进先出),这样的规则可用于流量控制。
    网络设备驱动程序可以选择自己的设备使用什么样的队列,或是不使用队列。
    对于有队列的设备,dev_queue_xmit调用dev->qdisc->enqueue方法将skb加入队列,然后调用qdisc_run函数。而qdisc_run会调用qdisc_restart来对队列进行处理。

    qdisc_restart(dev);
    该函数主要的工作就是不断调用dev->qdisc->dequeue方法从队列中取出待发送的报文,然后调用dev->hard_start_xmit方法进行发送。该方法是由设备驱动程序实现的,会直接和网络设备去打交道,将报文发送出去。
    如果报文发送失败,qdisc_restart会调用dev->qdisc->requeue方法将skb重新放回队列。同时,还将调用netif_schedule函数将dev加入softdate_net的output_queue队列中(其中的设备都是有报文等待发送的,将在稍后被处理)。然后触发一次NET_TX_SOFTIRQ软中断。于是在下一个中断到来时,对应的软中断处理函数net_tx_action将被调用。
    而如果dev->hard_start_xmit方法发送报文成功,则表示报文已经送到了网络设备的发送缓冲区,设备会自动将报文发送出去。并且在报文发送完成时,设备会通过中断通知驱动程序。对应的中断处理函数也会触发NET_TX_SOFTIRQ软中断。此外,已发送完成的skb将被加入softdate_net的completion_queue队列中,等待被释放。

    软中断NET_TX_SOFTIRQ被触发,将使得net_tx_action函数被调用。该函数主要做了两件事:
    1、从softdate_net的completion_queue队列中取出每一个skb,将其释放;
    2、对于softdate_net的output_queue队列中的dev,调用qdisc_run继续尝试发送其qdisc队列中的报文;

    对于有队列的设备,其队列主要用于流量控制以及发送失败时的缓冲;对于没有队列的设备(比如lo,环回设备),dev_queue_xmit函数则会直接调用dev->hard_start_xmit进行发送,如果失败报文就会被丢弃。

    以上过程如图所示:

    qdisc_restart函数在执行过程中还会关心dev是否被暂停(就如接收报文时要关心网络是否拥塞一样),如果被暂停则结束处理流程并返回。
    而dev的暂停与否是由设备驱动程序来设置的,在dev->hard_start_xmit函数中,驱动程序如果发现设备当前的发送缓冲区太小(比如小到无法再容纳一个报文。这表示报文发送过快,以致于设备来不及处理),则会让设备暂停。而当网络设备在完成报文的发送后会产生中断,对应的中断处理程序又可以根据设备当前的发送缓冲区大小,决定是否让设备从暂停中恢复。

    而如果网络设备出现问题,无法发送报文了,则可能设备上的发送缓冲区一直处于被占满的状态,导致设备一直被暂停。另一方面,报文发不出去,也就不会有通知发送完成的中断产生,设备也就不会从暂停状态恢复,于是网络就瘫痪了。
    为了检测这种情况,驱动程序可以为设备设置一个看门狗定时器。如果发现设备正在暂停状态,并且距离最后一次发送报文已经过去一定的时间,而发送完成的中断还没有收到,则认为该设备出现问题。此时看门狗定时器将触发驱动程序提供的相关函数,将设备复位,以试图让其恢复正常工作。

    展开全文
  • 好的做法是,接收端收到发送文件的请求收,接受文件,不考虑标识,就没有标识位,发送发送完文件后调用close(),以发送结束标识,接收端会通过read()收到-1。接收端关闭接受流。则,文件传输过程结束。 ...

    1.写了一个socket传输文件的程序,发现传输过去文件有问题。找了一下午终于似乎找到了原因,记录下来警示一下:

    接受文件的一端,向本地写文件之前使用Thread.sleep(time)休息一下就解决了问题。

    个人认为可能是传输过程中,接收端向磁盘写速度有点慢,被后面的覆盖导致错误。

    //--------------------------------------------------------------------------------------------------------------------

    12-29:最近看了本书<>,似乎了解了如题这个问题的原因:

    不能假设在连接的一端将数据写入输出流和在另一端从输入流读入的数据间有任何的一致性。虽然发送端都是1024bytes为单位发送的,但是由于网速问题接收端不一定是按照1024bytes为单位接受的,可能小于1024。所以buf[0]=5这种手段是行不通的,接受方收到的buff的第一个字符可不一定是5。

    注:若以1024bytes为发送和接受缓冲区的话。

    //---------------------------------------------------------------------------------------------------------------------

    12-29晚:我彻底知道了原因。就是网络传输的问题,发送端以1024byte为单位发送,接收端以1024byte为单位接受。但是由于网络传输速度的限制,发送端发送出去的1024byte不能同时到达接收端,而接收端使用read独到的可能少于1024byte。下次从上次读到的下一个位置继续读,所以以1024byte数组的开头设为标识位的做法是行不通的,是错误的。解决办法是在接收端每次read之前,Thread.sleep(mileseconds);一会。这样就有足够的时间等待发送端发送的数据完全到达接受端后再接受,这样的话buff[0]的值就可以最为标示位了。

    但是还是不提倡这种设置buff[0]为表示位的做法。好的做法是,接收端收到发送文件的请求收,接受文件,不考虑标识,就没有标识位,发送端发送完文件后调用close(),以发送结束标识,接收端会通过read()收到-1。接收端关闭接受流。则,文件传输过程结束。

    http://www.cnblogs.com/wangjiyuan/p/3493186.html

    展开全文
  • Javadoc为 org.springframework.jms.listener.AbstractMessageListenerContainer 表示,如果...如果抛出异常,则无法重新发送 .我猜,“在抛出异常的情况下没有重新传递”意味着,即使jms监听器中抛出异常,该消息...

    Javadoc为 org.springframework.jms.listener.AbstractMessageListenerContainer 表示,如果

    “sessionAcknowledgeMode”设置为“CLIENT_ACKNOWLEDGE”:成功侦听器执行后自动确认消息;如果抛出异常,则无法重新发送 .

    我猜,“在抛出异常的情况下没有重新传递”意味着,即使jms监听器中抛出异常,该消息也不会被重新传递(因此,我的猜测,它会得到确认) . 但是,从侦听器抛出的异常意味着对它的调用不成功,并且由于没有确认应该重新发送 .

    问题是:

    What actually should happen with message acknowledgement in case of exception thrown in the jms listener?

    从这个堆栈跟踪中可以看到真正发生的事情:

    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:98)

    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:66)

    at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:660)

    at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:620)

    at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:591)

    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:308)

    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:246)

    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1142)

    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1134)

    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1031)

    堆栈跟踪的第5行是特别感兴趣的 . 那里的代码基本上意味着,(大多数情况下)从侦听器抛出的任何异常都将绕过在 org.springframework.jms.listener.AbstractMessageListenerContainer#commitIfNecessary 中完成的确认 .

    That's ok, but what does "no redelivery in case of exception thrown" mean then?

    附加信息:

    spring JMS:4.1.2

    展开全文
  • 利用OKhttp网络框架,进行Maven项目管理//报文发送com.squareup.okhttp3okhttp3.8.0//报文解析xomxom1.2.5报文示例18赵明玉沙明德报文拼接StringBuffer strBuff = new StringBuffer();strBuff.append("");strBuff....
  • } /** * 发送信息给指定ID用户,如果用户不在线则返回不在线信息给自己 * @param message * @param sendUserId * @throws IOException */ public Boolean sendToUser(String message, String sendUserId) throws ...
  • 公司最近启用了F5设备(负载均衡),部署完成后,发现负载的业务时通时断,在宿主机上抓包发现当虚拟机发送的报文原MAC地址是宿主机的MAC时,TCP请求会失败。...如何改成始终通过虚拟机的MAC发送报文?感谢了 ...
  • 弄了两天,终于搞定了!把最简单的icmp报文发送实现了。本程序在linux环境编写,使用原始套接字。实现步骤:1、得到protocol实体(protoent,声明于);2、初始化地址结构(sockaddr_...5、发送报文(sendto(),声明于)...
  • CAN为什么会发送失败

    2021-05-16 18:48:58
    CAN总线调试过程中出现报文发送失败,很多工程师都对此只知其一不知其二,这里就CAN报文发送失败的问题我们来做一次探讨。在了解CAN报文为什么会发送失败之前我们先看看一条正确的CAN报文到底应该是怎么样的,表1是...
  • // 一定要设置报文格式,否则发送失败 con.setRequestProperty("Content-Type", "text/xml"); OutputStreamWriter out = null; try { out = new OutputStreamWriter(con.getOutputStream()); } catch ...
  • 在linux协议栈中,发送队列管理队列策略,而直接管理发送报文的是队列策略。所有发包软中断中调度的是队列策略,而不是发送队列。一、softnet_date结构体中为报文的发送定义如下字段:struct softnet_data{//有报文...
  • ABAP 发送JSON报文

    2021-01-05 16:23:20
    设置请求报文 CALL METHOD lr_http_client->request->set_cdata EXPORTING data = lv_post_string offset = 0 length = lv_len. * 构建HTTP连接,以及发送数据 CALL METHOD lr_...
  • scapy的发送包函数 scapy中,将Ether()看作是第二层,IP()看作是第三层 send()是发送第三层的包,也就是IP层,会自动处理路由和第二层 sendp()是发送第二层的包,需要自己选择正确的接口和正确的链路层协议 sendp...
  • } } else { //查询失败 } } // 调用WS private static StringBuffer testWebService(String sid, String content, String tranSeq, String tranReqDate) throws Exception { //拼接请求报文 String sendMsg = ...
  • BGP邻居建立过程及报文详解 BGP是基于TCP的,要建立邻居首先得建立TCP连接,所以要保证邻居地址可达,可以利用IGP协议来完成邻居的连通性。所以我们在R1和R2上分别配置静态路由完成邻居连通性R1:iproute10.10.10....
  • 本报文格式不能处理粘包问题,因为处理粘包问题的成本太高,会极大的降低服务端的处理效率...通讯建议:不要做什么握手机制,直接发送数据,服务器收到了就响应,收到响应后就结束通讯,握手增加耗电又增加流量消耗...
  • 释放双眼,带上耳机,听听看~!本文主要讲述了Socket协议脚本的基础知识和编写...1.1 Socket通讯方式说明与socket通讯有两种方式,一种是建立长连接,建立后不停的发送,接收;另一种是建立短连接,即建立连接发送报...
  • (tcp的收发与接收窗口/发送窗口/通告窗口关联比较紧密,接收/发送过程在《TCP/IP传输层协议实现 - TCP接收窗口/发送窗口/通告窗口(lwip)》https://blog.csdn.net/arm7star/article/details/117153533都有介绍,本文...
  • 常见的ICMP报文

    2020-12-24 02:49:55
    过程:一台主机向一个节点发送一个类型字段值为8的ICMP报文,如果途中没有异常(如果没有被路由丢弃,目标不回应ICMP或者传输失败),则目标返回类型字段值为0的ICMP报文,说明这台主机存在。目标不可达,源抑制和超时...
  • DAD报文控制

    2021-02-09 22:14:39
    PROC文件accept_dad控制DAD(Duplicate Address Detection)报文的接收,内核中根据目录all和接口(ens33)名称目录下的accept_dad的两个值中的最大值来决定最终的值。accept_dad的取值有以下三个: 0 - 关闭DAD 1 - ...
  • 在测试、调试策略代码时、实盘运行机器人时经常有...1、使用Python的scapy库抓包打印出发送的请求报文 首先安装scapy模块 pip3 install scapy 然后创建一个python策略: from scapy.all import * def Method_prin
  • 发送xml报文请求: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.MalformedURLException; import java.net...
  • plsql解析xml报文问题

    2021-04-30 08:52:04
    以下两个程序输入报文为falsefalse1. 输入参数为varchar类型,代码如下。长度input_list_n,能够计算出来为1,但是取不出p_id的值,值为null,为什么?create or replace procedure P_XMLTEST3(in_param in varchar,...
  • BGP报文格式分析

    千次阅读 2021-01-16 21:19:33
    BGP不需要开发确认报文,因为所有的确认都由TCP层来提供,从而可以减少BGP的报文数量,BGP 所有报文均采用单播的方式来发送,因此不能够自动地发现邻居。 BGP的运行是通过消息驱动的,共有Open、Update、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 57,026
精华内容 22,810
关键字:

发送报文失败