《TCP/IP網絡編程》第4章 基於TCP的服務器端/客戶端(1)

4.1 理解TCP和UDP

    TCP是TransmissionControl Protocol(傳輸控制協議)的簡寫。

    以多個標準爲依據設計的系統稱爲開放式系統。

    TCP和UDP層以IP層提供的路徑信息爲基礎完成實際的數據傳輸,故該層又稱傳輸層(Transport)。

    IP層是面向消息的、不可靠的協議。只關注1個數據包(數據傳輸的基本單位)的傳輸過程。若只利用IP層傳輸數據,則有可能導致數據丟失或者數據包收、發順序不一致。TCP和UDP存在於IP層之上,決定主機之間的數據傳輸方式。

    編寫軟件的過程中,需要根據程序特點決定服務器和客戶端之間的數據傳輸規則(規定),這便是應用層協議。網絡編程的大部分內容就是設計並實現應用層協議。

4.2 實現基於TCP的服務器端/客戶端

1.       TCP端的默認函數調用順序

    進入等待連接請求狀態:

#include <sys/socket.h>
int listen(int sock, int backlog);

-sock: 希望進入等待連接請求狀態的套接字文件描述符,傳遞的描述符套接字參數成爲服務器端套接字(監聽套接字)

-backlog: 連接請求等待隊列(Queue)的長度,若爲5,則隊列長度爲5,表示最多使5個連接請求進入隊列;連接請求隊列的大小始終根據實驗結果而定。


    受理客戶端連接請求:

#include<sys/socket.h>
int accept(int sock, struct sockaddr *addr, socklen_t *addrlen);

    -sock: 服務器套接字的文件描述符;

    -addr: 保存發起連接的客戶端地址信息的變量地址值,調用函數後向傳遞來的地址變量參數填充客戶端地址信息

    -addrlen: 第二個參數addr的長度,注意是該參數是指針變量,應傳入長度變量的地址;

    accept函數受理連接請求等待隊列中待處理的客戶端連接請求。函數調用成功後,accept函數內部將產生用於數據I/O的套接字,並返回其文件描述符。

    另外,調用accept函數時,若等待隊列爲空,則accept函數不會返回,直到隊列中出現新的客戶端連接。

2.       TCP客戶端的默認函數調用順序

    與服務器端相比,區別就在於“請求連接”,服務器端調用listen函數後創建連接請求等待隊列,之後客戶端即可請求連接。

#include <sys/socket.h>
int connect(int sock, struct sockaddr*servaddr, socklen_t addrlen);

    -sock: 客戶端套接字文件描述符;

    -servaddr: 保存目標服務器端地址信息的變量地址值;

    -addrlen: 以字節爲單位傳遞已傳遞給第二個結構體參數servaddr的地址變量長度;

    客戶端調用connect函數後,發生以下情況之一纔會返回:

    A.服務器端接收連接請求(服務器端將請求消息記錄到等待隊列),因此,connect函數返回後並不立即進行數據交換;

    B.發生斷網等異常情況而中斷連接請求;

    網絡數據交換必須分配IP和端口,客戶端的IP地址和端口在調用connect函數時自動分配(操作系統,內核),端口號隨機分配,無需調用標記的bind函數進行分配。

3.       基於TCP的服務器端/客戶端函數調用關係

4.3 實現迭代服務器端/客戶端

1.       迭代回聲服務器端/客戶端

    程序運行方式:

    服務器端在同一時刻只與一個客戶端相連,並提供回聲服務;

    服務器端依次爲5個客戶端連接提供服務並退出;

    客戶端接收用戶輸入的字符串併發送到服務器端;

    服務器端將接收的字符串數據傳回客戶端,即“回聲”;、

    服務器端與客戶端之間的字符串回聲一直執行到客戶端輸入Q爲止;

    

2.       回聲客戶端存在的問題

    多次調用write函數傳遞的字符串有可能一次性傳遞到服務器端,此時客戶端有可能從服務器端收到多個字符串,這不是希望的結果。

 



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