网站动态背景欣赏,md风格wordpress主题,wordpress固定连接404,网站怎么推广效果好一点呢一、UDP编程
UDP编程的应用和TCP编程的应用同样非常广泛#xff0c;如果说真得想使用UDP编程#xff0c;一般情况下还真得不至于运用DPDK这种重量级的框架。但一个框架的优秀与否#xff0c;不仅仅在于自身的整体设计优秀#xff0c;更重要的在于其对应用的支持更完善。 正…一、UDP编程
UDP编程的应用和TCP编程的应用同样非常广泛如果说真得想使用UDP编程一般情况下还真得不至于运用DPDK这种重量级的框架。但一个框架的优秀与否不仅仅在于自身的整体设计优秀更重要的在于其对应用的支持更完善。 正如DPDK对TCP的支持一样其实对于DPDK这种更侧重于底层的应用来说实现UDP和TCP没有本质的区别只是套的一层解析的协议不同罢了。同样UDP与TCP的不同及其协议的内容如有不明白可自行查看相关资料此处不再赘述。
二、DPDK实现UDP源码分析
下面看一下例程代码来源与TCP相同: 1、数据结构和协议
// arp表的单个条目
struct arp_entry
{uint32_t ip;unsigned char hwaddr[RTE_ETHER_ADDR_LEN];unsigned char type;struct arp_entry *next;struct arp_entry *prev;
};// arp表结构
struct arp_table
{struct arp_entry *entries;int count;pthread_spinlock_t spinlock;
};
// udp control block
struct localhost
{int fd;//unsigned int status; //uint32_t localip; // ip -- macunsigned char localmac[RTE_ETHER_ADDR_LEN];uint16_t localport;unsigned char protocol;struct rte_ring *sndbuf;struct rte_ring *rcvbuf;struct localhost *prev;struct localhost *next;pthread_cond_t cond;pthread_mutex_t mutex;
};
//UDP的数据包
struct offload
{uint32_t sip;uint32_t dip;uint16_t sport;uint16_t dport;int protocol;unsigned char *data;uint16_t length;};
//common.c
int ng_arp_entry_insert(uint32_t ip, unsigned char *mac)
{struct arp_table *pstTbl arp_table_instance();struct arp_entry *pstEntry NULL;unsigned char *pstHwaddr NULL;pstHwaddr ng_get_dst_macaddr(ip);if(pstHwaddr NULL){pstEntry rte_malloc(arp_entry, sizeof(struct arp_entry), 0);if (pstEntry){memset(pstEntry, 0, sizeof(struct arp_entry));pstEntry-ip ip;rte_memcpy(pstEntry-hwaddr, mac, RTE_ETHER_ADDR_LEN);pstEntry-type 0;pthread_spin_lock(pstTbl-spinlock);LL_ADD(pstEntry, pstTbl-entries);pstTbl-count ;pthread_spin_unlock(pstTbl-spinlock);}return 1;}return 0;
}static struct arp_table *arp_table_instance(void)
{if (g_pstArpTbl NULL){g_pstArpTbl rte_malloc(arp table, sizeof(struct arp_table), 0);if (g_pstArpTbl NULL)rte_exit(EXIT_FAILURE, rte_malloc arp table failed\n);memset(g_pstArpTbl, 0, sizeof(struct arp_table));pthread_spin_init(g_pstArpTbl-spinlock, PTHREAD_PROCESS_SHARED);}return g_pstArpTbl;
}unsigned char* ng_get_dst_macaddr(uint32_t dip)
{struct arp_entry *pstIter;struct arp_table *pstTbl arp_table_instance();int count pstTbl-count;for (pstIter pstTbl-entries; count-- ! 0 pstIter ! NULL; pstIter pstIter-next){if (dip pstIter-ip)return pstIter-hwaddr;}return NULL;
}UDP数据处理分为两类一类是控制包一类是负载包也就是数据包。arp表的作用类似于快递小哥的作用查找IP与MAC的映射并实现数据包的准确传输即其有两个出口一个是数据发送时的出口保存发送时的IP和MAC没有则先广播一个是接收时的出口用来保存收到的数据包对应的IP和MAC。代码没有什么难度大家对照着相关的协议实现就明白了。
int nsocket(__attribute__((unused)) int domain, int type, __attribute__((unused)) int protocol)
{int iFd;struct localhost *pstHost;pthread_cond_t pctCond PTHREAD_COND_INITIALIZER;pthread_mutex_t pmtMutex PTHREAD_MUTEX_INITIALIZER;iFd get_fd_frombitmap();if(type SOCK_DGRAM) // udp{pstHost rte_malloc(localhost, sizeof(struct localhost), 0);if(pstHost NULL){printf([%s][%d]: rte_malloc fail!\n, __FUNCTION__, __LINE__);return -1;}memset(pstHost, 0x00, sizeof(struct localhost));pstHost-fd iFd;pstHost-protocol IPPROTO_UDP;pstHost-rcvbuf rte_ring_create(recv buffer, D_RING_SIZE, rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ);if (pstHost-rcvbuf NULL){printf([%s][%d]: rte_ring_create fail!\n, __FUNCTION__, __LINE__);rte_free(pstHost);return -1;}pstHost-sndbuf rte_ring_create(send buffer, D_RING_SIZE, rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ);if (pstHost-sndbuf NULL){printf([%s][%d]: rte_ring_create fail!\n, __FUNCTION__, __LINE__);rte_ring_free(pstHost-rcvbuf);rte_free(pstHost);return -1;}rte_memcpy(pstHost-cond, pctCond, sizeof(pthread_cond_t));rte_memcpy(pstHost-mutex, pmtMutex, sizeof(pthread_mutex_t));LL_ADD(pstHost, g_pstHost);}else if(type SOCK_STREAM) // tcp{struct tcp_stream *pstStream rte_malloc(tcp_stream, sizeof(struct tcp_stream), 0);if (pstStream NULL)return -1;memset(pstStream, 0, sizeof(struct tcp_stream));pstStream-fd iFd;pstStream-protocol IPPROTO_TCP;pstStream-next pstStream-prev NULL;pstStream-rcvbuf rte_ring_create(tcp recv buffer, D_RING_SIZE, rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ);if (pstStream-rcvbuf NULL){rte_free(pstStream);return -1;}pstStream-sndbuf rte_ring_create(tcp send buffer, D_RING_SIZE, rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ);if (pstStream-sndbuf NULL){rte_ring_free(pstStream-rcvbuf);rte_free(pstStream);return -1;}pthread_cond_t blank_cond PTHREAD_COND_INITIALIZER;rte_memcpy(pstStream-cond, blank_cond, sizeof(pthread_cond_t));pthread_mutex_t blank_mutex PTHREAD_MUTEX_INITIALIZER;rte_memcpy(pstStream-mutex, blank_mutex, sizeof(pthread_mutex_t));g_pstTcpTbl tcpInstance();LL_ADD(pstStream, g_pstTcpTbl-tcb_set); // todo :hash}return iFd;
}
int nbind(int sockfd, const struct sockaddr *addr, __attribute__((unused)) socklen_t addrlen)
{void *info NULL;info get_hostinfo_fromfd(sockfd);if(info NULL)return -1;struct localhost *pstHostInfo (struct localhost *)info;if(pstHostInfo-protocol IPPROTO_UDP){const struct sockaddr_in *pstAddr (const struct sockaddr_in *)addr;pstHostInfo-localport pstAddr-sin_port;rte_memcpy(pstHostInfo-localip, pstAddr-sin_addr.s_addr, sizeof(uint32_t));rte_memcpy(pstHostInfo-localmac, g_stCpuMac, RTE_ETHER_ADDR_LEN);}else if(pstHostInfo-protocol IPPROTO_TCP){struct tcp_stream* pstStream (struct tcp_stream*)pstHostInfo;const struct sockaddr_in *pstAddr (const struct sockaddr_in *)addr;pstStream-dport pstAddr-sin_port;rte_memcpy(pstStream-dip, pstAddr-sin_addr.s_addr, sizeof(uint32_t));rte_memcpy(pstStream-localmac, g_stCpuMac, RTE_ETHER_ADDR_LEN);pstStream-status TCP_STATUS_CLOSED;}return 0;
}
ssize_t nrecvfrom(int sockfd, void *buf, size_t len, __attribute__((unused)) int flags,struct sockaddr *src_addr, __attribute__((unused)) socklen_t *addrlen)
{struct localhost *pstHostInfo NULL;struct offload *pstOffLoad NULL;struct sockaddr_in *pstAddr NULL;unsigned char *pucPtr NULL;int iLen 0;int iRet -1;pstHostInfo (struct localhost *)get_hostinfo_fromfd(sockfd);if(pstHostInfo NULL)return -1;pthread_mutex_lock(pstHostInfo-mutex);while((iRet rte_ring_mc_dequeue(pstHostInfo-rcvbuf, (void**)pstOffLoad)) 0){pthread_cond_wait(pstHostInfo-cond, pstHostInfo-mutex);}pthread_mutex_unlock(pstHostInfo-mutex);pstAddr (struct sockaddr_in *)src_addr;pstAddr-sin_port pstOffLoad-sport;rte_memcpy(pstAddr-sin_addr.s_addr, pstOffLoad-sip, sizeof(uint32_t));if(len pstOffLoad-length){rte_memcpy(buf, pstOffLoad-data, len);pucPtr rte_malloc(unsigned char *, pstOffLoad-length - len, 0);rte_memcpy(pucPtr, pstOffLoad-data len, pstOffLoad-length - len);pstOffLoad-length - len;rte_free(pstOffLoad-data);pstOffLoad-data pucPtr;rte_ring_mp_enqueue(pstHostInfo-rcvbuf, pstOffLoad);return len;}iLen pstOffLoad-length;rte_memcpy(buf, pstOffLoad-data, pstOffLoad-length);rte_free(pstOffLoad-data);rte_free(pstOffLoad);return iLen;
} ssize_t nsendto(int sockfd, const void *buf, size_t len, __attribute__((unused)) int flags,const struct sockaddr *dest_addr, __attribute__((unused)) socklen_t addrlen)
{struct localhost *pstHostInfo NULL;struct offload *pstOffLoad NULL;const struct sockaddr_in *pstAddr (const struct sockaddr_in *)dest_addr;pstHostInfo (struct localhost *)get_hostinfo_fromfd(sockfd);if(pstHostInfo NULL)return -1;pstOffLoad rte_malloc(offload, sizeof(struct offload), 0);if (pstOffLoad NULL)return -1;pstOffLoad-dip pstAddr-sin_addr.s_addr;pstOffLoad-dport pstAddr-sin_port;pstOffLoad-sip pstHostInfo-localip;pstOffLoad-sport pstHostInfo-localport;pstOffLoad-length len;struct in_addr addr;addr.s_addr pstOffLoad-dip;printf(nsendto --- src: %s:%d \n, inet_ntoa(addr), ntohs(pstOffLoad-dport));pstOffLoad-data rte_malloc(unsigned char *, len, 0);if (pstOffLoad-data NULL) {rte_free(pstOffLoad);return -1;}rte_memcpy(pstOffLoad-data, buf, len);puts(rte_ring_mp_enqueue before !);rte_ring_mp_enqueue(pstHostInfo-sndbuf, pstOffLoad);puts(rte_ring_mp_enqueue after !);return len;
}int nclose(int fd)
{void *info NULL;info (struct localhost *)get_hostinfo_fromfd(fd);if(info NULL)return -1;struct localhost *pstHostInfo (struct localhost *)info;if(pstHostInfo-protocol IPPROTO_UDP){LL_REMOVE(pstHostInfo, g_pstHost);if (pstHostInfo-rcvbuf)rte_ring_free(pstHostInfo-rcvbuf);if (pstHostInfo-sndbuf)rte_ring_free(pstHostInfo-sndbuf);rte_free(pstHostInfo);set_fd_frombitmap(fd);}else if(pstHostInfo-protocol IPPROTO_TCP){struct tcp_stream *pstStream (struct tcp_stream*)info;if (pstStream-status ! TCP_STATUS_LISTEN){struct tcp_fragment *pstFragment rte_malloc(tcp_fragment, sizeof(struct tcp_fragment), 0);if (pstFragment NULL)return -1;memset(pstFragment, 0x00, sizeof(struct tcp_fragment));pstFragment-data NULL;pstFragment-length 0;pstFragment-sport pstStream-dport;pstFragment-dport pstStream-sport;pstFragment-seqnum pstStream-snd_nxt;pstFragment-acknum pstStream-rcv_nxt;pstFragment-tcp_flags RTE_TCP_FIN_FLAG | RTE_TCP_ACK_FLAG; // 发送FINpstFragment-windows D_TCP_INITIAL_WINDOW;pstFragment-hdrlen_off 0x50;rte_ring_mp_enqueue(pstStream-sndbuf, pstFragment);pstStream-status TCP_STATUS_LAST_ACK;set_fd_frombitmap(fd);}else{LL_REMOVE(pstStream, g_pstTcpTbl-tcb_set);rte_free(pstStream);}}return 0;
}2、接口实现
#include udp.h
int udp_process(struct rte_mbuf *pstUdpMbuf)
{struct rte_ipv4_hdr *pstIpHdr;struct rte_udp_hdr *pstUdpHdr;struct localhost *pstHost;struct offload *pstOffLoad;pstIpHdr rte_pktmbuf_mtod_offset(pstUdpMbuf, struct rte_ipv4_hdr *, sizeof(struct rte_ether_hdr));pstUdpHdr (struct rte_udp_hdr *)(pstIpHdr 1);pstHost get_hostinfo_fromip_port(pstIpHdr-dst_addr, pstUdpHdr-dst_port, pstIpHdr-next_proto_id);if (pstHost NULL){rte_pktmbuf_free(pstUdpMbuf);return -3;}struct in_addr addr;addr.s_addr pstIpHdr-src_addr;printf(udp_process --- src: %s:%d \n, inet_ntoa(addr), ntohs(pstUdpHdr-src_port));pstOffLoad rte_malloc(offload, sizeof(struct offload), 0);if (pstOffLoad NULL){rte_pktmbuf_free(pstUdpMbuf);return -1;}pstOffLoad-dip pstIpHdr-dst_addr;pstOffLoad-sip pstIpHdr-src_addr;pstOffLoad-sport pstUdpHdr-src_port;pstOffLoad-dport pstUdpHdr-dst_port;pstOffLoad-protocol IPPROTO_UDP;pstOffLoad-length ntohs(pstUdpHdr-dgram_len);pstOffLoad-data rte_malloc(unsigned char*, pstOffLoad-length - sizeof(struct rte_udp_hdr), 0);if (pstOffLoad-data NULL){rte_pktmbuf_free(pstUdpMbuf);rte_free(pstOffLoad);return -2;}rte_memcpy(pstOffLoad-data, (unsigned char *)(pstUdpHdr1), pstOffLoad-length - sizeof(struct rte_udp_hdr));rte_ring_mp_enqueue(pstHost-rcvbuf, pstOffLoad); // recv bufferpthread_mutex_lock(pstHost-mutex);pthread_cond_signal(pstHost-cond);pthread_mutex_unlock(pstHost-mutex);rte_pktmbuf_free(pstUdpMbuf);return 0;
}static int ng_encode_udp_apppkt(uint8_t *msg, uint32_t sip, uint32_t dip,uint16_t sport, uint16_t dport, uint8_t *srcmac, uint8_t *dstmac,unsigned char *data, uint16_t total_len)
{struct rte_ether_hdr *pstEth;struct rte_ipv4_hdr *pstIp;struct rte_udp_hdr *pstUdp;// 1 ethhdrpstEth (struct rte_ether_hdr *)msg;rte_memcpy(pstEth-s_addr.addr_bytes, srcmac, RTE_ETHER_ADDR_LEN);rte_memcpy(pstEth-d_addr.addr_bytes, dstmac, RTE_ETHER_ADDR_LEN);pstEth-ether_type htons(RTE_ETHER_TYPE_IPV4);// 2 iphdrpstIp (struct rte_ipv4_hdr *)(pstEth 1);pstIp-version_ihl 0x45;pstIp-type_of_service 0;pstIp-total_length htons(total_len - sizeof(struct rte_ether_hdr));pstIp-packet_id 0;pstIp-fragment_offset 0;pstIp-time_to_live 64; // ttl 64pstIp-next_proto_id IPPROTO_UDP;pstIp-src_addr sip;pstIp-dst_addr dip;pstIp-hdr_checksum 0;pstIp-hdr_checksum rte_ipv4_cksum(pstIp);// 3 udphdrpstUdp (struct rte_udp_hdr *)(pstIp 1);pstUdp-src_port sport;pstUdp-dst_port dport;uint16_t udplen total_len - sizeof(struct rte_ether_hdr) - sizeof(struct rte_ipv4_hdr);pstUdp-dgram_len htons(udplen);rte_memcpy((uint8_t*)(pstUdp 1), data, udplen);pstUdp-dgram_cksum 0;pstUdp-dgram_cksum rte_ipv4_udptcp_cksum(pstIp, pstUdp);return 0;
}static struct rte_mbuf * ng_udp_pkt(struct rte_mempool *mbuf_pool, uint32_t sip, uint32_t dip,uint16_t sport, uint16_t dport, unsigned char *srcmac, unsigned char *dstmac,unsigned char *data, uint16_t length)
{unsigned int uiTotalLen;struct rte_mbuf *pstMbuf;unsigned char *pucPktData;uiTotalLen length 42; // 42 eth ippstMbuf rte_pktmbuf_alloc(mbuf_pool);if (!pstMbuf)rte_exit(EXIT_FAILURE, rte_pktmbuf_alloc\n);pstMbuf-pkt_len uiTotalLen;pstMbuf-data_len uiTotalLen;pucPktData rte_pktmbuf_mtod(pstMbuf, unsigned char*);ng_encode_udp_apppkt(pucPktData, sip, dip, sport, dport, srcmac, dstmac,data, uiTotalLen);return pstMbuf;
}int udp_out(struct rte_mempool *pstMbufPool)
{struct localhost *pstHost;for(pstHost g_pstHost; pstHost ! NULL; pstHost pstHost-next){struct offload *pstOffLoad NULL;int iSendCnt rte_ring_mc_dequeue(pstHost-sndbuf, (void **)pstOffLoad);if(iSendCnt 0)continue;struct in_addr addr;addr.s_addr pstOffLoad-dip;printf(udp_out --- src: %s:%d \n, inet_ntoa(addr), ntohs(pstOffLoad-dport));unsigned char *dstmac ng_get_dst_macaddr(pstOffLoad-dip); // 查询对端mac地址if (dstmac NULL) // 先广播发个arp包确定对端mac地址{struct rte_mbuf *pstArpbuf ng_send_arp(pstMbufPool, RTE_ARP_OP_REQUEST, g_aucDefaultArpMac,pstOffLoad-sip, pstOffLoad-dip);rte_ring_mp_enqueue_burst(g_pstRingIns-pstOutRing, (void **)pstArpbuf, 1, NULL);rte_ring_mp_enqueue(pstHost-sndbuf, pstOffLoad); // 将取出的udp数据再次写入队列}else{struct rte_mbuf *pstUdpbuf ng_udp_pkt(pstMbufPool, pstOffLoad-sip, pstOffLoad-dip,pstOffLoad-sport, pstOffLoad-dport, pstHost-localmac,dstmac, pstOffLoad-data, pstOffLoad-length);rte_ring_mp_enqueue_burst(g_pstRingIns-pstOutRing, (void **)pstUdpbuf, 1, NULL);if (pstOffLoad-data ! NULL)rte_free(pstOffLoad-data);rte_free(pstOffLoad);}}return 0;
}机制和TCP类似。
3、上层应用
//netfamily.c
unsigned char g_aucDefaultArpMac[RTE_ETHER_ADDR_LEN] {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};unsigned char g_ucFdTable[D_MAX_FD_COUNT] {0};static struct St_InOut_Ring *ringInstance(void)
{if (g_pstRingIns NULL){g_pstRingIns rte_malloc(in/out ring, sizeof(struct St_InOut_Ring), 0);memset(g_pstRingIns, 0, sizeof(struct St_InOut_Ring));}return g_pstRingIns;
}void ng_init_port(struct rte_mempool *pstMbufPoolPub)
{unsigned int uiPortsNum;const int iRxQueueNum 1;const int iTxQueueNum 1;int iRet;struct rte_eth_dev_info stDevInfo;struct rte_eth_txconf stTxConf;struct rte_eth_conf stPortConf // 端口配置信息{.rxmode {.max_rx_pkt_len 1518 } // RTE_ETHER_MAX_LEN 1518};uiPortsNum rte_eth_dev_count_avail();if (uiPortsNum 0)rte_exit(EXIT_FAILURE, No Supported eth found\n);rte_eth_dev_info_get(D_PORT_ID, stDevInfo);// 配置以太网设备rte_eth_dev_configure(D_PORT_ID, iRxQueueNum, iTxQueueNum, stPortConf);iRet rte_eth_rx_queue_setup(D_PORT_ID, 0 , 1024, rte_eth_dev_socket_id(D_PORT_ID), NULL, pstMbufPoolPub);if(iRet 0)rte_exit(EXIT_FAILURE, Could not setup RX queue!\n);stTxConf stDevInfo.default_txconf;stTxConf.offloads stPortConf.txmode.offloads;iRet rte_eth_tx_queue_setup(D_PORT_ID, 0 , 1024, rte_eth_dev_socket_id(D_PORT_ID), stTxConf);if (iRet 0)rte_exit(EXIT_FAILURE, Could not setup TX queue\n);if (rte_eth_dev_start(D_PORT_ID) 0 )rte_exit(EXIT_FAILURE, Could not start\n);rte_eth_promiscuous_enable(D_PORT_ID);
}static int ng_config_network_if(uint16_t port_id, unsigned char if_up) {if (!rte_eth_dev_is_valid_port(port_id)) {return -EINVAL;}int ret 0;if (if_up) {rte_eth_dev_stop(port_id);ret rte_eth_dev_start(port_id);} else {rte_eth_dev_stop(port_id);}if (ret 0) {printf(Failed to start port : %d\n, port_id);}return 0;
}static struct rte_kni *ng_alloc_kni(struct rte_mempool *mbuf_pool) {struct rte_kni *kni_hanlder NULL;struct rte_kni_conf conf;memset(conf, 0, sizeof(conf));snprintf(conf.name, RTE_KNI_NAMESIZE, vEth%u, D_PORT_ID);conf.group_id D_PORT_ID;conf.mbuf_size D_MAX_PACKET_SIZE;rte_eth_macaddr_get(D_PORT_ID, (struct rte_ether_addr *)conf.mac_addr);rte_eth_dev_get_mtu(D_PORT_ID, conf.mtu);// print_ethaddr(ng_alloc_kni: , (struct ether_addr *)conf.mac_addr);/*struct rte_eth_dev_info dev_info;memset(dev_info, 0, sizeof(dev_info));rte_eth_dev_info_get(D_PORT_ID, dev_info);*/struct rte_kni_ops ops;memset(ops, 0, sizeof(ops));ops.port_id D_PORT_ID;ops.config_network_if ng_config_network_if;kni_hanlder rte_kni_alloc(mbuf_pool, conf, ops);if (!kni_hanlder) {rte_exit(EXIT_FAILURE, Failed to create kni for port : %d\n, D_PORT_ID);}return kni_hanlder;
}static int pkt_process(void *arg)
{struct rte_mempool *pstMbufPool;int iRxNum;int i;struct rte_ether_hdr *pstEthHdr;struct rte_ipv4_hdr *pstIpHdr;pstMbufPool (struct rte_mempool *)arg;while(1){struct rte_mbuf *pstMbuf[32];iRxNum rte_ring_mc_dequeue_burst(g_pstRingIns-pstInRing, (void**)pstMbuf, D_BURST_SIZE, NULL);if(iRxNum 0)continue;for(i 0; i iRxNum; i){pstEthHdr rte_pktmbuf_mtod_offset(pstMbuf[i], struct rte_ether_hdr *, 0);if (pstEthHdr-ether_type rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) //IPv4: 0800{pstIpHdr rte_pktmbuf_mtod_offset(pstMbuf[i], struct rte_ipv4_hdr *, sizeof(struct rte_ether_hdr));// 维护一个arp表ng_arp_entry_insert(pstIpHdr-src_addr, pstEthHdr-s_addr.addr_bytes);if(pstIpHdr-next_proto_id IPPROTO_UDP) // udp{// udp processudp_process(pstMbuf[i]);}else if(pstIpHdr-next_proto_id IPPROTO_TCP) // tcp{// printf(tcp_process ---\n);tcp_process(pstMbuf[i]);}else{rte_kni_tx_burst(g_pstKni, pstMbuf, iRxNum);// printf(tcp/udp -- rte_kni_handle_request\n);}}else{// ifconfig vEth0 192.168.181.169 uprte_kni_tx_burst(g_pstKni, pstMbuf, iRxNum);// printf(ip -- rte_kni_handle_request\n);} }rte_kni_handle_request(g_pstKni);// to sendudp_out(pstMbufPool);tcp_out(pstMbufPool);}return 0;
}int udp_server_entry(__attribute__((unused)) void *arg)
{ int iConnfd;struct sockaddr_in stLocalAddr, stClientAddr;socklen_t uiAddrLen sizeof(stClientAddr);;char acBuf[D_UDP_BUFFER_SIZE] {0};iConnfd nsocket(AF_INET, SOCK_DGRAM, 0);if (iConnfd -1){printf(nsocket failed\n);return -1;}memset(stLocalAddr, 0, sizeof(struct sockaddr_in));stLocalAddr.sin_port htons(8889);stLocalAddr.sin_family AF_INET;stLocalAddr.sin_addr.s_addr inet_addr(192.168.181.169);nbind(iConnfd, (struct sockaddr*)stLocalAddr, sizeof(stLocalAddr));while (1){if (nrecvfrom(iConnfd, acBuf, D_UDP_BUFFER_SIZE, 0,(struct sockaddr*)stClientAddr, uiAddrLen) 0){continue;}else{printf(recv from %s:%d, data:%s\n, inet_ntoa(stClientAddr.sin_addr),ntohs(stClientAddr.sin_port), acBuf);nsendto(iConnfd, acBuf, strlen(acBuf), 0,(struct sockaddr*)stClientAddr, sizeof(stClientAddr));}}nclose(iConnfd);return 0;
}int main(int argc, char *argv[])
{struct rte_mempool *pstMbufPoolPub;struct St_InOut_Ring *pstRing;struct rte_mbuf *pstRecvMbuf[32] {NULL};struct rte_mbuf *pstSendMbuf[32] {NULL};int iRxNum;int iTotalNum;int iOffset;int iTxNum;unsigned int uiCoreId;if(rte_eal_init(argc, argv) 0)rte_exit(EXIT_FAILURE, Error with EAL init\n);pstMbufPoolPub rte_pktmbuf_pool_create(MBUF_POOL_PUB, D_NUM_MBUFS, 0, 0,RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());if(pstMbufPoolPub NULL){printf(rte_errno %x, errmsg %s\n, rte_errno, rte_strerror(rte_errno));return -1;}if (-1 rte_kni_init(D_PORT_ID))rte_exit(EXIT_FAILURE, kni init failed\n);ng_init_port(pstMbufPoolPub);g_pstKni ng_alloc_kni(pstMbufPoolPub);// ng_init_port(pstMbufPoolPub);rte_eth_macaddr_get(D_PORT_ID, g_stCpuMac);pstRing ringInstance();if(pstRing NULL)rte_exit(EXIT_FAILURE, ring buffer init failed\n);pstRing-pstInRing rte_ring_create(in ring, D_RING_SIZE, rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ);pstRing-pstOutRing rte_ring_create(out ring, D_RING_SIZE, rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ);uiCoreId rte_lcore_id();uiCoreId rte_get_next_lcore(uiCoreId, 1, 0);rte_eal_remote_launch(pkt_process, pstMbufPoolPub, uiCoreId);uiCoreId rte_get_next_lcore(uiCoreId, 1, 0);rte_eal_remote_launch(udp_server_entry, pstMbufPoolPub, uiCoreId);uiCoreId rte_get_next_lcore(uiCoreId, 1, 0);rte_eal_remote_launch(tcp_server_entry, pstMbufPoolPub, uiCoreId);while (1){// rxiRxNum rte_eth_rx_burst(D_PORT_ID, 0, pstRecvMbuf, D_BURST_SIZE);if(iRxNum 0)rte_ring_sp_enqueue_burst(pstRing-pstInRing, (void**)pstRecvMbuf, iRxNum, NULL);// txiTotalNum rte_ring_sc_dequeue_burst(pstRing-pstOutRing, (void**)pstSendMbuf, D_BURST_SIZE, NULL);if(iTotalNum 0){iOffset 0;while(iOffset iTotalNum){iTxNum rte_eth_tx_burst(D_PORT_ID, 0, pstSendMbuf[iOffset], iTotalNum - iOffset);if(iTxNum 0)iOffset iTxNum;}}}}
在前面的应用中其实可以发现处理的TCP和UDP的数据有的是写在一个函数里了这其实是从设计上看不是很好以后不容易扩展可它也有好处啊容易让人明白啊。更多的依赖代码可以参看GITHUB上的开源地址。
四、总结
UDP其实在普通的网络应用中基本用来做一些辅助的工作如果地址发现、广播简单消息等等。但由于它的占用资源少在一些场景下就能发挥很大作用。包括在前文提到的QUIC其实都借鉴了UDP的一些特点。所以是不是觉得很多技术其实并不是完全隔离的它们会不断的整合、独立再如此循环。所以以后别的公司会不会也会也一个类似于DPDK的框架呢拭目以待