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

正文內(nèi)容

lwip協(xié)議棧的學(xué)習(xí)與應(yīng)用-googlecode(已改無錯字)

2022-12-27 04:10:02 本頁面
  

【正文】 onnection already has a PCB allocated. */ /* Is this an error condition? Should it be deleted? */ /* We currently just are happy and return. */ TCPIP_APIMSG_ACK(msg)。 } 還是看 TCP 的,在 pcb_new 函數(shù)中有如下代碼: case NETCONN_TCP: msgconn = tcp_new()。 if(msgconn == NULL) { msgconnerr = ERR_MEM。 break。 } setup_tcp(msgconn)。 break。 我們知道在這里建立了這個 tcp 的連接。至亍這個超級牛的函數(shù),以后再做介紹。 嗯,還是回過頭來接著看 accept 函數(shù)吧。 Sock 獲得了,接著就是 newconn = conn_accept(sockconn)。通過 mbox 叏得新的連接。粗略的估計(jì)了一下,這個新的連接應(yīng)該和 listen 有關(guān)系。那就再次打斷一下,看看那個 listen 操作。 lwip_listen ? conn_listen_with_backlog? do_listen? 23 tcp_arg(msgconn, msgconn)。 tcp_accept(msgconn, accept_function)。//注冊了一個接受函數(shù) * Accept callback function for TCP conns. * Allocates a new conn and posts that to connacceptmbox. static err_t accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) { struct conn *newconn。 struct conn *conn。 conn = (struct conn *)arg。 /* We have to set the callback here even though * the new socket is unknown. connsocket is marked as 1. */ newconn = conn_alloc(conntype, conncallback)。 if (newconn == NULL) { return ERR_MEM。 } newconn = newpcb。 setup_tcp(newconn)。 newconnerr = err。 /* Register event with callback */ API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0)。 if (sys_mbox_trypost(connacceptmbox, newconn) != ERR_OK) { /* When returning != ERR_OK, the connection is aborted in tcp_process(), so do nothing here! */ newconn = NULL。 conn_free(newconn)。 return ERR_MEM。 } return ERR_OK。 } 對了, accept 函數(shù)中從 mbox 中獲叏的連接就是這里放迚去的。 再回到 accept 中來,叏得了新的連接,接下來就是分配 sock 了,再然后,再然后?再然后就等用戶來使用接收、収送數(shù)據(jù)了。 到此整個 APP 層,也就是傳輸層以上對 socket 的封裝讱完了。在最后再總結(jié)一些整個路徑的調(diào)用情冴吧 24 API_MSG 結(jié)構(gòu)及其實(shí)現(xiàn) 如果要評起到最關(guān)鍵作用的一個結(jié)構(gòu)體,那么 struct api_msg 當(dāng)之無愧。先看下它的定義: /** This struct contains a function to execute in another thread context and a struct api_msg_msg that serves as an argument for this function. This is passed to tcpip_apimsg to execute functions in tcpip_thread context. */ struct api_msg { /** function to execute in tcpip_thread context */ void (* function)(struct api_msg_msg *msg)。 /** arguments for this function */ struct api_msg_msg msg。 }。 功能說的很清楚。但是具體怎么個操作法還是不知道,沒關(guān)系,接著看它的調(diào)用。 舉一個例子,剛好是上一篇中調(diào)用,但是沒有看具體實(shí)現(xiàn)的 err_t conn_getaddr(struct conn *conn, struct ip_addr *addr, u16_t *port, u8_t local) { struct api_msg msg。 = do_getaddr。 = conn。 = addr。 = port。 25 = local。 TCPIP_APIMSG(amp。msg)。 return connerr。 } 說明一下, api_msg結(jié)構(gòu)幾乎都是在 conn_xxx 函數(shù)中被調(diào)用,方式千篇一律,除了 ms 的賦值不一樣外。上面的調(diào)用很簡單,對該結(jié)構(gòu)體變量賦值,接著就是調(diào)用 TCPIP_APIMSG,這個函數(shù)上面講 過,可過去看下。既然如此,就不得不說 mbox 及其相關(guān)函數(shù)了。 static sys_mbox_t mbox = SYS_MBOX_NULL?!?】 再看 sys_mbox_t 的定義,在【 src\include\lwip\】中 /* For a totally minimal and standalone system, we provide null definitions of the sys_ functions. */ typedef u8_t sys_sem_t。 typedef u8_t sys_mbox_t。 typedef u8_t sys_prot_t。 可以看到這里只是簡單的定義成了 u8 類型,注意上面的紅色字體的說明,很明顯這個是可移植的一部分,需要根據(jù)不同的平臺,不同的操作系統(tǒng)具體定義??梢越梃b 焦海波 大俠的關(guān)于 ucos上對 lwip 的移植筆記來看。 我們可以看到在 api_msg 結(jié)構(gòu)的處理過程中,所有的信息都是包含在 api_msg_msg 結(jié)構(gòu)體中的, api_msg只是將其和 function簡單的組合了。下面看下這個牛結(jié)構(gòu)的定義: /** This struct includes everything that is necessary to execute a function for a conn in another thread context (mainly used to process conns in the tcpip_thread context to be thread safe). */ struct api_msg_msg { /** The conn which to process always needed: it includes the semaphore which is used to block the application thread until the function finished. */ struct conn *conn。 /** Depending on the executed function, one of these union members is used */ union { /** used for do_send */ struct buf *b。 /** used for do_newconn */ struct { u8_t proto。 } n。 /** used for do_bind and do_connect */ struct { struct ip_addr *ipaddr。 u16_t port。 26 } bc。 /** used for do_getaddr */ struct { struct ip_addr *ipaddr。 u16_t *port。 u8_t local。 } ad。 /** used for do_write */ struct { const void *dataptr。 int len。 u8_t apiflags。 } w。 /** used ofr do_recv */ struct { u16_t len。 } r。 if LWIP_IGMP /** used for do_join_leave_group */ struct { struct ip_addr *multiaddr。 struct ip_addr *interface。 enum conn_igmp join_or_leave。 } jl。 endif /* LWIP_IGMP */ if TCP_LISTEN_BACKLOG struct { u8_t backlog。 } lb。 endif /* TCP_LISTEN_BACKLOG */ } msg。 }。 一個很合理的設(shè)計(jì),至少筆者是這么認(rèn)為的。關(guān)鍵在于 msg union的設(shè)計(jì)。 TCP 層發(fā)送相關(guān) 現(xiàn)在我們正式開始進(jìn)入對 TCP 的研究,它屬于傳輸層協(xié)議,它為應(yīng)用程序提供了可靠的字節(jié)流服務(wù)。在 LWIP 中基本的 TCP 處理過程被分割為六個功能函數(shù)的實(shí)現(xiàn): tcp_input(), tcp_process(), tcp_receive()【與 TCP 輸入有關(guān)】 , tcp_write(), tcp_enqueue(), tcp_output()【用于 TCP 輸出】。這些是從大的方面來劃分的。 27 現(xiàn)在先從小部 :我們知道這里的函數(shù)都是被 socket 那一層的最終調(diào)用的。為了利于分析,我選擇 lwip_send函數(shù)來分析,具體不多說,最終調(diào)用到了 static err_t do_writemore(struct conn *conn)這個函數(shù),當(dāng)然這期間也做了不少工作,最主要的就是把發(fā)送數(shù)據(jù)的指針放到了 msg 的指定變量中 = dataptr。//指針 = size。 //長度 這些又經(jīng)過轉(zhuǎn)化放到了 conn 的 write_msg中 最后就是對 do_writemore 的調(diào)用了,下面詳細(xì)分析這個函數(shù)。 這個函數(shù)的最直接調(diào)用有以下幾個: available = tcp_sndbuf(conn)。 err = tcp_write(conn, dataptr, len, connwrite_msgs)。 err = tcp_output_nagle(conn)。 err = tcp_output(conn)。 好,先看 tcp_sndbuf 這個。從其參數(shù),我們應(yīng)該想像 pcb 的重要性。 define tcp_sndbuf(pcb) ((pcb)snd_buf)//由下面分析得這里直接返回 buf 大小 那就繼續(xù)跟蹤這個 pcb好了。是的,這還得從 lwip_socket 開始,在創(chuàng)建連接 conn 的時候調(diào)用了 do_newconn,它接著調(diào)用了 pcb_new,在這個函數(shù)中如果是 tcp的話有以下代碼 msgconn = tcp_new()。 哈哈,還記得吧,在前面我討論到了這里,就沒有再討論了。嗯,現(xiàn)在開始吧。 * Creates a new TCP protocol control block but doesn39。t place it on * any of the TCP PCB lists. * The pcb
點(diǎn)擊復(fù)制文檔內(nèi)容
環(huán)評公示相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖片鄂ICP備17016276號-1