网络编程(二)——服务器和客户端信息的获取

目录

1、字符串IP地址和二进制IP地址结构的转换

2.套接字文件描述符的判定

3、IP地址与域名之间的相互转换

4、协议名称处理函数


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

猜你喜欢

转载自blog.csdn.net/lixiangsheng2012/article/details/83450545