TCP IP工作流5 connect開始

2021-07-26 02:25:39 字數 2564 閱讀 4021

這個函式原型中,sockfd是就用socket呼叫得到乙個socket的檔案id。addr引數是,遠端要連線到的伺服器的位址了。addrlen是這個位址的描述符的長度。這裡,我就有了乙個疑問了,struct sockaddr的型別是確定的,為什麼這裡要要求乙個長度呢?看原始碼當然能找到答案,我們先猜測下,看**的不多的樂趣中的乙個。

* 猜想1:難道我們可以連線到遠端多個伺服器,或者有多個備選的伺服器可供使用。從系統可靠性的角度來說,這個猜測是合理的,為了可靠的服務,我提供給使用者乙個可選的伺服器列表,讓使用者乙個個都去嘗試下,選擇最優的,或者當前的伺服器宕掉了,選擇下乙個備用的。這裡的實現就是建立乙個列表,把伺服器的位址都寫進去,然後把列表的總長度作為引數傳遞進去。但這個猜測也有不合理的地方。

* 猜想2:如果是乙個列表的話,可以直接把列表中的元素的數量作為引數傳遞進去。何必傳遞乙個位址長度,還要讓函式自己計算數量。那麼有了第二個猜測,就是struct sockaddr是乙個變長的結構體,變長的結構體應該怎麼實現呢?c語言裡,一般把結構體裡的最後乙個成員設定為乙個指標,用來指向乙個陣列。這個也不合理,因為如果是乙個指標的話,就是乙個位址長度。32位os是4位元組,也是乙個定值,所以如何實現變長,還不明所以,這個推斷也不合理。

* 猜想3:sockaddr會在編譯時根據一些配置選項,來確定要不要包含一些成員。這個猜測也不合理。針對乙個編譯後的變數,用乙個sizeof也可以求出它的長度。

綜合以上3種猜測,現在看來,第一種最合理。去原始碼中看下。

connect呼叫還是開始於sys_sockcall函式。

sys_socketcall(call, args) net/socket.c 2004

然後呼叫sys_connect。

2032 sys_connect(a0, (struct sockaddr __user *)a0, a[2]);

sys_connect函式定義為於net/socket.c中。

1479 asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr,

1480

int addrlen)

1481

從函式的宣告看到,從connect函式呼叫傳遞過來的兩個引數還沒有得到處理。

1482 就不用再說了。是使用者層的socket的表達。

1483 定義了乙個最大位址數的字元陣列。c語言裡沒有單位元組資料型別,都是用char型別來代替的。這裡定義的max_sock_addr為128。我們假設這裡存的是ip位址,我們知道ipv4裡乙個位址要用4個位元組表示,那麼這裡能存貯的位址的最大數量為128/4 = 32。

1484 定義兩個臨時變數。

1486 根據檔案id fd去得到其sock的位址。這裡恰好是之前socket建立時的反過程上。從建立時,不難看出,大概的流程是根據fd找到struct file,struct file中的private變數就是指向struct sock的位址。感興趣的可以去看下。

1489 把使用者空間的位址,轉換到核心空間位址。因為系統呼叫目前還是在核心空間裡操作,想要處理使用者傳遞來的資料就需要用到move_addr_to_kernel的函式呼叫。

1494 安全檢查,有以前的經驗知道這裡面跟協議相關的東西沒有多少,我們先不考慮。

1498 這裡是真正執行呼叫的地方。第一篇tcp/ip工作流的開始 socket建立 1 中在socket建立過程中我們知道,這裡sock->ops為inet_stream_ops函式集。根據它的定義,最終執行的函式是inet_stream_connect。

546

int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,

547int addr_len, int flags)

548

561switch (sock->state)

591 timeo = sock_sndtimeo(sk, flags & o_nonblock);

593if ((1

<< sk->sk_state) & (tcpf_syn_sent | tcpf_syn_recv))

606if (sk->sk_state == tcp_close)

607goto sock_error;

614 sock->state = ss_connected;

615 err = 0;

616out:

617 release_sock(sk);

618return err;

620 sock_error:

621 err = sock_error(sk) ? : -econnaborted;

622 sock->state = ss_unconnected;

623if (sk->sk_prot->disconnect(sk, flags))

624 sock->state = ss_disconnecting;

625goto

out;

626 }

工作流建模 工作流概念

工作流建模 工作流概念 1 案例 工作流系統得基本目的是處理案例。每個案例都有乙個唯一標識,而且每個案例的生命週期都是有限的。案例生命週期都處於某個特定狀態,該狀態由三個元素組成 1 案例相關的屬性的值 案例屬性是一系列同案例相關的變數。能夠用來管理案例。正是通過這些變數,才有可能指出在特定條件下某...

工作流 一 什麼是工作流

什麼是工作流 工作流的英文全稱是 workflow,簡單理解則是業務流程的計算機化或自動化。它是是針對工作中具有固定程式的常規活動而提出的乙個概念,通過將工作活動分解定義良好的任務 角色 規則和過程來進行執行和監控,達到提高生產組織水平和工作效率的目的。工作流技術發端於70年代中期辦公自動化領域的研...

Activiti5工作流引擎

1.1 1 pocessengine是activiti中最核心的類,其他的類都是由他而來 1.1 2 產生方式 processengine processengine processengines.getdefaultprocessengine 呼叫 processengine的getdefault...