1. 程式人生 > 其它 >第13章學習筆記

第13章學習筆記

一、概述

本章論述了TCP/IP和網路程式設計,分為兩個部分。第一部分論述了TCP/IP協議及其應用,具體包括TCP/IP棧、IP地址、主機名、DNS、IP資料包和路由器;介紹了TCP/P網路中的UDP和TCP協議、埠號和資料流;闡述了伺服器-客戶機計算模型和套接字程式設計介面;通過使用UDP和TCP套接字的示例演示了網路程式設計。第一個程式設計專案可實現一對通過網際網路執行檔案操作的TCP伺服器–客戶機,可讓使用者定義其他通訊協議來可靠地傳輸檔案內容。
本章的第二部分介紹了Web和CGI程式設計,解釋了HTTP程式設計模型、Web頁面和Web瀏覽器;展示瞭如何配置Linux HTTPD伺服器來支援使用者Web頁面、PHP和CGI程式設計;闡釋了客戶機和伺服器端動態Web頁面;演示瞭如何使用PHP和CGI建立伺服器端動態Web頁面。

二、學到了什麼

1.TCP/IP協議

TCP/IP(Comer 1988,2001;RFC1180 1991)是網際網路的基礎。TCP代表傳輸控制協議。IP 代表網際網路協議。目前有兩個版本的IP,即IPv4和IPv6。IPv4使用32位地址,IPv6則使用128位地址。本節圍繞IPv4 進行討論,它仍然是目前使用最多的IP版本。TCP/IP 的組織結構分為幾個層級,通常稱為TCP/IP堆疊。如圖所示為 TCP/IP 的各個層級以及每一層級的代表性元件及其功能。

2.IP協議:

用於在IP主機之間傳送/接收資料包。IP盡最大努力執行。IP主機只向接收主機發送資料包,但它不能保證資料包會被髮送到它們的目的地,也不能保證按順序傳送。

3.IP資料包:

由IP頭、傳送方地址和接收方I地址以及資料組成。每個資料包的大小最大為64KB。IP頭包含有關資料包的更多資訊,例如資料包的總長度、資料包使用TCP還是UDP、生存時間(TTL)計數、錯誤檢測的校驗和等。

4.UDP/TCP

UDP(使用者資料報協議)
在IP上執行,用於傳送/接收資料報。與IP類似,UDP不能保證可靠性,但是快速高效。它可用於可靠性不重要的情況。

TCP(傳輸控制協議)
是一種面向連線的協議,用於傳送/接收資料流。TCP也可在IP 上執行,但它保證了可靠的資料傳輸。通常,UDP類似於傳送郵件的USPS,而TCP類似於電話連線。

5.埠編號:
埠號是分配給應用程式的唯一無符號短整數。要想使用UDP或TCP,應用程式(程序)必須先選擇或獲取一個埠號。前1024個埠號已被預留。其他埠號可供一般使用。應用程式可以選擇一個可用埠號,也可以讓作業系統核心分配埠號。

6.網路和主機位元組序:
計算機可以使用大端位元組序,也可以使用小端位元組序。在網際網路上,資料始終按網路序排列,這是大端。在小端機器上,例如基於Intel x86的PC,htons()、htonl()、ntohs()、ntohl()等庫函式,可在主機序和網路序之間轉換資料。例如,PC中的埠號1234按主機位元組序(小端)是無符號短整數。必須先通過htons(1234)把它轉換成網路序,才能使用。相反,從網際網路收到的埠號必須先通過ntohs(port)轉換為主機序。

7.TCP/Ip網路中的資料流

8.網路程式設計

伺服器 — 客戶機計算模型

在伺服器 — 客戶機計算模型中,我們首先在伺服器主機上執行伺服器程序。然後,我們從客戶主機執行客戶及。在UDP中,伺服器等待來自客戶機的戶籍包,處理資料包並生成對客戶及的相應。在TCP中,伺服器等待客戶機連線。客戶機首先連線到伺服器,在客戶機和伺服器之間建立一個虛擬電路。

9. 套接字地址

建立套接字的函式 socket 的三個引數的含義:
domain:使用的協議族。一般只會用到 PF_INET,即 IPv4 協議族。
type:套接字型別,即套接字的資料傳輸方式。主要是兩種:SOCK_STREAM(即 TCP)和 SOCK_(即 UDP)。
protocol:選擇的協議。一般情況前兩個引數確定後,protocol 也就確定了,所以設為 0 即可。

10.套接字型別
同一個協議族可能有多種資料傳輸方式,因此在指定了 socket 的第一個引數後,還要指定第二個引數 type。

SOCK_STREAM 代表的是 TCP 協議,會建立面向連線的套接字,有如下特點:
1.可靠傳輸,傳輸的資料不會消失。
2.按序傳輸。
3.傳輸的資料沒有邊界:從面向連線的位元組流角度理解。接收方收到資料後放到接收快取中,使用者使用 read 函式像讀取位元組流一樣從中讀取資料,因此傳送方 write 的次數和接收方 read 的次數可以不一樣

11.主機名和IP地址

如果打算在不同的主機上執行伺服器和客戶機,伺服器埠號由作業系統核心分配,則需要 知道伺服器的主機名或IP地址及其埠號。如果某臺計算機執行TCP/IP,他的主機名通常記錄在/etc/hosts/檔案中。庫函式

gethostname(char *name,sizeof(name))

在name陣列中返回計算機的主機名字串。但是他可能不是用點記法表示的完整正式名稱,也不是其IP地址。庫函式

struct hostent *gethostbyname(void addr,socklen_t len,int typo) //用來獲取計算機全名及其IP地址。

三、實踐

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <time.h>

#include <string.h>

#include <unistd.h>

#define MAXLINE 256

#define PORT 7777

void sys_err(char *msg){

perror(msg);

exit(-1);

}

int main(int argc , char **argv){

int sockFd,n;

char recvLine[MAXLINE];

struct sockaddr_in servAddr;

if (argc != 2) {

sys_err("usage: a.out <IPaddress>");

}

sockFd=socket(AF_INET,SOCK_STREAM,0);

memset(&servAddr,0,sizeof(servAddr));

servAddr.sin_family = AF_INET;

servAddr.sin_port = htons(PORT);

if (inet_pton(AF_INET,argv[1],&servAddr.sin_addr) <= 0) {

sys_err("inet_pton error");

}

connect(sockFd,(struct sockaddr *)&servAddr,sizeof(servAddr));

while((n=read(sockFd,recvLine,MAXLINE)) >0 ){

recvLine[n] = '\0';

if(fputs(recvLine,stdout) == EOF){

sys_err("fputs error");

}

}

if(n <0){

sys_err("read error");

}

return 0;

}