当前位置: 首页 > news >正文

公司网站建设宣传报道稿件/市场营销是做什么的

公司网站建设宣传报道稿件,市场营销是做什么的,wordpress keywords插件,一键生成静态网页从前面的一篇文章应用层发送一个数据包的时候,是如何到达网卡的(上)可以知道,应用层发送一个数据包的时候首先经过tcp_write和ip_queue_xmit函数,然后调用mac层的dev_queue_xmit函数。该函数代码如下,主要功…

从前面的一篇文章应用层发送一个数据包的时候,是如何到达网卡的(上)可以知道,应用层发送一个数据包的时候首先经过tcp_write和ip_queue_xmit函数,然后调用mac层的dev_queue_xmit函数。该函数代码如下,主要功能是完成arp解析(如果还没解析的话)、把数据包复制一份和对所有数据包都感兴趣的协议、把数据包插入发送队列,然后发送发送队列中的数据包。如果发送失败则加到发送队列里等待重发。

// dev为路由项对应的设备,在数据包路由的时候赋值
void dev_queue_xmit(struct sk_buff *skb, struct device *dev, int pri)
{unsigned long flags;int nitcount;struct packet_type *ptype;int where = 0;		/* used to say if the packet should go	*//* at the front or the back of the	*//* queue - front is a retransmit try	*/if (dev == NULL) {printk("dev.c: dev_queue_xmit: dev = NULL\n");return;}if(pri>=0 && !skb_device_locked(skb))skb_device_lock(skb);	/* Shove a lock on the frame */
#ifdef CONFIG_SLAVE_BALANCINGsave_flags(flags);cli();if(dev->slave!=NULL && dev->slave->pkt_queue < dev->pkt_queue &&(dev->slave->flags & IFF_UP))dev=dev->slave;restore_flags(flags);
#endif		
#ifdef CONFIG_SKB_CHECK IS_SKB(skb);
#endif    skb->dev = dev;/**	This just eliminates some race conditions, but not all... */if (skb->next != NULL) {/**	Make sure we haven't missed an interrupt. */printk("dev_queue_xmit: worked around a missed interrupt\n");start_bh_atomic();dev->hard_start_xmit(NULL, dev);end_bh_atomic();return;}/**	Negative priority is used to flag a frame that is being pulled from the*	queue front as a retransmit attempt. It therefore goes back on the queue*	start on a failure.*/// 类似坐标轴,-1和1是对称的,如果传的是负数,则先取他的对边,因为数组是从0开始,需要减一,比如传2即数组下标是1if (pri < 0) {pri = -pri-1;// 是直接发送还是先缓存到发送队列,1说明直接发送,0说明当前的skb先入队尾,先发送队列的队头节点where = 1;}if (pri >= DEV_NUMBUFFS) {printk("bad priority in dev_queue_xmit.\n");pri = 1;}/**	If the address has not been resolved. Call the device header rebuilder.*	This can cover all protocols and technically not just ARP either.*//*还没有完成arp解析,重新构建mac头,如果当前arp解析还没成功则直接返回,等待解析完成重新执行该函数(arp_rcv->arp_send_q).*/if (!skb->arp && dev->rebuild_header(skb->data, dev, skb->raddr, skb)) {return;}save_flags(flags);cli();	/*1 where一般是0,即pri是正整数,这时候skb会先插入队尾,先发送队头的节点,并且把数据包复制一份给对数据包感兴趣的协议,然后发送。2 where等于1,即pri是负数代表这个skb是发送失败后重发的,这时候这个数据包时直接发送出去的,不再走1的那些流程*/if (!where) {
#ifdef CONFIG_SLAVE_BALANCING	skb->in_dev_queue=1;
#endif		// 插入队尾,取出队头节点发送skb_queue_tail(dev->buffs + pri,skb);skb_device_unlock(skb);		/* Buffer is on the device queue and can be freed safely */skb = skb_dequeue(dev->buffs + pri);skb_device_lock(skb);		/* New buffer needs locking down */
#ifdef CONFIG_SLAVE_BALANCING		skb->in_dev_queue=0;
#endif		}restore_flags(flags);/* copy outgoing packets to any sniffer packet handlers */if(!where){	// 把所有发出去的数据包传一份给其他协议for (nitcount= dev_nit, ptype = ptype_base; nitcount > 0 && ptype != NULL; ptype = ptype->next) {/* Never send packets back to the socket* they originated from - MvS (miquels@drinkel.ow.org)*/// 对所有包都感兴趣的、不是packet协议产生的packet_type节点if (ptype->type == htons(ETH_P_ALL) &&(ptype->dev == dev || !ptype->dev) &&((struct sock *)ptype->data != skb->sk)){struct sk_buff *skb2;if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL)break;/**	The protocol knows this has (for other paths) been taken off*	and adds it back.*/skb2->len-=skb->dev->hard_header_len;ptype->func(skb2, skb->dev, ptype);nitcount--;}}}start_bh_atomic();// 调用驱动层发送if (dev->hard_start_xmit(skb, dev) == 0) {end_bh_atomic();/**	Packet is now solely the responsibility of the driver*/return;}end_bh_atomic();/**	Transmission failed, put skb back into a list. Once on the list it's safe and*	no longer device locked (it can be freed safely from the device queue)*/cli();
#ifdef CONFIG_SLAVE_BALANCINGskb->in_dev_queue=1;dev->pkt_queue++;
#endif		skb_device_unlock(skb);// 发送失败则把数据包重新加入队列skb_queue_head(dev->buffs + pri,skb);restore_flags(flags);
}

由以上代码可知mac层最后调用驱动层的函数去发送数据包,这里以3c501网卡为例。下面是发送函数的代码。


static int
el_start_xmit(struct sk_buff *skb, struct device *dev)
{struct net_local *lp = (struct net_local *)dev->priv;int ioaddr = dev->base_addr;unsigned long flags;if (dev->tbusy) {if (jiffies - dev->trans_start < 20) {if (el_debug > 2)printk(" transmitter busy, deferred.\n");return 1;}if (el_debug)printk ("%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",dev->name, inb(TX_STATUS), inb(AX_STATUS), inb(RX_STATUS));lp->stats.tx_errors++;outb(TX_NORM, TX_CMD);outb(RX_NORM, RX_CMD);outb(AX_OFF, AX_CMD);	/* Just trigger a false interrupt. */outb(AX_RX, AX_CMD);	/* Aux control, irq and receive enabled */dev->tbusy = 0;dev->trans_start = jiffies;}if (skb == NULL) {dev_tint(dev);return 0;}save_flags(flags);/* Avoid incoming interrupts between us flipping tbusy and flippingmode as the driver assumes tbusy is a faithful indicator of cardstate */cli();/* Avoid timer-based retransmission conflicts. */if (set_bit(0, (void*)&dev->tbusy) != 0){restore_flags(flags);printk("%s: Transmitter access conflict.\n", dev->name);}else {int gp_start = 0x800 - (ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN);unsigned char *buf = skb->data;lp->tx_pkt_start = gp_start;lp->collisions = 0;/**	Command mode with status cleared should [in theory]*	mean no more interrupts can be pending on the card.*/outb(AX_SYS, AX_CMD);inb(RX_STATUS);inb(TX_STATUS);/* *	Turn interrupts back on while we spend a pleasant afternoon*	loading bytes into the board */restore_flags(flags);outw(0x00, RX_BUF_CLR);		/* Set rx packet area to 0. */outw(gp_start, GP_LOW);		/* aim - packet will be loaded into buffer start */// 传输数据到网卡outsb(DATAPORT,buf,skb->len);	/* load buffer (usual thing each byte increments the pointer) */outw(gp_start, GP_LOW);		/* the board reuses the same register */outb(AX_XMIT, AX_CMD);		/* fire ... Trigger xmit.  */dev->trans_start = jiffies;}if (el_debug > 2)printk(" queued xmit.\n");dev_kfree_skb (skb, FREE_WRITE);return 0;
}

通过对整个过程的分析我们知道,一个数据包从应用层到网卡的过程中,数据包在tcp层处理完后下发到ip层,ip层会缓存一份数据到缓存队列,以备重传,但其实这里tcp层的工作。再到mac层,数据包也不一定是直接发送出去的,他可能会先缓存在发送队列里,按序发送。如果发送失败,则放回发送队列,等待重发。

http://www.lbrq.cn/news/965107.html

相关文章:

  • 宝塔面板做网站不能打开PHP显示404/建设网站制作
  • 上海网站搜索排名优化哪家好/北京百度推广投诉电话
  • 手机网站模板单页/现在学seo课程多少钱
  • 网页设计教程课本课后题答案/购买seo关键词排名优化官网
  • 云阳有没有做网站的/seo排名优化怎样
  • 网站后台管理系统设计/seo怎么做最佳
  • 购物网站怎么做/百度seo在哪里
  • 网站提供什么服务/网络营销的策划方案
  • 如何对网站做渗透/做网站推广
  • 桂林网站制作多少钱/百度广告怎么推广
  • 手机怎么自创网站/百度一级代理商
  • 电商网站怎么做聚合/北京seo的排名优化
  • 神奇网站/朋友圈推广一天30元
  • 大连筑成建设集团有限公司网站/郑州seo网络营销
  • 安新网站建设/怎样推广产品
  • 上海网站制作网站建设/杭州seo招聘
  • 网站建设包含的费用内容/小红书软文推广
  • 电商网站建设哪好/seo标题优化的心得总结
  • 做网站横幅技巧/优化推广网站怎么做最好
  • 网站做外链推广的常用方法/竞价 推广
  • WordPress分类ID能修改吗/西安网站seo诊断
  • 网站和其他系统对接怎么做/论坛软文案例
  • 驻马店市可以做网站的公司/举出最新的网络营销的案例
  • php和django做网站哪个好/中国seo第一人
  • 做外贸开通哪个网站好/微信引流推广精准粉
  • 重庆做网站的公司/app推广营销
  • 游戏推广渠道/广州seo优化公司排名
  • 网站怎么做兼容测试/互联网推广方式有哪些
  • 浙江 网站建设/怎么引流推广
  • 长春网站建设报价/seo资料站
  • Paimon 动态分桶
  • vue中的this.$set
  • 聚类算法原理与应用(一):K-means聚类算法原理
  • 16路串口光纤通信FPGA项目实现指南 - 第二部分(下)
  • 【JVM】内存分配与回收原则
  • Unity音游开发全指南:模板与免费资源高效构建节奏游戏