1、什么是計(jì)算機(jī)網(wǎng)絡(luò)?
多個(gè)計(jì)算機(jī)進(jìn)行通信--->計(jì)算機(jī)網(wǎng)絡(luò)。
2、計(jì)算機(jī)通信的復(fù)雜度
(1)、傳輸信息的復(fù)雜度(種類、內(nèi)容);
(2)、信息的數(shù)量
(3)、傳輸距離(干擾...)
(4)、信息的安全問題
(5)、計(jì)算機(jī)體系的完整性和封閉性。
既要保證計(jì)算機(jī)的封閉性,又要達(dá)成計(jì)算機(jī)的通信。
3、ip地址
(1)、IP地址是有限的,需要一種方式將IP地址復(fù)用。
(2)、IP地址的復(fù)用導(dǎo)致了數(shù)據(jù)傳遞的復(fù)雜性(ATM,存儲(chǔ)轉(zhuǎn)發(fā)機(jī)制;路由機(jī)制)。
(3)、IP地址過于抽象不方便使用,于是給出了IP地址的人文化轉(zhuǎn)義:域名。
(4)、域名只能代表一個(gè)IP網(wǎng)絡(luò)地址,于是就只能代表一個(gè)網(wǎng)絡(luò)上的節(jié)點(diǎn)實(shí)體。
(5)、實(shí)際上訪問節(jié)點(diǎn)的時(shí)候,本質(zhì)上使用的是IP地址,所以就需要將域名轉(zhuǎn)化為IP地址(DNS...)
4、IP地址的分類
(1)、IPv4地址是4字節(jié)的,中間以 . 劃分;IPv6地址是16字節(jié)的;
規(guī)定:在IP地址劃分上,一般不取全0/全1;
IP一般分為5類;
A、B、C、D、E,一般常用的IP地址為A類,B類,C類;
A類IP:第一個(gè)字節(jié)是以0開頭 0000 0000--->0111 1111 0~127
B類IP:第一個(gè)字節(jié)是以10開頭 1000 0000--->1011 1111 128~191
C類IP:第一個(gè)字節(jié)是以110開頭 1100 0000--->1101 1111 192~223
(2)、子網(wǎng)掩碼:就是將網(wǎng)絡(luò)號(hào)設(shè)置為1,主機(jī)號(hào)設(shè)置為0(對(duì)每一個(gè)字節(jié)的位進(jìn)行設(shè)置);
例:C類IP地址,3個(gè)字節(jié)網(wǎng)絡(luò)號(hào)和一個(gè)字節(jié)的主機(jī)號(hào);
1111 1111 1111 1111 1111 1111 0000 0000
255 . 255 . 255 . 0
(3)、子網(wǎng)劃分:此時(shí)就存在C類地址的子網(wǎng)掩碼不一定總是255.255.255.0;
這還的看C類IP下面有沒有子網(wǎng)劃分,
有子網(wǎng)劃分的話,最后一個(gè)字節(jié),也就是主機(jī)號(hào)可能為2段(01/10)、4段(00/01/10/11)
例:192.168.3.11xx xxxx 1111 1111 1111 1111 1111 1111 1100 0000
此時(shí)對(duì)應(yīng)的子網(wǎng)掩碼為:255.255.255.192
(4)、IOS和TCP/IP
模型分析
(5)、端口號(hào)
port:唯一標(biāo)識(shí)應(yīng)用程序的編號(hào);
我們之間通過QQ、微信、郵箱進(jìn)行收發(fā)數(shù)據(jù)時(shí),沒有導(dǎo)致數(shù)據(jù)的錯(cuò)亂接收,是怎么做到的呢?又是怎么一一對(duì)應(yīng)找到的呢?
:通過端口號(hào),識(shí)別了電腦上的某一應(yīng)用程序,也就是找對(duì)應(yīng)的編號(hào)。
我們?cè)谶M(jìn)行數(shù)據(jù)的發(fā)送時(shí):首先通過IP尋找物理計(jì)算機(jī),在根據(jù)port,尋找對(duì)應(yīng)的應(yīng)用程序。
(6)、TCP和UDP
UDP屬于TCP/IP體系中的一部分。
TCP協(xié)議和UDP協(xié)議都屬于傳輸層協(xié)議。
TCP協(xié)議:
i>、面向連接的傳輸協(xié)議、可靠的、同步的;
ii>、面向連接的網(wǎng)絡(luò)傳輸特點(diǎn):a、需要有一方主動(dòng)的建立連接,另一方接收連接請(qǐng)求;b、只有建立了連接之后才能夠進(jìn)行數(shù)據(jù)的傳輸;c、當(dāng)數(shù)據(jù)傳輸完畢之后,就需要釋放連接,由連接的兩端來共同決定連接是否保持。
UDP協(xié)議:
a、面向無連接的:即就是在進(jìn)行數(shù)據(jù)傳輸?shù)臅r(shí)候,不需要預(yù)先創(chuàng)建一個(gè)連接;
b、不可靠的:無法知道發(fā)送的數(shù)據(jù)是否能夠到達(dá)目的,也無法知道什么時(shí)候能夠到達(dá)目的。
c、異步的:
(7)、TCP的三次握手、四次揮手
TCP------->至少3次握手(最后一次防止誤按,2次的話,有可能死鎖); : 打電話模型
模型分析
TCP-------->4次揮手。 模型:男女朋友分手模型
通過IP,只能保證物理上的連通,至于收發(fā)數(shù)據(jù)的形式是什么,都不歸它管。
127.0.0.1:本機(jī)回送地址,可作為測(cè)試本機(jī)使用,不安裝網(wǎng)卡也是可以ping通的。
5、TCP的編程實(shí)現(xiàn)
基礎(chǔ)的socket編程對(duì)TCP的就是下面的步驟:
(1)、模型分析
(2)、代碼實(shí)現(xiàn)
utili.h
#include#include #include #include #include #include #define SERVER_PORT 9090 #define SERVER_IP "127.0.0.1" #define LISTEN_QUEUE 5 #define BUF_SIZE 255
服務(wù)器端代碼:
#include"utili.h" //TCP int main(void){ int sockSer = socket(AF_INET, SOCK_STREAM, 0); if(sockSer == -1){ perror("socket"); return -1; } struct sockaddr_in addrSer, addrCli; addrSer.sin_family = AF_INET; addrSer.sin_port = htons(SERVER_PORT); addrSer.sin_addr.s_addr = inet_addr(SERVER_IP); int yes = 1; setsockopt(sockSer, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); //地址、端口的重用 socklen_t len = sizeof(struct sockaddr); int res = bind(sockSer, (struct sockaddr *)&addrSer, len); if(res == -1){ perror("bind"); close(sockSer); return -1; } res = listen(sockSer, LISTEN_QUEUE); if(res == -1){ perror("listen"); close(sockSer); return -1; } int sockConn; char sendbuf[BUF_SIZE]; char recvbuf[BUF_SIZE]; while(1){ sockConn = accept(sockSer, (struct sockaddr *)&addrCli, &len); if(sockConn == -1){ continue; }else{ printf("Server Accept Client Connect OK\n"); } printf("Ser :>"); scanf("%s", sendbuf); if(strncmp(sendbuf, "quit", 4) == 0) break; send(sockConn, sendbuf, strlen(sendbuf)+1, 0); recv(sockConn, recvbuf, BUF_SIZE, 0); printf("Cli :>%s\n", recvbuf); } close(sockSer); return 0; }
客戶端代碼:
#include"utili.h" //TCP int main(void){ int sockCli = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in addrSer; addrSer.sin_family = AF_INET; addrSer.sin_port = htons(SERVER_PORT); addrSer.sin_addr.s_addr = inet_addr(SERVER_IP); struct sockaddr_in addrCli; addrCli.sin_family = AF_INET; addrCli.sin_port = htons(7070); addrCli.sin_addr.s_addr = inet_addr("192.168.1.155"); int yes = 1; setsockopt(sockCli, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); //地址、端口的重用 socklen_t len = sizeof(struct sockaddr); int res = bind(sockCli, (struct sockaddr *)&addrCli, len); if(res == -1){ perror("bind"); close(sockCli); return -1; } res = connect(sockCli, (struct sockaddr*)&addrSer, len); if(res == -1){ perror("connect"); close(sockCli); return -1; }else{ printf("Client Connect Server ok\n"); } char sendbuf[BUF_SIZE]; char recvbuf[BUF_SIZE]; while(1){ connect(sockCli, (struct sockaddr*)&addrSer, len); recv(sockCli, recvbuf, BUF_SIZE, 0); printf("Ser :>%s\n", recvbuf); printf("Cli :>"); scanf("%s", sendbuf); if(strncmp(sendbuf, "quit", 4) == 0) break; send(sockCli, sendbuf, strlen(sendbuf)+1, 0); } close(sockCli); return 0; }
(3)、運(yùn)行結(jié)果
6、UDP的編程實(shí)現(xiàn)
基礎(chǔ)的socket編程對(duì)UDP的就是下面的步驟:
(1)、模型分析
(2)、代碼實(shí)現(xiàn)
utili.h
#include#include #include #include #include #include #define SERVER_PORT 9090 #define SERVER_IP "127.0.0.1" #define LISTEN_QUEUE 5 #define BUFFER_SIZE 255
服務(wù)器端代碼:
#include"utili.h" int main(){ int sockSer = socket(AF_INET, SOCK_DGRAM, 0); if(sockSer == -1){ perror("socket"); return -1; } struct sockaddr_in addrSer, addrCli; addrSer.sin_family = AF_INET; addrSer.sin_port = htons(SERVER_PORT); addrSer.sin_addr.s_addr = inet_addr(SERVER_IP); socklen_t len = sizeof(struct sockaddr); int res = bind(sockSer, (struct sockaddr*)&addrSer, len); if(res == -1){ perror("bind"); close(sockSer); return -1; } char sendbuf[BUFFER_SIZE]; char recvbuf[BUFFER_SIZE]; while(1){ recvfrom(sockSer, recvbuf, BUFFER_SIZE, 0, (struct sockaddr*)&addrCli, &len); printf("Cli:>%s\n",recvbuf); printf("Ser:>"); scanf("%s",sendbuf); if(strncmp(sendbuf, "quit", 4) == 0){ break; } sendto(sockSer, sendbuf, strlen(sendbuf)+1, 0, (struct sockaddr*)&addrCli, len); } close(sockSer); return 0; }
客戶端代碼:
#include"utili.h" int main(){ int sockCli = socket(AF_INET, SOCK_DGRAM, 0); if(sockCli == -1){ perror("socket"); return -1; } struct sockaddr_in addrSer; addrSer.sin_family = AF_INET; addrSer.sin_port = htons(SERVER_PORT); addrSer.sin_addr.s_addr = inet_addr(SERVER_IP); char sendbuf[BUFFER_SIZE]; char recvbuf[BUFFER_SIZE]; socklen_t len = sizeof(struct sockaddr); while(1){ printf("Cli:>"); scanf("%s",sendbuf); if(strncmp(sendbuf, "quit", 4) == 0){ break; } sendto(sockCli, sendbuf, strlen(sendbuf)+1, 0, (struct sockaddr*)&addrSer, len); recvfrom(sockCli, recvbuf, BUFFER_SIZE, 0, (struct sockaddr*)&addrSer, &len); printf("Ser:>%s\n",recvbuf); } close(sockCli); return 0; }
(3)、運(yùn)行結(jié)果
服務(wù)器端截圖
客戶端截圖
服務(wù)端的套接字總領(lǐng)全局,不與任何客戶端進(jìn)行通信,為每一個(gè)新的客戶端所分配一個(gè)新的套接字,進(jìn)行通信。
LISTEN_QUEUE:等待隊(duì)列的大小(最多等待多少隊(duì)列);
UDP:必須先知道服務(wù)器在哪。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。