使用VS2008作為編輯器編輯的。如下:
/* 值-結果參數(value-result),調用時進程傳遞核心一個值,返回時核心告訴進程一個結果 從進程到核心(socklen_t addrlen):bind、connect、sendto 從核心到進程(socklen_t *addrlen):accept、recvfrom、getsockname、getpeername 大端位元組序,大端模式:高低低高,與小端模式相反(SPARC、linux為大端模式,其它有待驗證) 小端位元組序,小端模式:高高低低,高地址存高位元組,低地址存低地址。(具體處理器使用何種模式,依據手冊。一般IA體繫結構為小端模式。其它有待驗證) -----注意:以上關於體繫結構中的定義不確切,應當查明 以上兩種由處理器、或作業系統決定的位元組序稱為主機位元組序。 網路資訊傳輸使用網路位元組序,網際協議使用大端位元組序作為網路位元組序。 */ #include <netinet/in.h> /* h-host, to, n-network, s-short,l-long */ uint16_t htons(uint16_t); uint32_t htonl(uint32_t); uint16_t ntohs(uint16_t); uint32_t ntohl(uint32_t); uint16_t--無符號16位整數,其它類比推理即可 #include <arpa/inet.h> /**下面三個函數,運用在處理IPV4點分十進位串**/ int inet_aton(const char *strptr,struct in_addr *addrptr);//將strptr所指的C字串轉換成一個32位的網路位元組序,並通過指標addrptr儲存。成功1,失敗-1。該函數沒有寫入正式文檔 int_addr_t inet_addr(const char *strptr);//轉換同上,存在問題IP 255.255.255.255不能處理,還有潛在問題。已被廢棄,不述。 char *inet_ntoa(struct in_addr inaddr);//與inet_addr轉換相反,傳回值駐留在靜態記憶體,他是不可重新進入函數 #include <arpa/inet.h> /**下面兩個函數,運用在處理IPV4和IPV6,p-presentation表達,n-numeric數值**/ int inet_pton(int family,const char *strptr,void *addrptr);//轉換strptr字串,addrptr存放二進位結果 const char *inet_ntop(int family,const void *addrptr,char *strptr,size_t len);//數值格式轉換成表達格式,len為目標儲存單元的大小 數值格式:in_addr{}、in6_addr{} 表達格式:點分十進位IPV4,128位IPV6 等價代碼 inet_pton(AF_INET,str,&foo.sin_addr);<=>foo.sin_addr.s_addr = inet_addr(str); char str[INET_ADDRSTRLEN]; ptr = inet_ntop(AF_INET,&foo.sin_addr,str,sizeof(str));<=>inet_ntoa(foo.sin_addr); #include <sys/socket.h> /* family:協議族(協議域/地址族),AF_XXX,eg, AF_INET(IPV4)、AF_INET6(IPV6)、AF_LOCAL(AF_UNIX,unix域協議)、AF_ROUTE(路由通訊端)、AF_KEY(密鑰通訊端) socktype:通訊端類型,eg,SOCK_PACKET(linux資料連結層) SOCK_STREAM(位元組流通訊端,TCP)、SOCK_DGRAM(資料通訊端,UDP)、SOCK_SEQPACKET(有序分組通訊端,SCTP)、SOCK_RAW(原始通訊端,IP) protocol:協議類型常值,eg, 0(選擇給定family和socktype組合的系統預設值,最常用)、IPPROTO_TCP(TCP傳輸協議)、IPPROTO_UDP(UDP傳輸協議)、IPPROTO_SCTP(SCTP傳輸協議) */ int socket(int family,int socktype,int protocol); /*激發三路握手,一般總是又用戶端發起,其異常情況 1.TCP用戶端沒有收到伺服器對SYN分節的ACK分節,逾時重傳SYN分節。最終沒收到ACK,則返回ETIMEDOUT錯誤, 2.TCP客戶收到RST分節,表明伺服器在對應連接埠上沒有進程在等待,即沒有服務。硬性錯誤(hard error)返回ECONNREFUSED錯誤。 RST分節是TCP發生錯誤時發送的一種分解。其產生條件是下列條件之一: 目的地為某連接埠的SYN已到達,然而該連接埠沒有正在監聽的伺服器;TCP想取消一個已有的串連;TCP接收到一個根本不存在的串連上的分節 3.用戶端發出的SYN分節在中間路由器引發了destination unreachable的ICMP錯誤,軟性錯誤。返回EHOSTUNREACH或ENETUNREACH錯誤。 */ int connect(int sockfd,const struct sockaddr *servaddr,socklen_t addrlen); /* 將一個本地協議地址賦予一個通訊端,當一個客戶或者伺服器沒調用bind,當調用connect或listen時, 核心為通訊端選擇一個臨時連接埠,伺服器一般指定其眾所周知連接埠,但是RPC伺服器通常由核心選擇一個臨時連接埠 IPV4通配地址:INADDR_ANY IPV6通配地址:in6addr_any INADDR_ANY_INIT */ int bind(int sockfd,struct sockaddr *myaddr,socklen_t addrlen); /* socket函數建立通訊端時假設它是主動通訊端;listen調用將未串連的通訊端轉換成被動通訊端; TCP狀態:CLOSED——>LISTEN backlog:核心應該為相應通訊端排隊的最大串連個數。核心為監聽通訊端維護兩個隊列, 未完成串連隊列:沒完成三步握手,處在SYN_RCVD狀態 已完成串連隊列:已經完成三步握手,處在ESTABLISHED狀態 兩隊列之和不超過backlog,backlog還有很微妙的地方需要再研究。 */ int listen(int sockfd,int backlog); /* 從已完成隊列頭部返回下一個已完成串連,隊列為空白進程睡眠(假定通訊端位阻塞方式) sockfd稱為監聽通訊端,傳回值稱為已串連通訊端 */ int accept(int sockfd,struct sockaddr *cliaddr,socklen_t *addrlen); int close(int sockfd);//關閉通訊端 /*sockaddr_storage地址結構能夠承載系統支援的任何通訊端地址結構*/ int getsockname(int sockfd,struct sockaddr *localaddr,socklen_t *addrlen);//返回與sockfd通訊端關聯的本地協議地址 int getpeername(int sockfd,struct sockaddr *peeraddr,socklen_t *addrlen);//返回與sockfd通訊端關聯的外地協議地址