`
braverong
  • 浏览: 6156 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

linux socket编程学习

阅读更多

    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协议。

    参:http://www.cnblogs.com/skynet/archive/2010/12/12/1903949.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);
    }

        关于网络自己序和主机字节序的转换可参见:http://blog.csdn.net/sunboy_2050/article/details/6100734 和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

 

分享到:
评论

相关推荐

    实战Linux Socket编程

    在IT领域,Linux Socket编程是网络通信的核心技术之一,它为开发者提供了在Linux操作系统上实现进程间通信(IPC)和网络通信的接口。本实战指南将深入探讨这一主题,帮助你掌握如何在Linux环境中构建高效的网络应用...

    实战Linux+Socket编程.pdf

    实战Linux+Socket编程.pdf

    Linuxsocket编程入门[参照].pdf

    Linux Socket 编程入门 Linux Socket 编程入门是指在 Linux 操作系统中使用 Socket 编程技术来实现网络通信的过程。Socket 编程是网络编程的基础,...读者可以根据这个教程继续深入学习 Socket 编程的其他知识和技术。

    实战Linux Socket编程_2-1

    实战Linux Socket编程_2-1 Socket编程新手使用

    实战Linux Socket编程.rar

    Linux Socket编程是网络编程的重要组成部分,它为开发者提供了在Linux操作系统上进行网络通信的基础接口。本实战教程将深入探讨如何利用Socket API构建高效、可靠的网络应用程序。以下是对标题和描述中涉及的知识点...

    实战Linux Socket 编程.rar

    本资源“实战Linux Socket编程”旨在帮助你深入理解并掌握这一关键技能,尤其对于那些希望在嵌入式领域有所建树的开发者来说,它是不可或缺的学习资料。 在Linux系统中,Socket编程主要涉及以下几大知识点: 1. **...

    Linux socket 编程入门

    Linux Socket编程是网络编程的重要组成部分,它允许程序员创建和使用网络连接,特别是在TCP/IP协议栈上构建应用程序。本文将深入探讨TCP服务器端的Socket编程,为初学者提供基础的指导。 首先,理解Socket编程的...

    实战linux socket 编程 pdf版本

    实战 linux socket 编程 pdf格式

    实战Linux socket编程Linux Socket Programming By Example

    《实战Linux Socket编程》是...总之,《实战Linux Socket编程》的配套源代码是一个宝贵的资源,它使学习者能够动手实践,从而更好地掌握网络编程的核心概念和技术,对于提升Linux系统下的网络编程能力具有重要意义。

    实战LinuxSocket编程

    资源名称:实战Linux Socket编程资源截图: 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。

    实战Linux Socket编程源码

    Linux Socket编程是网络编程的重要组成部分,它允许...总之,"实战Linux Socket编程源码"提供了一个实践Socket编程和多客户端处理的平台,通过对源代码的学习和分析,可以加深对Socket编程的理解,提升网络编程技能。

    Linux下使用C++进行Socket编程

    Linux下使用C++进行Socket编程是一门涉及网络通信的高级技术。在Linux操作系统中,Socket编程通常采用C语言,因为传统的GNU C库提供了丰富的Socket API函数,但这些函数是面向过程设计的,没有面向对象的封装,使用...

    linux socket 实战编程pdf及源码

    Linux Socket实战编程是深入理解网络通信机制的...总的来说,这份资源对于想要深入理解和精通Linux Socket编程的IT从业者来说是一份宝贵的资料,通过学习和实践,可以显著提升网络编程能力,为职业发展打下坚实基础。

    Linux SOCKET编程 PDF 清晰文字版 非扫描(附录一 简明SOCKET编程指南.[pdf)

    Linux/Unix系统下的Socket编程是网络通信程序设计的基础,其核心是BSD Socket接口,这一接口被广泛地应用在众多Unix系统中,包括Linux。BSD Socket接口提供了一组用于网络通信的函数,这些函数允许开发者进行套接字...

    《实战 Linux Socket编程》练习代码

    下面将根据提供的压缩包文件名“实战 Linux Socket编程代码”来解析其中可能包含的知识点。 1. **Socket基础知识**:Socket是网络通信的基础,它是进程间通信的一种方式,特别适用于跨网络的通信。在Linux系统中,...

    实战linux socket编程.pdf

    ### 实战Linux Socket编程知识点概览 #### 一、Socket编程基础 **1.1 Socket概念简介** Socket是一种用于进程间通信的机制,它为不同主机间的进程提供了一种可靠的双向通信链路。在Linux环境下,Socket编程是实现...

    实战Linux Socket 编程-示例源码

    本实战教程将通过具体的源码实例,帮助你深入理解Linux Socket编程的核心概念和技巧。 一、Socket基础知识 Socket是网络通信的基础,它分为服务器端Socket和客户端Socket。服务器端Socket监听特定端口,等待客户端...

Global site tag (gtag.js) - Google Analytics