關於網絡編程中一些常用函數的理解

自以爲對於UDP,TCP的理解還算深刻,但是具體到使用的時候還是經常犯糊塗,現在再梳理梳理。

在網絡編程中,用到的一些函數有:socket,bind,listen,accept,connect,send,sendto,recv,recvfrom等。
socket()用於創建一個套接字。
bind()將套接字和本地地址結構綁定。
listen()將套接字設置爲監聽狀態。
connect()用於向另一端發送連接請求。
accept()用於接受另一端的連接請求。
send(),sendto()用於向對端發送數據。
recv(),recvfrom()用於接收對端發來的數據。
在網絡上通訊的兩個程序中,一般都是一方扮演服務者的角色,一方扮演客戶的角色。服務器一般首先通過socket()函數創建一個套接字,然後通過bind()函數將該套接字和本地地址(協議,地址,端口等信息的集合)進行綁定,綁定的目的在於通知操作系統,應用程序請求關注進入本地主機某個網絡接口上的某個端口的數據包:若有滿足這個條件的數據包,請交給我處理。例如本地主機有兩個網卡AB,IP地址分別爲192.168.1.2/255.255.0.0和192.168.2.2/255.255.0.0,某應用程序需要接收來自A網卡,目的端口爲8888的數據包,那麼應用程序可以將IP 192.168.1.2,端口8888的地址信息和套接字綁定。當網卡A接收到一個目的端口爲8888的數據包時,它就會交給應用程序來處理。
上述操作僅僅是將套接字和地址信息綁定,內核並沒有執行真正的接收數據包並提交的操作,這個操作要等到用戶調用了listen()函數時才發生。listen()將使內核執行真正的”監聽操作”, 接下來當有一個來自網絡的連接請求時,內核將該連接請求交給應用程序,應用程序可以調用accept()函數來接受這個連接請求。
accept()原型如下:
這裏寫圖片描述

該函數在沒有連接請求時默認進入阻塞狀態,直到有連接請求。該函數調用返回後,將會有一個來自對端的地址信息被保存在addr中,並且返回一個套接字,在以後的操作中,應用程序就可以通過這個套接字和地址信息與對端進行通訊,而原來的套接字則可以繼續進行監聽操作。通常socket(),bind(),listen(),accept()是服務端程序都需要進行操作,而作爲客戶端,則執行socket(),connect()之後,就可以通訊了。
socket()同樣用於產生一個套接字,connect()函數是比較神奇的,原型如下:
這裏寫圖片描述
對於TCP它將向參數中指定的遠程服務器發出連接請求,若對端服務器調用了accept()接受了連接請求(完成TCP3次握手)之後,雙發就可以調用send(),sendto(),recv(),recvfrom()來進行數據的收發了。

recv(),recvfrom()與send() ,sendto()的區別在於,sendto(),recvfrom()可以指定地址,即,sendto()每次發送時可以指定一個目的地址,recvfrom()可以獲得來自對端的地址信息。
這也引發一個問題,就是TCP和UDP編程時,使用這些函數的差別。
當對方地址已知,並且和套接字建立了聯繫之後,就可以直接調用send()函數,當對方地址已知但是沒有和套接字綁定時,可以sendto()的參數來指定對方地址。
recv()和recvfrom()區別在於,recv()只接收特定地址的數據包,因爲在這之前,地址和套接字已經通過某些方式關聯在一起了,如accept(),connect()函數,accept已經得到了對端的地址,並且和套接字綁定在一起,connect()把目的地址和本地的套接字綁定在一起,雙方的通訊可以建立在已經形成的綁定關係上,所以發送時無需再指定地址,接收時也僅僅接收來自與該套接字綁定地址相同的數據包。

綜上所述:
bind()就是用來把套接字和地址信息綁定的,一般服務器使用來設置原地址和端口,以表明在哪一個端口提供服務,該端口是應該要告知客戶端的,如果不設置,那麼就又內核自動分配,此時服務器也可以進入監聽或接收狀態,這樣客戶端是無法知道這個端口號,從而無法連接或發送數據到這個端口。客戶端也可以用來設置自己的原地址和端口(一般都不使用,僅由內核自動提供動態端口,因爲服務器不關心客戶端的端口是多少)。
connect()是客戶端用來設置目的地址,TCP和UDP使用的效果有所不一樣,TCP設置目的地址之後就開始發送連接請求,進行3次握手,UDP僅僅是設置目的地址,因爲UDP是無連接的,無需三次握手。服務器無需使用。 UDP調用了connect()之後,也可以使用recv(),send(), 或者recvfrom(),sendto()相應地址參數可以設置爲NULL。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章