如上圖所示的tcp連線的基本過程。一般來說,伺服器先於客戶端執行,伺服器程式執行的基本過程是:
socket()函式建立伺服器段socket。以上是連線建立的過程中伺服器的流程,而客戶端有一些不同:bind()函式進行埠繫結,或者不呼叫bind()函式而在呼叫listen()或者connect()函式時,核心為套介面分配乙個臨時埠。
listen()函式進行監聽。
accept()函式在接受客戶端的連線請求後,建立乙個所謂的已連線socket,這個已連線socket在雙方連線過程中存在,當服務完成之後就被關閉。
同樣的在客戶端建立socket。呼叫connect函式嘗試連線伺服器。如connect失敗,則該套介面不在可用必須關閉,重新呼叫socket()。
#include #include由fork建立的新程序被稱為子程序(child process)。該函式被呼叫一次,但返回兩次。兩次返回的區別是子程序的返回值是0,而父程序的返回值則是新程序(子程序)的程序 id。將子程序id返回給父程序的理由是:因為乙個程序的子程序可以多於乙個,沒有乙個函式使乙個程序可以獲得其所有子程序的程序id。 對子程序來說,之所以fork返回0給它,是因為它隨時可以呼叫getpid()來獲取自己的pid;也可以呼叫getppid()來獲取父程序的id。(程序id 0總是由交換程序使用,所以乙個子程序的程序id不可能為0 )。/*功能:複製程序
引數:無
返回值: 成功: 父程序:返回子程序id
子程序:返回0
失敗: 返回-1
*/pid_t fork(
void);
fork之後,作業系統會複製乙個與父程序完全相同的子程序,雖說是父子關係,但是在作業系統看來,他們更像兄弟關係,這2個程序共享**空間,但是資料空間是互相獨立的,子程序資料空間中的內容是父程序的完整拷貝,指令指標也完全相同,子程序擁有父程序當前執行到的位置(兩程序的程式計數器pc值相同,也就是說,子程序是從fork返回處開始執行的),但有一點不同,如果fork成功,子程序中fork的返回值是0,父程序中fork的返回值是子程序的程序號,如果fork不成功,父程序會返回錯誤。
伺服器在服務多使用者時,可用fork子程序來服務每乙個客戶。併發伺服器的典型過程是:
伺服器建立監聽socket。繫結埠bind()並監聽。
父程序呼叫accept()函式。
fork子程序。此時fork的子程序可以共享之前父程序擁有的所有資源,當然也包括accept返回的已連線socket。
子程序關閉監聽socket。注意:此處子程序關閉的監聽socket是從父程序共享而來,因為子程序要負責自己的任務,不再接納其它。子程序建立之後監聽socket的引用計數為2,那麼此時子程序關閉監聽socket只是讓該socket的引用計數減1,並不會真正關閉,因為父程序還需要使用這個監聽socket。
父程序關閉已連線socket。和監聽socket一樣,此時的已連線socket也只是計數器減1,相當於父程序把連線全權交給了子程序(之前相當於是一對二的關係)。
子程序完成任務。
子程序關閉已連線socket。子程序完成任務之後關閉已連線socket,這時便真正關閉socket了。
Unix網路程式設計學習日記 2
今天繼續探索 unix網路程式設計 的框架。並改善上次的程式 在第一次接觸中,我將error.h標頭檔案分出,但是發現錯誤檢測和輸出大量的存在,因此歸入到common.h中。加入了一些安全包裝函式,就是對於原函式的呼叫並進行錯誤檢查。用新的函式改善了daytimecpcli,並學習伺服器程式dayt...
UNIX網路程式設計
在unix network programming 的 3.7 inet pton and inet ntop functions 中提到中有如下兩個巨集定義 define inet addrstrlen 16 for ipv4 dotted decimal define inet6 addrstr...
unix網路程式設計
任何tcp的實現都需要為msl選擇乙個合適的值,rfc的建議值是2分鐘。分組可能出現迷途,若迷途分組在msl中找到路,造成重複,tcp必須修復 time wait存在的理由 可靠的實現全雙工的連線和終止 考慮最終ack丟失的情況,允許老的重複分組在網路中消逝 tcp的化生身現象,因為time wai...