主要是网络套接字笔记 linux平台
1.使用网络套接字,通常要先用一个未被使用的端口(大于1024-小于它的端口是系统保留端口,且之前该端口没有在/etc/services中列出)。如果有足够的权限,可以将自己的服务端口添加到/etc/services文件的已知服务列表中,并为该服务分配一个服务名,这样用户也可以通过服务名而不是端口号来访问服务端程序。
#include <netdb.h>
struct servent *getservbyname(const char *name,const char *proto);
struct servent *getservbyname(int port, const char *proto);
前者通过服务名查询服务信息,后者通过服务端口查询。
proto是用于连接该服务的协议,它取“tcp”和“udp”,前者用于SOCK_STREAM类型的tcp连接,后者用于SOCK_DGRAM类型的udp连接。
结构servent至少包含以下成员
struct servent {
char *s_name; /*服务名*/
char **s_aliases; /*服务别名列表*/
int s_port; /*ip端口*/
char *s_proto; /*使用的协议*/
};
2.主机信息解析
struct hostent *gethostbyaddr(const void *addr, size_t len, int type);
struct hostent *gethostbyname(const char *name);
前者通过ip地址获得主机的相关信息,后者通过主机名获得主机信息,这两函数通过查询网络配置文件(如/etc/services)来完成工作。
这些函数返回的主机信息结果结构至少包含以下几个成员
struct hostent {
char *h_name; /*主机名*/
char **h_aliases; /*主机别名列表,一台主机可能有多个别名*/
int h_addrtype; /*地址类型*/
int h_length; /*该类地址的长度*/
char **h_addr_list /*主机ip地址列表,一台主机可能有多个ip地址*/
};
返回的地址列表是网络字节序类型,要将它们打印出来,需要先转换要可打印的字符:
#include <arpa/inet.h>
char *inet_ntoa(struct in_addr in);
该函数的作用是将一个因特网地址转换为一个四个点表示法格式的字符串。
其他相关的函数还有gethostname()
#include <unistd.h>
int gethostname(char *name, int namelength);
函数获得当前主机的主机名,将主机名放入name所指的内存中,namelength是调用者指定的字串长度,如果获得的主机名超过这个长度,则截去多余的部分。
3.如果想允许多个远程客户连接服务端,就必须指定一组允许连接的ip地址。可以用特殊的INADDR_ANY来表示允许任何来自网络的主机连接,只要将监听套接字的sin_addr.s_addr设为它。
4.主机字节序和网络字节序
不同的计算机使用不同的字节序来表示整数,例如Intel处理器将32位的数字分为四个连续的字节,并以字节序1-2-3-4的顺主观性存储在内存中,这里1表示最高位的字节。而Motorola是以字节序4-3-2-1的方式存储。在二进制传输方式中,如果直接以简单的逐个字节方式来传输,会导致网络两端不同类型的主机的整数值不一致。
为了解决这一问题,需要定义一个网络字节序,客户端和服务端在传输整数前,应先将数值转换为网络字节序。
#include <netinet/in.h>
unsigned long int htonl(unsigned long int hostlong);
unsigned short int htons(unsigned short int netshort);
unsigned long int ntohl(unsigned long int netlong);
unsigned short int ntohs(unsigned short int netshort);
这些函数将16位和32位整数在主机字节序和标准的网络字节序之间转换。函数名是对应操作的简写形式,如htonl:host to net long。
5.因特网守护进程
unix系统通常以因特网守护进程(inetd)来提供多项网络服务。当有客户连接到某项服务时,inetd程序就运行相应的服务。这使得各项网络服务不必一直运行着,它们可以在需要时以inetd程序来启动。inetd配置文件/etc/inetd.conf配置文件决定哪些服务可以启动。
要改变系统提供的服务,可以通过修改/etc/inetd.conf配置文件并重启inetd的方法实现.
killall -HUP inetd 重启inetd
新版本的linux系统一般会运行xinetd来替代inetd,它提供了更友好的配置服务的方式。