應用層:應用程序間溝通的層,如簡單電子郵件傳輸(SMTP)、
文件傳輸協議(FTP)、網絡遠程訪問協議(Telnet)等。
傳輸層:在此層中,它提供了節點間的數據傳送,應用程序之間的通訊服務,
主要功能是數據格式化、數據確認和丟失重傳等。
如傳輸控制協議(TCP)、用戶數據報協議(UDP)等,
TCP和UDP給數據包加入傳輸數據並把它傳輸到下一層中,這一層負責傳送數據,
而且肯定數據已被送達並接收。
互連網絡層:負責提供基本的數據封包傳送功能,讓每一塊數據包都可以到達目的主機(但不檢查是否被正確接收),如網際協議(IP)。如ARP是地址解析協議,在這一層的時候吧IP地址轉換爲物理地址
網絡接口層(主機-網絡層):接收IP數據報並進行傳輸,從網絡上接收物理幀,抽取IP數據報轉交給下一層,對實際的網絡媒體的管理,定義如何使用實際網絡(如Ethernet、Serial Line等)來傳送數據。另外補充一下OSI的七層所對應的協議:
應用層(Application):
應用程序網關(application gateway)Telnet: 遠程登陸 (在應用層鏈接兩部分應用程序)
FTP(File Transfer Protocol):文件傳輸協議
HTTP(Hyper Text Transfer Protocol):超文本傳輸協議
SMTP(Simple Mail Transter Protocol):簡單郵件傳輸協議
POP3(Post Office Ptotocol):郵局協議
SNMP(Simple Network Mangement Protocol)簡單網絡管理協議
DNS(Domain Name System):域名系統
傳輸層(Transport):
傳輸網關(transport gateway)
TCP(Transmission Control Potocol):傳輸控制協議
(在傳輸層鏈接兩個網絡)
UDP(User Data Potocol):用戶數據協議
網絡層(Internet):
多協議路由器(multiprotocol router)
IP(Internet Protocol):網絡協議 (在異構網絡間轉發分組)
ARP(Address Resolution Protocol):地址解析協議
RARP(Reverse Address Resolution Protocol) :逆地址解析協議
ICMP(Internet Control Message Protocol):因特網控制消息協議
IGMP(Internet Group Manage Protocol):因特網組管理協議
BOOTP (Bootstrap):可選安全啓動協議
數據鏈路層(Data Link):
網橋(bridge)交換機(switcher)
HDLC(High Data Link Control):高級數據鏈路控制 (在LAN之間存儲-轉發數據鏈路針)
SLIP(Serial Line IP):串行線路IP
PPP(Point-to-Point Protocol):點到點協議802.2等
物理層(Physical):
中繼器(repeater) 集線器(hub)
(放大或再生弱的信號,在兩個電纜段之間複製每個比特)
再回過頭來看,ftp是用tcp寫的一個文件傳輸協議,明顯就是在應用層了
====================================================================
2.在網絡應用中,函數htons,htonl,ntohs,ntohl的做用?
htons: 把短整型的主機字節順序轉變爲網絡字節順序
其它依次類推
htons通常用來轉變端口,htonl通常用來轉IP
網絡字節順序是先高位字節,再低位字節;主機字節順序則視cpu而定
乾脆擴展一點
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<
string.h>
#include<netinet/
in.h>
#include<sys/socket.h>
#include<sys/types.h>
int main()
{
char str[]=
"255.255.255.255";
in_addr_t r1,r2,r3;
struct in_addr inp;
r1=inet_addr(str);
if(r1==-1)
{
printf(
"inet_addr return -1 when 255.255.255.255\n");
}
else
{
printf(
"inet_addr:ip=%lu\n",ntohl(r1));
}
r2=inet_network(str);
if(r2==-1)
{
printf(
"inet_network return -1 when 255.255.255.255\n");
}
else
{
printf(
"inet_network:ip=%lu\n",r2);
}
r3=inet_aton(str,&inp);
if(r3==0)
{
printf(
"inet_aton return -1 when 255.255.255.255\n");
}
else
{
printf(
"inet_aton:ip=%lu\n",ntohl(inp.s_addr));
}
return 0;
}
====================================================================
3.在c語言中,static函數與普通函數有什麼區別?
1. 全局靜態變量
在全局變量以前加上關鍵字static,全局變量就被定義成爲一個全局靜態變量。
1)內存中的位置:靜態存儲區(靜態存儲區在整個程序運行期間都存在)。
2)初始化:未經初始化的全局靜態變量會被程序自動初始化爲0(自動對象的值是任意的,除非他被顯示初始化)。
3)做用域:全局靜態變量在聲明他的文件以外是不可見的。準確地講從定義之處開始到文件結尾。
定義全局靜態變量的好處:
<1>不會被其餘文件所訪問,修改。
<2>其餘文件中能夠使用相同名字的變量,不會發生衝突。
2. 局部靜態變量
在局部變量以前加上關鍵字static,局部變量就被定義成爲一個局部靜態變量。
1)內存中的位置:靜態存儲區。
2)初始化:未經初始化的全局靜態變量會被程序自動初始化爲0(自動對象的值是任意的,除非他被顯示初始化)。
3)做用域:做用域仍爲局部做用域,當定義它的函數或者語句塊結束的時候,做用域隨之結束。
注:當static用來修飾局部變量的時候,它就改變了局部變量的存儲位置,從原來的棧中存放改成靜態存儲區。考試,大提示局部靜態變量在離開做用域以後,並無被銷燬,而是仍然駐留在內存當中,直到程序結束,只不過咱們不能再對他進行訪問。
當static用來修飾全局變量的時候,它就改變了全局變量的做用域(在聲明他的文件以外是不可見的),可是沒有改變它的存放位置,仍是在靜態存儲區中。
3. 靜態函數
在函數的返回類型前加上關鍵字static,函數就被定義成爲靜態函數。
函數的定義和聲明默認狀況下是extern的,但靜態函數只是在聲明他的文件當中可見,不能被其餘文件所用。
定義靜態函數的好處:
<1> 其餘文件中能夠定義相同名字的函數,不會發生衝突。
<2> 靜態函數不能被其餘文件所用。
存儲說明符auto,register,extern,static,對應兩種存儲期:自動存儲期和靜態存儲期。
auto和register對應自動存儲期。具備自動存儲期的變量在進入聲明該變量的程序塊時被創建,它在該程序塊活動時存在,退出該程序塊時撤銷。
關鍵字extern和static用來講明具備靜態存儲期的變量和函數。用static聲明的局部變量具備靜態存儲持續期(static storage duration),或靜態範圍(static extent)。雖然他的值在函數調用之間保持有效,可是其名字的可視性仍限制在其局部域內。靜態局部對象在程序執行到該對象的聲明處時被首次初始化。
擴展分析:
術語static有着不尋常的歷史.起初,在C中引入關鍵字static是爲了表示退出一個塊後仍然存在的局部變量。隨後,static C中有了第二種含義:用來表示不能被其它文件訪問的全局變量和函數。爲了不引入新的關鍵字,因此仍使用static關鍵字來表示這第二種含義。最後,C++重用了這個關鍵字,並賦予它與前面不一樣的第三種含義:表示屬於一個類而不是屬於此類的任何特定對象的變量和函數(與Java中此關鍵字的含義相同)。
寫個例子,比對一下
#include <stdio.h>
#include <stdlib.h>
extern int a;//聲明
static int b=5;
a=0;//初始化
void func1()
{
printf(
"a=%d;b=%d\n",a,b);
return ;
}
void func2()
{
static int i=333;
i++;
printf(
"i=%d\n",i);
return ;
}
int main()
{
a=20;
func1();
func2();
func2();
return 0;
}
輸出爲:
a=20;b=5
i=334
i=335
總的來講,靜態的東西就是隻在本文件中可見,並且在本文件中保持,它只初始化一次,存在靜態存儲區中,再對它進行初始化不會引發錯誤,可是沒有用了
====================================================================
4.請實現內存複製函數
void memcpy(void *dst,void *src,int size)?
網上搜了一下
void *MyMemCopy(void *dest,
const void *src,size_t count)
{
char *pDest=static_cast<char *>(dest);
const char *pSrc=static_cast<
const char *>(src);
if( pDest>pSrc && pDest<pSrc+count )
{
for(size_t i=count-1; i<=0; ++i)
{
pDest[i]=pSrc[i];
}
}
else
{
for(size_t i=0; i<count; ++i)
{
pDest[i]=pSrc[i];
}
}
return pDest;
}
哎,搞IT真的沒有前途,你看,人都這麼聰明的?!
就這還考慮到了,幸虧,我還不是笨到家,還能看得懂
稍微解釋下:
若是是這個狀況:
src --------------------
dst --------------------------
說明兩個在內存區有重疊的地方。
若是用dst[0]=src[0]
那麼說明src的某塊會被弄髒掉,怎麼辦?從後面拷起就不會有問題,dst[size-1]=src[size-1]
若是沒有重疊的話就從頭拷起
如程序所見