1. 程式人生 > >linux IPC socket

linux IPC socket

函數 strerror size 網絡字節序 getname truct 數據 and net

套接字是通訊端點的抽象

創建一個套接字

#include <sys/types.h>
#include <sys/socket.h>

int socket(int domain, int type, int protocol);
返回值:成功文件(套接字)描述符,失敗-1
domain:即協議域,又稱為協議族(family)。常用的協議族有,AF_INET、AF_INET6、AF_LOCAL(或稱AF_UNIX,Unix域socket)、AF_ROUTE等等。 協議族決定了socket的地址類型,在通信中必須采用對應的地址,如AF_INET決定了要用ipv4地址(32位的)與端口號(16位的)的組合、AF_UNIX決定了要用一個絕對路徑名作為地址。 type:指定socket類型。常用的socket類型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等(socket的類型有哪些?)。 protocal:故名思意,就是指定協議。常用的協議有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等 它們分別對應TCP傳輸協議、UDP傳輸協議、STCP傳輸協議、TIPC傳輸協議。

套接字通信是雙向的。可以禁止一個套接字的I/O

#include <sys/socket.h>

int shutdown(int sockfd, int how);
返回值:成功0,出錯-1
sockfd:套接字的描述符
how:三種SHUT_RD(0)關閉sockfd上的讀功能
SHUT_WR(1)關閉sockfd上的寫功能
SHUT_RDWR(2)關閉sockfd的讀寫功能

用來在處理器字節序和網絡字節序之間實施轉換的函數

#include <arpa/inet.h>

uint32_t htonl(uint32_t hostlong);
返回值:以網絡字節序表示的32位整數 uint16_t htons(uint16_t hostshort);
返回值:以網絡字節序表示的16位整數
uint32_t ntohl(uint32_t netlong);
返回值:以主機字節序表示的32位整數
uint16_t ntohs(uint16_t netshort);
返回值:以主機字節序表示的16位整數

h表示主機字節序,n表示網絡字節序,l表示長整型,s表示短整型

打印出能被人理解而不是計算機所理解的地址格式。同時支持IPv4和IPv6地址

#include <arpa/inet.h>

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
返回值:成功地址字符串指針,出錯NULL
af:地址簇,僅支持AF_INET和AF_INET6
src:來源地址結構指針
dst:接收轉換後的字符串
size:保存文本字符串的緩沖區大小

int inet_pton(int af, const
char *src, void *dst); 返回值:成功1,格式無效0,出錯-1 af:地址簇,僅支持AF_INET和AF_INET6 src:轉換的地址字符串 dst:轉換後的地址結構指針

找到給定計算機系統的主機信息

#include <netdb.h>

struct hostent *gethostent(void);
返回值:成功返回指針,出錯NULL

void sethostent(int stayopen);
stayopen:true就是TCP,否則UDP
void endhostent(void);

能夠采用一套相似的接口來獲得網絡名字和網絡編號

#include <netdb.h>

struct netent *getnetbyaddr(uint32_t net, int type);
struct netent *getnetbyname(const char *name);
struct netent *getnetent(void);
返回值:成功返回指針,出錯NULL

void setnetent(int stayopen);
void endnetent(void);

在協議名字和協議編號之間進行映射

#include <netdb.h>

struct protoent *getprottobyname(const char *name);
struct protoent *getprotobynumber(int proto);
struct protoent *getprotoent(void);
返回值:成功返回指針,出錯NULL

void setprotoent(int stayopen);
void endprotoent(void);

服務是由地址的端口號部分表示的,每個服務由一個唯一的眾所周知的端口號來支持。可以使用getservbyname將一個服務名映射到一個端口號,使用函數getservbyport將一個端口號映射到一個服務名,使用函數getservent順序掃描服務數據庫。

#include <netdb.h>

struct servent *getservbyname(const char *name, const char *proto);
struct servent *getservbyport(int port, const char *proto);
struct servent *getservent(void);
返回值:成功返回指針,出錯NULL

void setservent(int stayopen);
void endservent(void);

將一個主機和一個服務名映射到一個地址

#include <sys/socket.h>
#include <netdb.h>

int getaddrinfo(const char *node, const char *service,
                        const struct addrinfo *hints,
                        struct addrinfo **res);
返回值:成功0,出錯非0錯誤碼

void freeaddrinfo(struct addrinfo *res);

addrinfo結構體

struct addrinfo
{ 
    int ai_flags; 
    int ai_family; //AF_INET,AF_INET6,UNIX etc
    int ai_socktype; //STREAM,DATAGRAM,RAW
    int ai_protocol; //IPPROTO_IP, IPPROTO_IPV4, IPPROTO_IPV6 etc
    size_t ai_addrlen;//length of ai_addr
    char* ai_canonname; //full hostname 
    struct sockaddr* ai_addr; //addr of host
    struct addrinfo* ai_next;
}

錯誤碼需要調用函數來轉換成錯誤消息

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

const char *gai_strerror(int errcode);

將一個地址轉換成一個額主機名和一個服務名

#include <sys/socke.h>
#include <netdb.h>

int getnameinfo(const struct sockaddr *sa, socklen_t salen,
                        char *host, socklen_t hostlen,
                        char *serv, socklen_t servlen, int flags);

sockaddr結構體

struct sockaddr
{
    __SOCKADDR_COMMON (sa_);    /* Common data: address family and length.  協議族*/
    char sa_data[14];         /* Address data.  地址+端口號*/
};

linux IPC socket