3. 生成套接口地址

生成套接口地址

1.通用套接口地址

#include <sys/socket.h>
struct sockaddr {
    sa_family_t    sa_family;//地址族,Linux中为2字节
    char             sa_data[14];//地址数据
};

2.本地套机口地址

#include <sys/un.h>
struct sockaddr_un{
    sa_family_t    sun_family;//地址族,Linux中为2字节
    char            sun_path[108];//路径名
};
sun_family必须为 AF_LOCAL或者AF_UNIX它指定了结构必须根据sockaddr_un规则格式化。
sun_path 包含有效的UNIX路径名,结尾不需要空字符。

3.Internet(IPV4)套接口地址

#include <netinet/in.h>
struct sockaddr_in {
    sa_faminly_t        sin_family;//地址族
    uint16_t            sin_port;//端口号
    struct in_addr    sin_addr;//Internet 地址
    unsigned char        sin_zero[8];//占位字节
};
struct in_addr {
    uint32_t        s_addr;//Internet 地址
};

4. Internet(IPV6)套接口地址

struct socketaddr_in6 {
    sa_family_t        sin6_family;
    uint16_t            sin6_port;//端口号
    uint32_t            sin6_flowinfo;//流信息
    struct in6_addr    sin6_addr;//IPv6地址
};
struct in6_addr {
    union {
        uint8_t    u6_addr8[16];
        uint16_t    u6_addr16[8];
        uint32_t    u6_addr32[4];
    } in6_u;
};

//生成本地套接口例子
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>

static void bail(const char* on_what)
{
        perror(on_what);
        exit(1);
}

int main(void)
{
        int z;//返回的状态码
        int sck_unix;//套接口
        struct sockaddr_un adr_unix;//AF_UNIX
        int len_unix;//长度
        const char pth_unix[] = "/tmp/my_sock";//路径名

        /* 建立AF_UNIX或者AF_LOCAL套接口 */
        sck_unix = socket(AF_UNIX, SOCK_STREAM, 0);

        if (sck_unix == -1)
                bail("socket() error/n");
        /* 为防止该套接口的路径名由于前次运行而保留下来,先进行删除操作,并忽视
         * 错误
         */
        unlink(pth_unix);
        /* 生成AF_UNIX地址 */
        memset(&adr_unix, 0, sizeof(adr_unix));
        adr_unix.sun_family = AF_UNIX;
        strncpy(adr_unix.sun_path,
                pth_unix,
                sizeof(adr_unix.sun_path)-1)
                [sizeof(adr_unix.sun_path) - 1] = 0;
        printf("sizeof(adr_unix.sun_path) -1 = %d/n", sizeof(adr_unix.sun_path) - 1);
        len_unix = SUN_LEN(&adr_unix);//宏SUN_LEN调用strlen计算UNIX路径名的字符串长度,不包括空字节,注意一定要在
                                      //adr_unix.sun_path[]添加一个'/0'
        printf("len_unix is %d/n", len_unix);

        /* 将套接口地址绑定到套接口 */
        z = bind(sck_unix, (struct sockaddr *)&adr_unix, len_unix);
        if (z == -1)
                bail("bind () error/n");
        /* 显示套接口*/
        system("netstat -pa --unix 2>/dev/null |grep /'/tmp/my/' "
                );
        /* 关闭套接口并断开与其相应路径名的连接 */
        close(sck_unix);
        //unlink(pth_unix);

        return 0;
}
                                                                                                                           

//生成抽象的本地地址
//传统的AF_UNIX套接口存在缺陷:总有一个文件系统对象生成。不需要,不方便。
//我们只需要把路径的第一个字符设置为空
/*把第一字节设置为空*/
        adr_unix.sun_path[0] = 0;

//生成Internet(IPv4)套接口地址

|-------------------|-----------------------|--------------------|---------------------|
|        sin_family=AF_INET            |        sin_port    |                            |
|-------------------|-----------------------|--------------------|---------------------|
|                                           sin_addr                                                       |                     
|-------------------|-----------------------|--------------------|---------------------|
|                              sin_zero[8]


sin_port,sin_addr都必须是网络字节序的(大端)。
关于大端小端:
大小端表示多字节值的哪一端(小端或大端)存储在该值的起始地址。这由CPU的体系结构决定的。
对于0x1234
<---------地址增加方向
| 0x34 | 0x12 |      大端
| 0x12 | 0x34 |      小端(高高低低,就是 高字节存在高地址 低字节存在低地址)


//例子
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/in.h>
#include <netinet/in.h>

static void bail(const char* on_what)
{
        perror(on_what);
}

int main(void)
{
        int z;//返回的状态码
        int sck_inet;//套接口
        struct sockaddr_in adr_inet;//AF_INET  in.h里有定义
        int len_inet;//地址长度***
        const unsigned char IPno[] = {127,0,0,23};//本地回送地址
        /* 生成一个IPv4 Internet 套接口 */
        sck_inet = socket(AF_INET, SOCK_STREAM, 0);

        if (sck_inet == -1)
                bail("socket()");
        /* 建立AF_INET 套接口地址 */
        memset(&adr_inet, 0, sizeof(adr_inet));

        adr_inet.sin_family = AF_INET;
        adr_inet.sin_port = htons(9000);
        memcpy(&adr_inet.sin_addr.s_addr, IPno, 4);
        len_inet = sizeof(adr_inet);

        /* 将地址绑定到套接口 */
        z = bind(sck_inet,
                (struct sockaddr*)&adr_inet,
                len_inet);
        if (z == -1)
                bail("bind() error/n");
        /*  显示所有已经绑定的套接口 */
        system("netstat -pa --tcp 2>/dev/null"/* | sed -n /"1,/^Proto/p;/af_inet/p/""*/);
         close(sck_inet);
        return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值