您的位置:首页 > 运维架构 > Linux

VMware启动CentOS 6.5后将网卡eth1重新设置为eth0

2014-12-29 17:37 459 查看
    1. int socket(int domain, int type, int protocol);

    返回套接字描述符,错误的情况下返回-1。Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。你也可以对socket执行这些操作。
    参数1:domain-指定用于通信的协议族,常见的协议族有:AF_INET、AF_INET6、AF_LOCAL等。协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合,AF_UNIX决定了要用一个绝对路径名作为地址。
    参数2:type-常用的socket类型有:SOCK_STREAM、SOCK_DGRAM等。
    参数3:protocol-指定协议,常用的协议有:IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等。默认使用0,会根据type值的不同,有不同的默认值:type-SOCK_STREAM则默认为TCP协议,type-SOCK_DGRAM则默认UDP协议。
    参:/article/4698733.html
    2. struct sockaddr_in
include <netinet/in.h>

// All pointers to socket address structures are often cast to pointers
// to this type before use in various functions and system calls:

struct sockaddr {
unsigned short    sa_family;    // address family, AF_xxx
char              sa_data[14];  // 14 bytes of protocol address
};

// IPv4 AF_INET sockets:

struct sockaddr_in {
short            sin_family;   // e.g. AF_INET, AF_INET6
unsigned short   sin_port;     // e.g. htons(3490)
struct in_addr   sin_addr;     // see struct in_addr, below
char             sin_zero[8];  // zero this if you want to
};

struct in_addr {
unsigned long s_addr;          // load with inet_pton()
};

这几个结构体用于处理internet address信息。sockaddr和sockaddr_in都是16字节长,通常情况下他们是可以自由转换的,在connect操作中有转换的操作。在sockaddr_in的sin_port和sin_addr存放网络字节序的数据。网络字节序和主机字节序的区别参见链接。sin_addr 和 sin_port 需要转换为网络字节序,而sin_family 不需要。因为 sin_addr 和 sin_port 分别封装在包的 IP 和 UDP 层。因此,它们必须 要 是网络字节序。但是 sin_family 域只是被内核 (kernel) 使用来决定在数 据结构中包含什么类型的地址,所以它必须是主机字节序。
    3. 主机字节序(host byte order)和网络字节序(network byte order)的转换:
        (1) . int inet_aton(const char *cp, struct in_addr *inp);
        作用是把cp参数指定的字符串形式(IPV4 numbers-and-dots notation)的ip地址转换为整数形式(binary form)的且已经是网络字节序的数据。并把结果存入inp所指向的结构体。如果传入的地址合法,则返回非0整数,否则,返回0。不支持IPV6。
        cp参数可以是由dot隔开的数字组成的IPV4地址,这些数字可以是十进制、八进制(以0开头)或者十六进制(以0X开头)的,如192.168.52.250和0XC0.0XA8.0X34.0XFA,也可以是不同进制混合的,如0XC0.0250.52.0XFA。这几个地址都是同一个地址192.168.52.250。这些形式的地址都可被命名为IPV4 numbers-and-dots notation。而如果四个数字全部是10进制的话,可以称为IPV4 dotted-decimal notation或者IPv4 dotted-quad notation。其实指的都是IP地址的字符串表示法。以上叫法不知道用什么词翻译好,所以直接列出。
        源自:http://linux.die.net/man/3/inet_aton
        用法:
char* ip = "192.168.52.250";
struct in_addr addr;
inet_aton(ip, &addr);


        (2) . int inet_pton(int af, const char *src, void *dst);

        作用:把src所指的地址转换为一个网络地址结构体(network address structure),并把这个结构体拷贝给dst。af参数的内容必须是AF_INET或者AF_INET6。成功的情况返回1;如果src字符串不符合af参数所指定协议族(address family)的要求地址格式,则返回0;如果传递的af参数不是有效地协议族,则返回-1。(支持IPV6地址)
         这里的src参数,如果af是AF_INET的话,必须是dotted-decimal notaion,也就是说它只支持十进制表示的IP地址字符串。
        源自:http://linux.die.net/man/3/inet_pton
        用法:
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons( (unsigned short)port);
inet_pton(AF_INET, hostIp, (void*)&sin.sin_addr);


        (3) . in_addr_t inet_addr(const char *cp);

        作用:把cp参数指定的且格式为IPV4 numbers-and-dots notation(与inet_aton所要求的地址格式一样)的地址转换为long型整数地址。不支持IPV6。在参数非法的情况下返回-1。而巧合的是255.255.255.255所对应的网络字节序整数地址正好也是-1,所以并不能凭借返回值来判断转换是否成功。所以更推荐使用inet_pton、inet_aton或者getaddrinfo。当然在确保255.255.255.255不会出现的情况下也是可以使用的。
        源自:http://linux.die.net/man/3/inet_addr
        用法:
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons( (unsigned short)port);
sin.sin_addr.s_addr = inet_addr(hostIp);


        (4) . int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);

        作用:根据给定的node和service信息,getaddrinfo()可以构造一个或多个addrinfo结构体,而其中的每一个addrinfo结构体所包含的互联网地址(internet address)都可用在bind()或者connect()函数调用时。也就是说getaddrinfo()构造了多个符合条件的互联网地址,这些多个地址信息单元组成一个链表,而由res指向这个链表的首元素。遍历每一个地址信息可以使用ai_next。
struct addrinfo {
int              ai_flags;
int              ai_family;
int              ai_socktype;
int              ai_protocol;
size_t           ai_addrlen;
struct sockaddr *ai_addr;
char            *ai_canonname;
struct addrinfo *ai_next;
};

        hints虽然也是一个addrinfo结构体,不过它起一个criteria的作用,或者说是过滤器,就是把符合条件的数据留下。hints的ai_flags、ai_family、ai_socktype和ai_protocol可以根据需要指定数值,但是其他的属性就不要去指定了,保证是0或者NULL就可以。如果hints是NULL,那么相当于是ai_socktype=0; ai_protocol=0; ai_family=AF_UNSPEC; ai_flags=(AI_V4MAPPED|AI_ADDRCONFIG)。ai_flags也起着限制的作用,它的值可以是单个值如:AI_ADDRCONFIG,也可以是多取值的,用“|”符号按位将每个flag分隔开,如(AI_V4MAPPED|AI_ADDRCONFIG)。
        node可以是IPV4 numbers-and-dots notation形式的地址,也支持IPV6地址,这些通称numerical network address;域名地址(network hostname)也可以。而如果hints.ai_flags包含AI_NUMBERICHOST标志,那么node必须是numberical network address。因为AI_NUMBERICHOST阻止了任何潜在的对冗长的network host address的查找。
        service指定端口。且node和service最多只能有一个是空的。
        源自:http://linux.die.net/man/3/getaddrinfo
        用法:
struct addrinfo hints;
struct addrinfo *result, *rp;
int sfd, s, j;
size_t len;
ssize_t nread;

/* Obtain address(es) matching host/port */
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
hints.ai_flags = 0;
hints.ai_protocol = 0;          /* Any protocol */

s = getaddrinfo(argv[1], argv[2], &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(EXIT_FAILURE);
}

/* getaddrinfo() returns a list of address structures.
Try each address until we successfully connect(2).
If socket(2) (or connect(2)) fails, we (close the socket
and) try the next address. */

for (rp = result; rp != NULL; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (sfd == -1)
continue;

if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
break;                  /* Success */

close(sfd);
}

        关于网络自己序和主机字节序的转换可参见:/article/1417601.html 和http://blog.csdn.net/Sunboy_2050/article/details/6061528这两篇博客的作者很牛!
    这个可做进一步的学习-网络socket编程指南:http://blog.csdn.net/hello_wyq/article/details/1180747
    如果想做深一步的研究可以使用wireshark做协议抓取分析:
    http://blog.csdn.net/hnney/article/details/5604677
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: