目录
1、字符串IP地址和二进制IP地址结构的转换
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
struct in_addr{
unsigned long int s_addr;
}
int inet_aton(const char *cp, struct in_addr *inp); /*将点分四段式的IP地址转为地址结构in_addr值*/
in_addr_t inet_addr(const char *cp); /*将点分四段式的IP地址字符串转为地址结构in_addr值*/
in_addr_t inet_network(const char *cp); /*将字符串地址的网络部分转为地址结构in_addr值*/
char *inet_ntoa(struct in_addr *inp); /*将in_addr结构地址转为字符串*/
struct in_addr net_makeaddr(int net, int host); /*将网络地址和主机地址合为IP地址*/
in_addr_t inet_lnaof(struct in_addr in); /*获得地址的主机部分*/
in_addr_t inet_netof(struct in_addr in); /*获得地址的网络部分*/
int inet_pton(int af, const char *src, void *dst); /*根据协议族af将srcz转为struct in_addr的dst*/
const char *inet_pton(int af, const void *src, char *dst,socklen_t cnt);/*根据协议族af将struct in_addr的src转为缓冲区大小为cnt的src*/
其中inet_ntoa与inet_addr是不可重入的。
可重入函数可以做这样的基本定义:重入意味着这个函数可以重复进入,可以被并行调用,可以被中断,它只使用自身栈上的数据变量,它不依赖于任务环境,在多任务调度过程中,它是安全的,不必担心数据出错。
不可重入函数基本上与可重入函数有相反的定义了:不可重入,意味着不可被并行调度,否则会产生不可预料的结果,这些函数提内一般使用了静态(static)的数据结构,使用了malloc()或者free()函数,使用了标准I/O函数等等。
例子请参考一下连接:
https://github.com/lixiangsheng2018/linux_network_programming/blob/master/chp8/trans.c
2.套接字文件描述符的判定
用fstat获取文件描述符的模式,然后将模式的S_IFMT部分与S_IFSOCK比较,就可以知道一个文件描述符是否为socket.
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int fstat(int fd, struct stat *buf);
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
The following flags are defined for the st_mode field:
S_IFMT 0170000 bit mask for the file type bit fields
S_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO
S_ISUID 0004000 set UID bit
S_ISGID 0002000 set-group-ID bit (see below)
S_ISVTX 0001000 sticky bit (see below)
S_IRWXU 00700 mask for file owner permissions
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRWXG 00070 mask for group permissions
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 mask for permissions for others (not in group)
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
例子请参考一下连接:
https://github.com/lixiangsheng2018/linux_network_programming/blob/master/chp8/issockettype.c
3、IP地址与域名之间的相互转换
DNS服务器功能:在主机的名称和IP地址之间担任翻译工作。
#include <netdb.h>
extern int h_errno;
struct hostent *gethostbyname(const char *name);/*不可重入函数*/
#include <sys/socket.h> /* for AF_INET */
struct hostent *gethostbyaddr(const void *addr,socklen_t len, int type);
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses */
}
例子参考一下连接:
https://github.com/lixiangsheng2018/linux_network_programming/blob/master/chp8/get_host.c
4、协议名称处理函数
#include <netdb.h>
struct protoent *getprotoent(void);/*从协议文件/etc/protocols中读取一行*/
struct protoent *getprotobyname(const char *name);/*从协议文件中找到匹配项*/
struct protoent *getprotobynumber(int proto);/*按照协议类型的值找到匹配项*/
void setprotoent(int stayopen); /*设置协议文件打开状态*/
void endprotoent(void); /*关闭协议文件*/
struct protoent {
char *p_name; /* official protocol name */
char **p_aliases; /* alias list */
int p_proto; /* protocol number */
}
使用协议族函数的例子:
https://github.com/lixiangsheng2018/linux_network_programming/blob/master/chp8/protocol.c