UNP-UNIX網絡編程 第三章:套接字編程簡介

1.IPV4套接字地址結構:

#include <netinet/in.h>
struct in_addr {
    in_addr_t s_addr; //32bit
}
struct sockaddr_in {
    uint8_t        sin_len;        //
    sa_family_t    sin_family;     //AF_INET
    in_port_t      sin_port;       //16bit
    struct in_addr sin_addr;
    char           sin_zero[8];
}

2.IPv6套接字地址結構:

#include <netinet/in.h>
struct in6_addr {
    unit8_t s6_addr[16];
}

struct sockaddr_in6 {
    uint8_t          sin6_len;
    sa_family_t      sin6_family;
    in_port_t        sin6_port;
    uint32_t         sin6_flowinfo;
    struct in6_addr  sin6_addr;
    uint32_t         sin6_scope_id;
}

3.通用套接字地址結構:

#include <sys/socket.h>

struct sockaddr {
    uint8_t      sa_len;
    sa_family_t  sa_family;
    char         sa_data[14]; //protocol-specific address
}
//很多方法中都是使用sockaddr
bind(socked,(struct sockaddr*) &serv,sizeof(serv));

4.新的通用套接字地址結構:

#include <netinet/in.h>
/*
sockaddr_storage能夠滿足最苛刻的對齊要求。
sockaddr_storage足夠大,能夠滿足系統支持的任何套接字地址結構。
sockaddr_storage中除了ss_len和ss_family之外,其他字段對用戶來說是透明的。sockaddr_storage結構必須強制轉換成或複製到適合於ss_family的套接字地址結構中,才能訪問其他字段。
*/
struck sockaddr_storage {
    uint8_t ss_len;
    sa_family_t  ss_family;
    /*
    用戶透明內容
    */
}

5.頭文件:

int8_t          <sys/types.h>
uint8_t         <sys/types.h>
int16_t         <sys/types.h>
uint16_t        <sys/types.h>
int32_t         <sys/types.h>
uint32_t        <sys/types.h>
sa_family_t     <sys/socket.h>
socklen_t       <sys/socket.h>
in_addr_t       <netinet/in.h>
in_port_t       <netinet/in.h>

6.值-結果參數

參數爲指針,可以兩個方向互相傳值,通俗一點的理解就是:參數既做value輸入,又做result返回。
就是該參數既是輸入參數也是輸出參數,相應函數有,accept、recvfrom、getsockname 和 getpeername
struct sockaddr_un cli;
socklen_t len;
len = sizeof(cli);
getpeername(unixfd, (SA*) &cli, &len )
參數有:
select函數中間的3個參數
getsockopt函數的長度參數
msghdr結構中的msg_namelen和msg_controllen字段(recvmsg函數使用)
ifconf結構中的ifc_len字段
sysctl函數兩個長的參數中的第一個

7.字節序

字節值的低序位存儲在內存起始地址叫小端字節序。
字節值的高序位存儲在內存起始地址叫大端字節序。
網絡協議使用大端字節序。

8.函數

#include <strings.h>
void bzero(void *dest, size_t nbytes);//字節操縱函數,指定數目字節置爲0;
void bcopy(void *src, void *dest, size_t nbytes);//指定數目字節從源到目標串
int bcmp(const void *ptr1, const void *ptr2, size_t nbytes);//比較任意字節穿,相等返回0,否則返回非0
//將字符串形式的ip地址與網絡字節序的二進制(存放在套接字地址結構中的值)之間轉換
#include <arpa/inet.h>//成功返回1,若輸入不是有效的表達式格式返回0
int inet_aton(const char *strptr, struct in_addr *addrptr);//得到二進制;strptr->addrptr
char *inet_ntoa(struct in_addr inaddr);//得到十進制
//上面三個只適用於IPv4,下面兩個同時適用於IPv4和IPv6
//成功返回1,若輸入不是有效的表達式格式返回0,若出錯返回-1,strptr->addrptr
int inet_pton(int family, const char *strptr, void *addr);
//若成功返回指向結果的指針,若出錯返回NULL;addrptr->strptr
int inet_ntop(int family ,const void *addr, char *strprt, size_t len);
#include <unistd.h>
//返回讀出的字節數,0表示連接已經關閉?,負數表示出錯(一般需要判斷errno是否是中斷EINTR)
ssize_t read(int fd,void *buf,size_t nbytes);
//返回寫入的字節數,負數表示出錯(一般需要判斷errno是否是中斷EINTR)
ssize_t write(int fd,const void *buf,size_t nbytes)
//
ssize_t readline(int fd,void *buf,size_t maxlen);

read和write存在緩衝區溢出的問題,改進爲readn、written、readline函數,避免讓調用者處理不足的字節計數值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章