網路程式設計基礎API

2022-08-02 17:24:09 字數 4591 閱讀 5925

網路位元組序

1.tcp/ip協議規定,網路資料流應採用大端位元組序

0x12345678

小端儲存:78儲存在低位址

大端儲存:12儲存在低位址

網路位元組序和主機位元組序的轉換

#include uint32_t htonl(uint32_t hostlong);

uint16_t htons(uint16_t hostshort);

uint32_t ntohl(uint32_t netlong);

uint16_t ntohs(uint16_t netshort);

h表示host,n表示network,l(long)表示32位長整數,s(short)表示16位短整數。

如果主機是小端位元組序,這些函式將引數做相應的大小端轉換然後返回,如果主機是大端位元組序,這些函式不做轉

換,將引數原封不動地返回。

ip位址轉換函式192.168.56.101這就是乙個字串,要把這個字串轉換成32位的ip位址

#include int inet_pton(int af, const char *src, void *dst);

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

支援ipv4和ipv6

可重入函式

1.socket
#include /* see notes */

#include int socket(int domain, int type, int protocol);

domain:

af_inet 這是大多數用來產生socket的協議,使用tcp或udp來傳輸,用ipv4的位址

af_inet6 與上面類似,不過是來用ipv6的位址

af_unix 本地協議,使用在unix和linux系統上,一般都是當客戶端和伺服器在同一臺及其上的時候使用

type:

sock_stream 這個協議是按照順序的、可靠的、資料完整的基於位元組流的連線。這是乙個使用最多的socket類

型,這個socket是使用tcp來進行傳輸。

sock_dgram 這個協議是無連線的、固定長度的傳輸呼叫。該協議是不可靠的,使用udp來進行它的連線。

sock_seqpacket 這個協議是雙線路的、可靠的連線,傳送固定長度的資料報進行傳輸。必須把這個包完整的

接受才能進行讀取。

sock_raw 這個socket型別提供單一的網路訪問,這個socket型別使用icmp公共協議。(ping、traceroute使

用該協議)

sock_rdm 這個型別是很少使用的,在大部分的作業系統上沒有實現,它是提供給資料鏈路層使用,不保證數

據包的順序

protocol:

0 預設協議

返回值:

成功返回乙個新的檔案描述符,失敗返回-1,設定errno

#include /* see notes */

#include int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

sockfd:

socket檔案描述符

addr:

構造出ip位址加埠號

addrlen:

sizeof(addr)長度

返回值:

成功返回0,失敗返回-1, 設定errno

bind函式的第二個引數是由於歷史原因決定的,其實完全可以寫成void*型別,然後根據前16為類決定是哪一類的位址。

servaddr.sin_addr.s_addr = htonl(inaddr_any);//inaddr_any表示本機的任意的ip位址,可能有好幾個網絡卡。

servaddr.sin_port = htons(8000);

首先將整個結構體清零,然後設定位址型別為af_inet,網路位址為inaddr_any,這個巨集表示本地的任意ip位址,因為伺服器可能有多個網絡卡,每個網絡卡也可能繫結多個ip位址,這樣設定可以在所有的ip位址上監聽,直到與某個客戶端建立了連線時才確定下來到底用哪個ip位址,埠號為8000。

#include /* see notes */

#include int listen(int sockfd, int backlog);

sockfd:

socket檔案描述符

backlog:

排隊建立3次握手佇列和剛剛建立3次握手佇列的鏈結數和(核心維護的兩個佇列)

listen函式後面維護了兩個佇列,乙個是完成3次握手的佇列,乙個是未完成3次握手的佇列。,當呼叫accept函式時,就是從已連線的佇列中取出乙個已經完成3次握手的連線。

典型的伺服器程式可以同時服務於多個客戶端,當有客戶端發起連線時,伺服器呼叫的accept()返回並接受這個連線,如果有大量的客戶端發起連線而伺服器來不及處理,尚未accept的客戶端就處於連線等待狀態,listen()宣告sockfd處於監聽狀態,並且最多允許有backlog個客戶端處於連接待狀態,如果接收到更多的連線請求就忽略。listen()成功返回0,失敗返回-1。

#include /* see notes */

#include int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

sockdf:

socket檔案描述符

addr:

addrlen:

傳入傳出引數(值-結果),傳入sizeof(addr)大小,函式返回時返回真正接收到位址結構體的大小

返回值:

成功返回乙個新的socket檔案描述符,專門用於和客戶端通訊,失敗返回-1,設定errno

為什麼要產生新的socket呢原來的socket還要處理請求連線的。

三方握手完成後,伺服器呼叫accept()接受連線,如果伺服器呼叫accept()時還沒有客戶端的連線請求,就阻塞等待直到有客戶端連線上來。addr是乙個傳出引數,accept()返回時傳出客戶端的位址和埠號。addrlen引數是乙個傳入傳出引數(value-resultargument),傳入的是呼叫者提供的緩衝區addr的長度以避免緩衝區溢位問題,傳出的是客戶端位址結構體的實際長度(有可能沒有佔滿呼叫者提供的緩衝區)。如果給addr引數傳null,表示不關心客戶端的位址。

#include /* see notes */

#include int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

sockdf:

socket檔案描述符

addr:

傳入引數,指定伺服器端位址資訊,含ip位址和埠號

addrlen:

傳入引數,傳入sizeof(addr)大小

返回值:

成功返回0,失敗返回-1,設定errno

客戶端需要呼叫connect()連線伺服器,connect和bind的引數形式一致,區別在於bind的引數是自己的位址,而connect的引數是對方的位址。connect()成功回0,出錯返回-1。

server.c

#include #include #include #include #include #include #include #include #include #define err_exit(m) \

do \

while(0)

int main(void)

fputs(recvbuf, stdout);

write(conn, recvbuf, ret);

} close(listenfd);

close(conn);

return 0;

}

client.c

#include #include #include #include #include #include #include #include #include #define err_exit(m) \

do \

while(0)

int main(void)

; while(fgets(sendbuf, sizeof(sendbuf), stdin) != null)

close(sock);

return 0;

}

linux網路程式設計基礎api

socket系統呼叫,成功返回乙個socket檔案描述符,失敗返回 1並設定errno bind命名套接字,成功返回0,失敗返回 1並設定errno listen監聽socket,成功返回0,失敗返回 1並設定errno accept從listen監聽佇列中接受乙個連線,成功返回新的socket,失...

學習筆記 網路程式設計基礎API

linux網路程式設計基礎api與核心內tc ip協議族關係。1.socket位址api ip位址及埠對,代表tcp通訊中的一方,稱為socket位址。socket就像pipe一樣,代表的是乙個檔案描述符。可以用socket 來建立。參考 include see notes include int ...

網路程式設計 常用API

該類用於標識網路上的硬體資源,表示網際網路協議的ip位址 該類沒有構造方法,所以不能直接new出乙個物件,可以通過該類的靜態方法獲得inetaddress的物件 public class ipdemo url 統一資源定位符,表示internet上某一資源的位址 public class urlde...