client**中,第乙個被呼叫的函式是socket(),在這個函式被呼叫之前,系統做了什麼事情,讓socket()可以正常呼叫?
首先,socket函式實際上是乙個系統呼叫,它是核心中的**,我們應用層通過系統呼叫,呼叫了系統的函式。
其次,在系統啟動時,已經呼叫sock_init()對socket進行了初始化,在我們呼叫socket函式之前,socket的初始化部分已經為我們的呼叫做好的鋪墊了。
void sock_init(void)
其中 #define nproto 16 /* should be enough for now.. */
pops[i]在初始化時,首先被 for (i = 0; i < nproto; ++i) pops[i] = null; 語句清空,再被proto_init();函式填充上對應的值
void proto_init(void)
/* we're all done... */
}
其中的
while (pro->name != null)
呼叫對應協議的初始化函式,來填充pops[ ]陣列的某一項
具體道tcp/ip協議,(*pro->init_func) (pro)就是 執行了protocols 這個陣列中的inet_proto_init函式來初始化的
struct net_proto protocols = ,
#endif
……
}
inet_proto_init()函式又呼叫了sock_registe()函式來註冊
sock_register又被inet_proto_init()函式呼叫,用於把陣列的指標記錄到pops[ ] 全域性變數中
int sock_register(int family, struct proto_ops *ops)
int sock_register(int family, struct proto_ops *ops)
sti();
return(-enomem);
}
pops[i] = ops;就是初始化pops [ ] 全域性陣列的地方了,其中,net_proto_ops定義如下
static struct proto_ops inet_proto_ops = ;
其實就是定義了一堆函式,並用這些函式來初始化陣列,將來使用這個函式來完成具體的任務。
回過頭看,socket初始化所做的事,就是把各個協議所對應的操作集登記在乙個全域性陣列中,為我們後面的應用程式呼叫socket()建立套接字做好準備,因為我們在使用static int sock_socket(int family, int type, int protocol)函式建立套接字時,通過int family這個引數,指定了所需要的協議,通過這個協議,就能掃瞄pops [ ]全域性資料,找到這個陣列中的對應的函式來完成我們的工作。
網路協議棧1 socket函式呼叫之前
client 中,第乙個被呼叫的函式是socket 在這個函式被呼叫之前,系統做了什麼事情,讓socket 可以正常呼叫?首先,socket函式實際上是乙個系統呼叫,它是核心中的 我們應用層通過系統呼叫,呼叫了系統的函式。其次,在系統啟動時,已經呼叫sock init 對socket進行了初始化,在...
1 Socket程式設計 網路協議一
我們在傳輸資料時,可以只使用 傳輸層 tcp ip協議,但是那樣的話,如果沒有應用層,便無法識別資料內容 tcp ip只是乙個協議棧,就像程式執行一樣,必須要實現執行,同時還要提供對外的操作介面 網路從下往上分為物理層 資料鏈路層 網路層 傳輸層 會話層 表示層和應用層。ip協議對應於網路層,tcp...
1 Socket網路程式設計
1.借助伺服器實現小寫轉大寫的程式 客戶端 傳送任意小寫字母到伺服器端。伺服器端 接收小寫字母,轉為大寫,回傳給客戶端,然後客戶端顯示到螢幕。結構體struct sockaddr in的標頭檔案 include toupper 函式標頭檔案 define serv ip 127.0.0.1 ip位址...