网络IPC:套字节
1.套字节描述符和文件描述符对比。
1.1使用套字节描述符访问套字节。
1.2使用文件描述符访问文件
2.套字节是通信端点的抽象。
2.1套字节描述符号。可以使用read,和write文件进行操作。
#include<sys/socket.h>
socket函数:
int socket(int domain, int type, int protocol);
返回值:
返回-1则表示出错。
如果成功返回套字节描述符。
参数一:domain确定通信的特性。包括地址格式。各个域有自己的格式表示地址。而表示各个域的宏都与AF_开始。意思是Address Fimaly
可能有如下值:
AF_LOCAL :unix域
AF_INET :IPV4
AF_INET6 :IPV6
AF_UNSPEC:未指定。
参数二:Type是套字节的类型。
可以的值有:
SOCK_DGRAM 长度固定,无连接的不可靠报文传递。
SOCK_RAW IP的数据报文接口。
SOCK_SEQPACKET 长度固定,有序,可靠的面向连接。报文传递。
SOCK_STREAM 有序,可靠,双向的面向连接的字节流。
参数三:
protocol:通常为0,表示给定的域,套字节类型选择的默认协议类型。
(注解://其中SOCK_RAW:需要使用root权限才能被创建。他绕过类TCP和UDP协议,需要自己构建协议的包头部分。它会被字节封装到网络层的数据包中。)
函数对比:
open():函数,创建一个文件描述符。
socket()函数,创建一个套字节描述符。
当不需要这个描述符的时候需要使用close()方法将他关闭。
close()关闭这个文件描述符。那么当不需要这个套字节描述符的时候,需要调用colse()对这个套字节文件描述符号进行关闭。
(注意不能使用lseek()方法操作套字节描述符)
shutdown函数.
函数功能:套字节通信是是双向的。可以使用shutdown()方法来禁止套字节上的输入/输出。
#include<sys/socket.h>
int shutdown(int sockfd, int how);
1.为什么有close还要使用shutdown呢。
原因一:
close()只有在最后一个活动引用被关闭的时候才释放网络端点。这意味着如果使用dup复制一个套字节描述符,套字节,直到关闭引用它的最后一个文件描述符之后才会被释放。
而shutdown允许使一个双向套字节处于不活动状态。无论引用它的文件描述符数目多少。
原因二:
当关闭套字节的一端时。可以使用。shutdown()方法。
使用处理文件描述符的函数处理套字节描述符的行为
close() 释放套字节。
dup, dup2: 和一般文件描述符一样复制。
fchdir:失败,并且将errno设置为ENOTDIR
fchmod:为规定。
fchown:有实现定义。
fcntl:支持一些命令,例如F_DUPFD, F_GETFD, F_GETFL.
F_GETOWN,FSETFD, F_SETFL, F_SETOWN
fdatasync, fsync,由实现定义。
fstat,支持一些stat的机构成员,但如何支持由实现定义。
ftruncate:未规定。
getmsg, putpmsg,如果套字节由STREAMS实现则可以支持,
read, readv, 与没有如何标志的recv等价。
select, 正常工作。
write, writev, 与没有如何标志的send等价。
字节序
大端,
最大字节地址对应于数字的最低有效字节上。
a[0] = (0xaabb>>8)&0xFF
a[1] = (0xaabb) & 0xFF
小端:
地址高位,对应数组的最高位。 a[0] = (0xaabb & 0xFF)
a[1] = ((0xaabb >> 8) & 0xFF)
地址转换:
#include<arpa/inet.h>
uint32_t htonl(uint32_t hostint32) //返回一个网络字节序,
uint16_t htons(uint16_t hostint16) //以网络字节序表示16位的整形。
uint32_t ntohl(uint32_t netint32) //将一个网络字节序转换成主机字节序号。
uint16_t ntohs(uint16_t netint16)
套字节:
struct sockadd_in {
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr; IPV4地址。
}
5.有时候需要被人理解的地址。而不是计算机理解的地址。需要使用如下api,进行转换。
#include<arpa/inet.h>
//将网络字节序转换成一个字符串表示的ip地址。
const char * inet_ntop(int domain, const void * restrict addr, char* restrict str, socklen_t size);
//将字符串转换成一个ip地址。
int inet_pton(int domain,const void *restrict str, char* restrict str, socklen_t size)
6.获取socket相关的信息。
他们可以保存在。/etc/hosts, /etc/services等文件中。或者可有命名服务器管理。 如DNS服务器。 NIS ,无论信息放在哪里都可以被他们访问到
1. gethostent(),
可以获取主机相关的信息。
#include<netdb.h>
struct hostent *gethostent(void); 如果成功返回指针,如果失败返回NULL
如果成功返回指针,如果失败返回NULL
如果成功返回指针,如果失败返回NULL
2.sethostent(int stayopen);
3.enthostent(void);
4.如果主机数据文件没有打开则gethostent()会打开这个文件。函数enthostent()方法将会关闭这个文件。
5.函数gethostent()返回的结构体如下,
struct hostent{
}
struct hostent * getnetbyaddr(uint32_t net, int type)
struct hostent * getnetbyname(const char * name);
struct netent * getnetent(void);
void setnetent(int stayopen);
void endnetent(void);
//close mouse:
sudo rmmod psmouse
7.inet_ntop,
socket编程时常用的参数。将一个ip数字转换成点分十进制的值。
在客户端连接到
8.
inet_ntop(int sa_family,&sinp_sin_addr, abuf,INET_ADDRSTRLEN);
9.可以使用bind函数将地址绑定到一个套字节上。
#include<sys/socket.h>
int bind(int sockfd, struct sockaddr *addr , socklen_t len)
如果成功返回0
失败返回-1
10.可以调用getsockname()方法来发现一个绑定套字节的地址。
#include<sys/socket.h>
int getsockname(int sockfd, struct sockaddr *restrict addr, socklen_t *restrict alenp);
在调用getsockname函数之前,设置alenp为指向一个整形的指针。该整形指向缓冲区sockaddr的长度大小,返回的时候该值被设置为该地址的大小。如果该地址和提供缓冲区的长度
不匹配。则将其截断而不报错。如果当前没有并定到该套接字, 其结果没有定义。
如果套字节已经和对方连接,调用getpeername来找到对方的地址。
11.
getpeername(int sockfd, struct sockaddr *restrict addr , socklen_t *restrict alenp);
除了返回对方地址以外,函数getpeername() 和getsockname()一样。
12.建立链接
#include<sys/socket.h>
connect(int sockfd, const struct sockaddr* addr, socklen_t len);
返回值:
成功返回0,出错返回则返回-1
connect函数的参数。
sockfd:
这个值是通过socket函数返回的一个套字节描述符。
addr:
可以通过 sockaddr_in这个结构体得到。这个结构体中包含如下成员。
struct sockaddr_in{
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
}
//其中端口号的初始化如下:
htons(uint16_t hostint16); hostint16:就是要转换的ip地址。
//ip地址转换。
inet_ntop(int domain, const void * restrict addr, char* restrict str, socklen_t size);
#include<sys/socket.h>
int listen(int sockfd, int backlog)
参数backlog提供类一个提示,用于表示该进程所要入队列的连接请求数量, 其实际值由系统决定。
但上限由<sys/socksocket.h> 中 SOMAXCONN指定。
一旦服务器调用了listen, 套字节就能接收连接请求。使用函数accept获得连接请求并建立连接。
#include<sys/socket.h>
int accpet(int sockfd, struct sockaddr * restrict addr, socklen_t *restrict len);
函数accpet()所返回的文件描述符号和原始
//设置socket选项。
int setsockopt(int sockfd, int level, int optname, const void * optval , socklen_t optlen);
int getsockopt(int sockfd, int level, int optname, const void *optval, socklen_t, optlen);如果返回成功则为0,若出错返回-1.
1.套字节描述符和文件描述符对比。
1.1使用套字节描述符访问套字节。
1.2使用文件描述符访问文件
2.套字节是通信端点的抽象。
2.1套字节描述符号。可以使用read,和write文件进行操作。
#include<sys/socket.h>
socket函数:
int socket(int domain, int type, int protocol);
返回值:
返回-1则表示出错。
如果成功返回套字节描述符。
参数一:domain确定通信的特性。包括地址格式。各个域有自己的格式表示地址。而表示各个域的宏都与AF_开始。意思是Address Fimaly
可能有如下值:
AF_LOCAL :unix域
AF_INET :IPV4
AF_INET6 :IPV6
AF_UNSPEC:未指定。
参数二:Type是套字节的类型。
可以的值有:
SOCK_DGRAM 长度固定,无连接的不可靠报文传递。
SOCK_RAW IP的数据报文接口。
SOCK_SEQPACKET 长度固定,有序,可靠的面向连接。报文传递。
SOCK_STREAM 有序,可靠,双向的面向连接的字节流。
参数三:
protocol:通常为0,表示给定的域,套字节类型选择的默认协议类型。
(注解://其中SOCK_RAW:需要使用root权限才能被创建。他绕过类TCP和UDP协议,需要自己构建协议的包头部分。它会被字节封装到网络层的数据包中。)
函数对比:
open():函数,创建一个文件描述符。
socket()函数,创建一个套字节描述符。
当不需要这个描述符的时候需要使用close()方法将他关闭。
close()关闭这个文件描述符。那么当不需要这个套字节描述符的时候,需要调用colse()对这个套字节文件描述符号进行关闭。
(注意不能使用lseek()方法操作套字节描述符)
shutdown函数.
函数功能:套字节通信是是双向的。可以使用shutdown()方法来禁止套字节上的输入/输出。
#include<sys/socket.h>
int shutdown(int sockfd, int how);
1.为什么有close还要使用shutdown呢。
原因一:
close()只有在最后一个活动引用被关闭的时候才释放网络端点。这意味着如果使用dup复制一个套字节描述符,套字节,直到关闭引用它的最后一个文件描述符之后才会被释放。
而shutdown允许使一个双向套字节处于不活动状态。无论引用它的文件描述符数目多少。
原因二:
当关闭套字节的一端时。可以使用。shutdown()方法。
使用处理文件描述符的函数处理套字节描述符的行为
close() 释放套字节。
dup, dup2: 和一般文件描述符一样复制。
fchdir:失败,并且将errno设置为ENOTDIR
fchmod:为规定。
fchown:有实现定义。
fcntl:支持一些命令,例如F_DUPFD, F_GETFD, F_GETFL.
F_GETOWN,FSETFD, F_SETFL, F_SETOWN
fdatasync, fsync,由实现定义。
fstat,支持一些stat的机构成员,但如何支持由实现定义。
ftruncate:未规定。
getmsg, putpmsg,如果套字节由STREAMS实现则可以支持,
read, readv, 与没有如何标志的recv等价。
select, 正常工作。
write, writev, 与没有如何标志的send等价。
字节序
大端,
最大字节地址对应于数字的最低有效字节上。
a[0] = (0xaabb>>8)&0xFF
a[1] = (0xaabb) & 0xFF
小端:
地址高位,对应数组的最高位。 a[0] = (0xaabb & 0xFF)
a[1] = ((0xaabb >> 8) & 0xFF)
地址转换:
#include<arpa/inet.h>
uint32_t htonl(uint32_t hostint32) //返回一个网络字节序,
uint16_t htons(uint16_t hostint16) //以网络字节序表示16位的整形。
uint32_t ntohl(uint32_t netint32) //将一个网络字节序转换成主机字节序号。
uint16_t ntohs(uint16_t netint16)
套字节:
struct sockadd_in {
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr; IPV4地址。
}
5.有时候需要被人理解的地址。而不是计算机理解的地址。需要使用如下api,进行转换。
#include<arpa/inet.h>
//将网络字节序转换成一个字符串表示的ip地址。
const char * inet_ntop(int domain, const void * restrict addr, char* restrict str, socklen_t size);
//将字符串转换成一个ip地址。
int inet_pton(int domain,const void *restrict str, char* restrict str, socklen_t size)
6.获取socket相关的信息。
他们可以保存在。/etc/hosts, /etc/services等文件中。或者可有命名服务器管理。 如DNS服务器。 NIS ,无论信息放在哪里都可以被他们访问到
1. gethostent(),
可以获取主机相关的信息。
#include<netdb.h>
struct hostent *gethostent(void); 如果成功返回指针,如果失败返回NULL
如果成功返回指针,如果失败返回NULL
如果成功返回指针,如果失败返回NULL
2.sethostent(int stayopen);
3.enthostent(void);
4.如果主机数据文件没有打开则gethostent()会打开这个文件。函数enthostent()方法将会关闭这个文件。
5.函数gethostent()返回的结构体如下,
struct hostent{
}
struct hostent * getnetbyaddr(uint32_t net, int type)
struct hostent * getnetbyname(const char * name);
struct netent * getnetent(void);
void setnetent(int stayopen);
void endnetent(void);
//close mouse:
sudo rmmod psmouse
7.inet_ntop,
socket编程时常用的参数。将一个ip数字转换成点分十进制的值。
在客户端连接到
8.
inet_ntop(int sa_family,&sinp_sin_addr, abuf,INET_ADDRSTRLEN);
9.可以使用bind函数将地址绑定到一个套字节上。
#include<sys/socket.h>
int bind(int sockfd, struct sockaddr *addr , socklen_t len)
如果成功返回0
失败返回-1
10.可以调用getsockname()方法来发现一个绑定套字节的地址。
#include<sys/socket.h>
int getsockname(int sockfd, struct sockaddr *restrict addr, socklen_t *restrict alenp);
在调用getsockname函数之前,设置alenp为指向一个整形的指针。该整形指向缓冲区sockaddr的长度大小,返回的时候该值被设置为该地址的大小。如果该地址和提供缓冲区的长度
不匹配。则将其截断而不报错。如果当前没有并定到该套接字, 其结果没有定义。
如果套字节已经和对方连接,调用getpeername来找到对方的地址。
11.
getpeername(int sockfd, struct sockaddr *restrict addr , socklen_t *restrict alenp);
除了返回对方地址以外,函数getpeername() 和getsockname()一样。
12.建立链接
#include<sys/socket.h>
connect(int sockfd, const struct sockaddr* addr, socklen_t len);
返回值:
成功返回0,出错返回则返回-1
connect函数的参数。
sockfd:
这个值是通过socket函数返回的一个套字节描述符。
addr:
可以通过 sockaddr_in这个结构体得到。这个结构体中包含如下成员。
struct sockaddr_in{
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
}
//其中端口号的初始化如下:
htons(uint16_t hostint16); hostint16:就是要转换的ip地址。
//ip地址转换。
inet_ntop(int domain, const void * restrict addr, char* restrict str, socklen_t size);
#include<sys/socket.h>
int listen(int sockfd, int backlog)
参数backlog提供类一个提示,用于表示该进程所要入队列的连接请求数量, 其实际值由系统决定。
但上限由<sys/socksocket.h> 中 SOMAXCONN指定。
一旦服务器调用了listen, 套字节就能接收连接请求。使用函数accept获得连接请求并建立连接。
#include<sys/socket.h>
int accpet(int sockfd, struct sockaddr * restrict addr, socklen_t *restrict len);
函数accpet()所返回的文件描述符号和原始
//设置socket选项。
int setsockopt(int sockfd, int level, int optname, const void * optval , socklen_t optlen);
int getsockopt(int sockfd, int level, int optname, const void *optval, socklen_t, optlen);如果返回成功则为0,若出错返回-1.