freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

lwip協(xié)議棧的學(xué)習(xí)與應(yīng)用-googlecode-資料下載頁

2024-11-14 04:10本頁面

【導(dǎo)讀】ComputerScience)AdamDunkels等人開収的一套用亍嵌入式系統(tǒng)的開放源代碼TCP/。LWIP的噸義是LightWeight(輕型)IP協(xié)議??梢栽跓o操作系統(tǒng)的情冴下獨(dú)立運(yùn)行。LWIPTCP/IP實(shí)現(xiàn)的重點(diǎn)是在保持TCP協(xié)議主要功。能的基礎(chǔ)上減少對(duì)RAM的占用。一般它叧需要幾十KB的RAM和40KB左右的ROM就??梢赃\(yùn)行,這使LWIP協(xié)議棧適合在小型嵌入式系統(tǒng)中使用。包括實(shí)驗(yàn)性擴(kuò)展的的UDP;包括阻塞控制,RTT估算和快速恢復(fù)和快速轉(zhuǎn)収的TCP;提供與門的內(nèi)部回調(diào)接口用亍提高應(yīng)用程序性能;可選擇的Berkeley接口API;在最新的版本中支持ppp;新版本中增加了的IPfragment的支持;支持DHCP協(xié)議,勱態(tài)分配ip地址。操作系統(tǒng)方面,我們選用的μC/OSII. 開収環(huán)境采用KEIL。原則上,秱植lwIP到其他。性的定時(shí)器,當(dāng)超時(shí)収生時(shí),調(diào)用一個(gè)已注冊(cè)函數(shù)至少要200ms的間隔。迚程同步機(jī)制僅提供了信號(hào)量。信息傳遞的實(shí)現(xiàn)使用一種簡單機(jī)制,用一種稱為“郵箱”的抽象方法。郵寄操作丌會(huì)阻塞迚程;郵寄到郵箱的消息由操作系統(tǒng)模擬層排入隊(duì)列直到另。隊(duì)列多用亍處理有序的事。向指定的信號(hào)量収送信號(hào)。

  

【正文】 is not put on any list until binding using tcp_bind(). struct tcp_pcb * tcp_new(void) { return tcp_alloc(TCP_PRIO_NORMAL)。 } 也許注釋的意義更大一些吧,哈哈,至此,我們從注釋可以知道, tcp_bind 的作用是把 tcp 的pcb 放入 list 中,至少是某一個(gè) list 既然都提到了,似乎不說說有點(diǎn)過意不去啊。 Lwid_bind 函數(shù)最終會(huì)調(diào)用到 tcp_bind【當(dāng)然是 tcp 為例進(jìn)行分析】。這個(gè)函數(shù)也比較有意思,在進(jìn)入正題之 前先來了下面這么個(gè)調(diào)用 if (port == 0) { port = tcp_new_port()。 } 意思很明顯,就是分配個(gè)新的端口號(hào),有意思的就是這個(gè)端口號(hào)的分配函數(shù) tcp_new_port static u16_t tcp_new_port(void) { struct tcp_pcb *pcb。 28 ifndef TCP_LOCAL_PORT_RANGE_START define TCP_LOCAL_PORT_RANGE_START 4096 define TCP_LOCAL_PORT_RANGE_END 0x7fff endif static u16_t port = TCP_LOCAL_PORT_RANGE_START。 again: if (++port TCP_LOCAL_PORT_RANGE_END) { port = TCP_LOCAL_PORT_RANGE_START。 } for(pcb = tcp_active_pcbs。 pcb != NULL。 pcb = pcbnext) { if (pcblocal_port == port) { goto again。 } } for(pcb = tcp_tw_pcbs。 pcb != NULL。 pcb = pcbnext) { if (pcblocal_port == port) { goto again。 } } for(pcb = (struct tcp_pcb *)。 pcb != NULL。 pcb = pcbnext) { if (pcblocal_port == port) { goto again。 } } return port。 }分別檢查了 3 個(gè) pcb鏈表,本來我不想把這個(gè)函數(shù)的實(shí)現(xiàn)列在這里的,但是這里告訴了我們一些東西,至少我們知道有 3 個(gè) pcb 的鏈表,分別是 tcp_active_pcbs【處于接受發(fā)送數(shù)據(jù)狀態(tài)的 pcbs】、 tcp_tw_pcbs【處于時(shí)間等待狀態(tài)的 pcbs】、 tcp_listen_pcbs【處于監(jiān)聽狀態(tài)的 pcbs】。 似乎 tcp_bind函數(shù)更有意思,它分別檢查了 4 個(gè) pcbs 鏈表,除了上面的三個(gè)還有一個(gè) tcp_bound_pcbs【處于已經(jīng)綁定但還沒有連接或者監(jiān)聽 pcbs】。作用是是否有與目前 pcb 的 ipaddr相同的 pcb 存在。不過這些都不是最重要的, TCP_REG(amp。tcp_bound_pcbs, pcb)。才是我們的目的,果然如此,直接加入到了 tcp_bound_pcbs鏈表中了。 struct tcp_pcb * tcp_alloc(u8_t prio)//是的,你沒看錯(cuò),這個(gè)參數(shù) 是學(xué)名是叫優(yōu)先級(jí) { pcb = memp_malloc(MEMP_TCP_PCB)。 if (pcb != NULL) { memset(pcb, 0, sizeof(struct tcp_pcb))。 pcbprio = TCP_PRIO_NORMAL。 29 pcbsnd_buf = TCP_SND_BUF。//對(duì)的,別的可以先不管,這就是我們要找的東西 pcbsnd_queuelen = 0。 pcbrcv_wnd = TCP_WND。 pcbrcv_ann_wnd = TCP_WND。 pcbtos = 0。 pcbttl = TCP_TTL。 /* The send MSS is updated when an MSS option is received. */ pcbmss = (TCP_MSS 536) ? 536 : TCP_MSS。 pcbrto = 3000 / TCP_SLOW_INTERVAL。 pcbsa = 0。 pcbsv = 3000 / TCP_SLOW_INTERVAL。 pcbrtime = 1。 pcbcwnd = 1。 iss = tcp_next_iss()。 pcbsnd_wl2 = iss。 pcbsnd_nxt = iss。 pcbsnd_max = iss。 pcblastack = iss。 pcbsnd_lbb = iss。 pcbtmr = tcp_ticks。 pcbpolltmr = 0。 if LWIP_CALLBACK_API pcbrecv = tcp_recv_null。 endif /* LWIP_CALLBACK_API */ /* Init KEEPALIVE timer */ pcbkeep_idle = TCP_KEEPIDLE_DEFAULT。 if LWIP_TCP_KEEPALIVE pcbkeep_intvl = TCP_KEEPINTVL_DEFAULT。 pcbkeep_t = TCP_KEEPCNT_DEFAULT。 endif /* LWIP_TCP_KEEPALIVE */ pcbkeep_t_sent = 0。 } return pcb。 }就是一個(gè) tcp_pcb的結(jié)構(gòu)體初始化過程,使用默認(rèn)值填充該結(jié)構(gòu) 好了,下面接著走,該輪到 tcp_write 了吧 * Write data for sending (but does not send it immediately). * It waits in the expectation of more data being sent soon (as * it can send them more efficiently by bining them together). 30 * To prompt the system to send data now, call tcp_output() after * calling tcp_write(). 【 src\core\】 err_t tcp_write(struct tcp_pcb *pcb, const void *data, u16_t len, u8_t apiflags) { /* connection is in valid state for data transmission? */ if (pcbstate == ESTABLISHED || pcbstate == CLOSE_WAIT || pcbstate == SYN_SENT || pcbstate == SYN_RCVD) { if (len 0) { return tcp_enqueue(pcb, (void *)data, len, 0, apiflags, NULL, 0)。 } return ERR_OK。 } else { return ERR_CONN。 } } 這個(gè)函數(shù)確實(shí)夠簡單的了,檢查 pcb 狀態(tài),直接入隊(duì)列。嗯,還是覺得看注釋比看函數(shù)實(shí)現(xiàn)過癮。 下面的這個(gè) tcp_enqueue 才是個(gè)大頭函數(shù), lwip協(xié)議棧的設(shè)計(jì)與 實(shí)現(xiàn)文檔中是這么介紹的:應(yīng)用層調(diào)用 tcp_write()函數(shù)以實(shí)現(xiàn)發(fā)送數(shù)據(jù),接著 tcp_write()函數(shù)再將控制權(quán)交給tcp_enqueue(),這個(gè)函數(shù)會(huì)在必要時(shí)將數(shù)據(jù)分割為適當(dāng)大小的 TCP 段,然后再把這些 TCP 段放到所屬連接的傳輸隊(duì)列中【 pcbunsent】。函數(shù)的注釋是這樣寫的: * Enqueue either data or TCP options (but not both) for tranmission * Called by tcp_connect(), tcp_listen_input(), tcp_send_ctrl() and tcp_write(). 咱們接著上面往下看, tcp_output_nagle 這個(gè)函數(shù)實(shí)際上是個(gè)宏,通過預(yù)判斷以決定是否調(diào)用 tcp_output。也就是說最后的執(zhí)行是 tcp_output 來實(shí)現(xiàn)的。這個(gè)函數(shù)或許比 tcp_enqueue 還要恐怖,從體積上來看。這里也只做一個(gè)簡單介紹,具體請(qǐng)參閱 文檔。該函數(shù)的注釋是這么說的: Find out what we can send and send it。文檔是這么解釋的:tcp_output 函數(shù)會(huì)檢查現(xiàn)在是不是能夠發(fā)送數(shù)據(jù),也就是判斷接收器窗口是否擁有足夠大的空間,阻塞窗口是否也足夠大,如果條件滿足,它先填充未被 tcp_enqueue 函數(shù)填充的 tcp報(bào)頭字段,接著就使用 ip_route 或者 ip_output_if 函數(shù)發(fā)送數(shù)據(jù)。 31 TCP 層接收相關(guān) 既然定了這么個(gè)標(biāo)題,當(dāng)然是要從 socket 的 recv來講了。這里主要涉及到 lwip_recvfrom 這個(gè)函數(shù)。它的大致過程是,先通過 conn_recv(sockconn)。從 conn 的 recvmbox中收取數(shù)據(jù),在這里有個(gè) do_recv 的調(diào)用,而 do_recv又調(diào)用了 tcp_recved,關(guān)于這個(gè)函數(shù)的注釋如下: * This function should be called by the application when it has * processed the data. The purpose is to advertise a larger window * when the data has been processed. 知道了,這里的 do_recv 只是起到一個(gè)知會(huì)的作用,可能的話會(huì)對(duì)接收條件做一些調(diào)整。 回到主題 , lwip_recvfrom 從 conn 接收完數(shù)據(jù)就是要 copy the contents of the received buffer into the supplied memory pointer mem,這一步是通過 buf_copy_partial 函數(shù)來完成的。 接著往下走,我們發(fā)現(xiàn),數(shù)據(jù)的來源是在 conn 的 recvmbox,剛才提到過的。好了,那么是在什么地方,什么時(shí)候這個(gè) recvmbox 被填充的呢? 在工程中搜索 recvmbox,發(fā)現(xiàn)在 recv_tcp 函數(shù)有這樣一句: sys_mbox_trypost(connrecvmbox, p) ok,就是它了。看看函數(shù)的原型: * Receive callback function for TCP conns. * Posts the packet to connrecvmbox, but doesn39。t delete it on errors. static err_t recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) 好的, p 是 個(gè)輸入?yún)?shù),并且這是個(gè)靜態(tài)函數(shù),是作為 tcp 的接收回調(diào)用的。 嗯接著看 recv_tcp 的 caller: * Setup a tcp_pcb with the correct callback function pointers * and their arguments. * @param conn the TCP conn to setup static void setup_tcp(struct conn *conn) { struct tcp_pcb *pcb。 pcb = conn。 tcp_arg(pcb, conn)。 tcp_recv(pcb, recv_tcp)。 tcp_sent(pcb, sent_tcp)。 tcp_poll(pcb, poll_tcp, 4)。 tcp_err(pcb, err_tcp)。 } 哈哈,可謂是一網(wǎng)打盡啊。對(duì)于這個(gè)函數(shù)中的幾個(gè)調(diào)用,我們看一個(gè)就好了,別的實(shí)現(xiàn)也差不多,就是個(gè)賦值的過程
點(diǎn)擊復(fù)制文檔內(nèi)容
環(huán)評(píng)公示相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖鄂ICP備17016276號(hào)-1