一、ip位址和埠號
1、ip位址
ip協議有兩個版本, ipv4和ipv6。
ip位址是在ip協議中, 用來標識網路中不同主機的位址;
對於ipv4來說, ip位址是乙個4位元組, 32位的整數; 我們通常也使用 "點分十進位制" 的字串表示ip位址, 例如 192.168.0.1 ;
用點分割的每乙個數字表示乙個位元組, 範圍是 0 - 255。
在ip資料報頭部中, 有兩個ip位址, 分別叫做源ip位址, 和目的ip位址.
但是,我們只有ip位址是不能完成通訊的。
比如我們給別人發訊息, 有了ip位址能夠把訊息傳送到對方的機器上, 但是還需要有乙個其他的標識來區分出, 這個資料要給哪個程式進行解析.
2、埠號
埠號(port)是傳輸層協議的內容。
埠號是乙個2位元組16位的整數;
埠號用來標識乙個程序, 告訴作業系統, 當前的這個資料要交給哪乙個程序來處理;
乙個埠號只能被乙個程序占用。
傳輸層協議(tcp和udp)的資料段中有兩個埠號, 分別叫做源埠號和目的埠號. 就是在描述 "資料是誰發的, 要發給誰";
注意:ip位址 + 埠號能夠標識網路上的某一台主機的某乙個程序;
二、認識傳輸層協議
1、tcp協議
傳輸層協議;
有連線;
可靠傳輸;
面向位元組流
2、udp協議
傳輸層協議;
無連線 ;
不可靠傳輸;
面向資料
三、網路位元組序
我們已經了解過,記憶體中的多位元組資料儲存時,相對於記憶體位址有大端和小端之分
1、傳送主機通常將傳送緩衝區中的資料按記憶體位址從低到高的順序發出;
2、接收主機把從網路上接到的位元組依次儲存在接收緩衝區中,也是按記憶體位址從低到高的順序儲存;
因此,網路資料流的位址應這樣規定:
先發出的資料是低位址,後發出的資料是高位址.
tcp/ip協議規定,網路資料流應採用大端位元組序,即低位址高位元組。
所以, 如果當前傳送主機是小端, 我們就必須先將資料轉成大端; 否則就忽略, 直接傳送。
這些,由系統完成,有相應的
網路位元組序和主機位元組序的轉換函式,來了解一下:
觀察上圖的函式名,很容易理解:
h(host),n(network),l(long),s(short)
舉例說明:
htonl:表示將32位的長整數從主機位元組序轉換為網路位元組序
如果主機是小端位元組序,這些函式將引數做相應的大小端轉換然後返回;
如果主機是大端位元組序,忽略,直接返回。
四、socket程式設計介面
了解完這些基礎知識,我們來看一下socket程式設計需要用到的介面。
1、sockaddr結構體
適用於各種底層網路協議,能夠用一套介面實現任意一種情況的網路程式設計,類似於泛型的一種結構體,用前兩個位元組辨識是哪乙個結構體。
比如:ipv4和ipv6的位址格式定義在netinet/in.h中,ipv4位址用sockaddr_in結構體表示,包括16位位址型別,16位埠號和32位ip位址. ipv4、ipv6位址型別分別定義為常數af_inet、af_inet6.
這樣,只要取得某種sockaddr結構體的首位址,不需要知道具體是哪種型別的sockaddr結構體,就可以根據位址型別字段確定結構體中的內容。
2、socket 常見api
建立 socket 檔案描述符:
引數:domain表示域,當前要使用的協議簇;type表明使用哪種服務(tcp或udp);protocol設定為0
返回值:
成功返回檔案描述符
錯誤返回-1
繫結埠號:
返回值:
接收資料:
回訊息:
五、簡單的udp網路程式
1、首先我們寫好makefile檔案:
phony:all
all:udp_server udp_client
udp_server:udp_server.c
gcc -o $@ $^
udp_client:udp_client.c
gcc -o $@ $^
.phony:clean
clean:
rm -f udp_client udp_server
2、udp_server.c
#include#include#include#include#include#include#includeint startup(const char *ip,int port)
printf("%d\n",sock);
struct sockaddr_in local;
local.sin_family=af_inet;
local.sin_port=htons(port);
local.sin_addr.s_addr=inet_addr(ip);
if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)
return sock;}
void service(int sock)}}
static void usage(const char *proc)
int main(int argc,char *argv)
int sock=startup(argv[1],atoi(argv[2]));//"8080"
service(sock);
return 0;
}
3、udp_client.c
#include#include#include#include#include#include#include#includeint main(int argc,char *argv)
int sock=socket(af_inet,sock_dgram,0);
if(sock<0)
struct sockaddr_in server;
server.sin_family=af_inet;
server.sin_port=htons(atoi(argv[2]));
server.sin_addr.s_addr=inet_addr(argv[1]);
char buf[1024];
struct sockaddr_in peer;
while(1)}}
close(sock);
return 0;
}
UDP網路程式設計套接字
ip協議有兩個版本,乙個是ipv4,乙個是ipv6。ip位址是在ip協議中,用來標識網路中不同的主機的位址。對於ipv4來說,ip位址是乙個4位元組,32位的整數。在資料報頭部的兩個ip位址,乙個叫源ip位址,乙個叫目的ip位址 埠號port 必須是眾所周知的,並且不能隨意修改 埠號是乙個2個位元組...
網路程式設計套接字(3) 簡單的UDP網路程式
include include include include include includevoid service int sock int main int argc,char argv int sock socket af inet,sock dgram,0 if sock 0 struct...
網路套接字程式設計介紹 UDP通訊
知識內容 1.udp通訊程式設計流程 2.套接字介面介紹 一 udp通訊程式設計 1.建立套接字 在核心中建立乙個socket結構體,返回乙個檔案描述符作為操作控制代碼,用於使程序與網絡卡之間建立聯絡 2.為套接字繫結位址資訊 在核心的socket結構體中新增描述資訊 位址資訊 告訴作業系統自己使用...