zoukankan      html  css  js  c++  java
  • linux C socket

      socket套接字和管道同样可以提供进程内通信。但套接字更胜一筹,不同的进程可以跨越不同的主机(说白了,支持网络通信)。使用套接字的知名程序:telnet、rlogin、ftp等。

      你需要知道的一些基本原理:

      使用socket时必须指定通信的类型和协议。

      通信类型决定了以下内容:1、数据传输的基本单元(有的会打包传输,有的作为一个结构体);2、数据是否可丢失,数据传输的可靠性:(有的数据丢失一两个便不可读了,有的数据如视频不受太大影响);3、是一对一的通信还是一对多的通信。

      每一个socket必须有一个命名空间,命名空间一般以PF_开头,AF_开头的符号名指定命名空间的地址格式。

    你需要了解的协议内容

      要让两个socket能够通信,必须指定相同的协议。

      协议和命名空间、通信风格是绑定的。比如TCP协议只能用在stream风格的通信中,Internet的命名空间中。对于指定的命名空间,请使用默认协议(不同的协议、命名空间组合可能会出错)

      

    SOCKET几种通信风格:

    int SOCK_STREAM: 提供可靠的通信方式。有连接。

    int SOCK_DGRAM: 和SOCK_STREAM相反,使用的是不可靠通讯方式。无连接,每一个数据包都必须指定地址。一般来说,丢包的时候需要重发数据包。

    int SOCK_RAW:  这种风格允许我们访问底层网络协议和接口,一般来讲我们不需要使用这种风格。

    SOCKET地址:

      实际上Socket地址就是socket的名字。在这里地址和名字是同义词。只有把地址和socket绑定后,我们才可以使用socket通信。

    网络接口名:

      每一个网络接口都有个名字如:lo、eth0。但在计算机内部,我们通过索引来使用接口。

    #include <net/if.h>
    size_t IFNAMESIZE    //常量:定义了保存接口名的最大buffer大小。(包含了最后zero 结束字节)
    unsigned int if_nametoindex (const char *ifname)
    //通过接口名返回该接口的索引号,如果不存在该接口名则返回0。也可以用来判断一个接口是否存在。
    char * if_indextoname (unsigned int ifindex, char *ifname)
    //将接口索引号ifindex和接口名ifname映射起来。如果索引无效,返回空指针,否则返回接口名。
    struct if_nameindex
    //用来保存某个接口的信息。
    
    /*成员如下:*/
    
    unsigned int if_index
    //接口索引
    
    char *if_name
    //接口名(以NULL结尾)
    struct if_nameindex * if_nameindex(void)
    //返回一个if_nameindex结构体的数组(包含了所有的网络接口)。结束标志:接口索引为0,接口名为空指针。
    //返回的结构体必须用if_freenameindex释放
    void if_freenameindex (struct if_nameindex *ptr)
    //解释如上

    本地命名空间:

      符号名为PF_LOCAL。本地命名空间也被称之为Unix域套接字。另外一个名字是file namespace(socket 地址常被实现为文件名)

      本地socket无法被其他机器连接(即便其他机器共享了包含本地socket的文件系统)。其他机器可以共享的文件系统查看到scoket文件,但无法连接。关闭本地命名空间的socket,建议同时删除socket文件。本地命名空间只支持一种协议(不管通信风格),协议号是0。

    #include <sys/socket.h>
    int PF_LOCAL
    int PF_UNIX
    int PF_FILE

    以上几个都是宏常量,而且都是同义词。这些常量用来指定本地命名空间。

    #incude <sys/un.h>
    
    struct sockaddr_un {
        short int sun_family;
        char sun_path[108];
    }

    sun_family:标志了地址族和socket 地址的格式。在本地命名空间中,使用AF_LOCAL。

    sun_path[108]:socket使用的文件名(很奇怪为何是108个字节,理查德·马修·斯托曼推荐使用alloca来申请适当大小的空间存储文件名。并将该数组长度设置为0)

    int SUN_LEN(struct sockaddr_un *ptr)

     SUN_LEN是宏定义的函数,用来计算本地命名空间中socket地址的长度。实际为结构体sockaddr_un的大小。

    创建一个本地socket实例:

    #include <stddef.h>
    #include <stdio.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <sys/un.h>
    
    int make_named_socket (const char *filename)
    {
        struct sockaddr_un name;
        int sock;
        size_t size;
        
        /* Create the socket */
        sock = socket (PF_LOACAL, SOCK_DGRAM, 0);
        if (sock < 0)
        {
            perror ("socket");
            exit (EXIT_FAILURE);
        }
    
        /*Bind a name to the socket.*/
        name.sun_family = AF_LOCAL;
        strncpy (name.sun_path, filename, sizeof (name.sun_path));
        name.sun_path[sizeof(name.sun_path)-1] ='';
    
        /* The size of the address is the 
        offset of the start of the filename,
        plus its length (not including the terminating null byte).
        Alternatively you can just do:
        size = SUN_LEN(&name);
        */
        size = (offsetof (struct sockaddr_un, sun_path)) + strlen (name.sun_path));
    
        if (bind (sock, (struct sockaddr_un *) &name, size) < 0)
        {
            perror ("bind");
            exit (EXIT_FAILURE);
        }
    
        return sock;
    
    }
  • 相关阅读:
    努力 加油
    大总结(全文手打)加深记忆 表单 注册页面的第一次制作 小白一只多多包含
    购物栏
    三级轮播
    图片轮播
    啊!!苦等,博客终于通过了!!
    SQL升级Oracle挖的Null坑,你懂的!
    关于master..xp_cmdshell’的几个错误_解决办法(转)
    班级博客
    图片系统架构思考之一:删除图片--不容忽视
  • 原文地址:https://www.cnblogs.com/san-fu-su/p/5746809.html
Copyright © 2011-2022 走看看