Linux IPC SOCKET 通信基本函数解析

                网络IPC:套字节

1.套字节描述符和文件描述符对比。
                
    1.1使用套字节描述符访问套字节。
    1.2使用文件描述符访问文件

2.套字节是通信端点的抽象。
    2.1套字节描述符号。可以使用read,和write文件进行操作。
    #include<sys/socket.h>

socket函数:
    int socket(int domain, int type, int protocol);
    返回值:
         返回-1则表示出错。
         如果成功返回套字节描述符。
    
    参数一:domain确定通信的特性。包括地址格式。各个域有自己的格式表示地址。而表示各个域的宏都与AF_开始。意思是Address Fimaly
            可能有如下值:
                AF_LOCAL :unix域
                AF_INET  :IPV4
                AF_INET6 :IPV6
                AF_UNSPEC:未指定。
    参数二:Type是套字节的类型。
            可以的值有:
                SOCK_DGRAM          长度固定,无连接的不可靠报文传递。
                SOCK_RAW            IP的数据报文接口。
                SOCK_SEQPACKET        长度固定,有序,可靠的面向连接。报文传递。
                SOCK_STREAM            有序,可靠,双向的面向连接的字节流。

    参数三:
        protocol:通常为0,表示给定的域,套字节类型选择的默认协议类型。

    (注解://其中SOCK_RAW:需要使用root权限才能被创建。他绕过类TCP和UDP协议,需要自己构建协议的包头部分。它会被字节封装到网络层的数据包中。)
    
    函数对比:
        open():函数,创建一个文件描述符。
        socket()函数,创建一个套字节描述符。
        
        当不需要这个描述符的时候需要使用close()方法将他关闭。
        close()关闭这个文件描述符。那么当不需要这个套字节描述符的时候,需要调用colse()对这个套字节文件描述符号进行关闭。

        (注意不能使用lseek()方法操作套字节描述符)


shutdown函数.    
    函数功能:套字节通信是是双向的。可以使用shutdown()方法来禁止套字节上的输入/输出。
    #include<sys/socket.h>
    int shutdown(int sockfd, int how);

    1.为什么有close还要使用shutdown呢。
    原因一:
        close()只有在最后一个活动引用被关闭的时候才释放网络端点。这意味着如果使用dup复制一个套字节描述符,套字节,直到关闭引用它的最后一个文件描述符之后才会被释放。
        而shutdown允许使一个双向套字节处于不活动状态。无论引用它的文件描述符数目多少。

    原因二:
        当关闭套字节的一端时。可以使用。shutdown()方法。
    
    使用处理文件描述符的函数处理套字节描述符的行为

    close() 释放套字节。
    dup, dup2:  和一般文件描述符一样复制。
    fchdir:失败,并且将errno设置为ENOTDIR
    fchmod:为规定。
    fchown:有实现定义。
    fcntl:支持一些命令,例如F_DUPFD, F_GETFD, F_GETFL.
    F_GETOWN,FSETFD, F_SETFL, F_SETOWN
    fdatasync, fsync,由实现定义。
    fstat,支持一些stat的机构成员,但如何支持由实现定义。
    ftruncate:未规定。
    getmsg, putpmsg,如果套字节由STREAMS实现则可以支持,
    read, readv, 与没有如何标志的recv等价。
    select, 正常工作。
    write, writev, 与没有如何标志的send等价。


字节序
    大端,
        最大字节地址对应于数字的最低有效字节上。
                                    a[0]  = (0xaabb>>8)&0xFF
                                    a[1]  = (0xaabb) & 0xFF
    小端:
        地址高位,对应数组的最高位。 a[0] = (0xaabb & 0xFF)
                                     a[1] = ((0xaabb >> 8) & 0xFF)

地址转换:
    #include<arpa/inet.h>
    uint32_t htonl(uint32_t hostint32)       //返回一个网络字节序,
    uint16_t htons(uint16_t hostint16)         //以网络字节序表示16位的整形。
    uint32_t ntohl(uint32_t netint32)       //将一个网络字节序转换成主机字节序号。
    uint16_t ntohs(uint16_t netint16)


套字节:
 struct sockadd_in {
    sa_family_t  sin_family;
    in_port_t  sin_port;
    struct  in_addr sin_addr;      IPV4地址。
 }


5.有时候需要被人理解的地址。而不是计算机理解的地址。需要使用如下api,进行转换。
    
    #include<arpa/inet.h>
    //将网络字节序转换成一个字符串表示的ip地址。
    const char * inet_ntop(int domain, const void * restrict addr, char* restrict str, socklen_t size);
    //将字符串转换成一个ip地址。
    int inet_pton(int domain,const void *restrict str, char* restrict str, socklen_t size)

6.获取socket相关的信息。
    他们可以保存在。/etc/hosts, /etc/services等文件中。或者可有命名服务器管理。 如DNS服务器。 NIS ,无论信息放在哪里都可以被他们访问到

    1. gethostent(),
        可以获取主机相关的信息。
        #include<netdb.h>
        struct hostent *gethostent(void); 如果成功返回指针,如果失败返回NULL
     如果成功返回指针,如果失败返回NULL
     如果成功返回指针,如果失败返回NULL
    
   2.sethostent(int stayopen);

   3.enthostent(void);
    
   4.如果主机数据文件没有打开则gethostent()会打开这个文件。函数enthostent()方法将会关闭这个文件。

   5.函数gethostent()返回的结构体如下,
       struct hostent{
    
    }

struct hostent * getnetbyaddr(uint32_t net, int type)

struct hostent * getnetbyname(const char * name);

struct netent * getnetent(void);

void setnetent(int stayopen);

void endnetent(void);



//close mouse:
 sudo rmmod psmouse

7.inet_ntop,
    socket编程时常用的参数。将一个ip数字转换成点分十进制的值。
    在客户端连接到
8.
    inet_ntop(int sa_family,&sinp_sin_addr, abuf,INET_ADDRSTRLEN);
 
9.可以使用bind函数将地址绑定到一个套字节上。

#include<sys/socket.h>
int bind(int sockfd, struct sockaddr *addr , socklen_t len)

    如果成功返回0
    失败返回-1

10.可以调用getsockname()方法来发现一个绑定套字节的地址。

#include<sys/socket.h>
int getsockname(int sockfd, struct sockaddr *restrict addr, socklen_t  *restrict alenp);

在调用getsockname函数之前,设置alenp为指向一个整形的指针。该整形指向缓冲区sockaddr的长度大小,返回的时候该值被设置为该地址的大小。如果该地址和提供缓冲区的长度
不匹配。则将其截断而不报错。如果当前没有并定到该套接字, 其结果没有定义。

如果套字节已经和对方连接,调用getpeername来找到对方的地址。

11.
    getpeername(int sockfd, struct sockaddr *restrict addr , socklen_t *restrict alenp);
    
    除了返回对方地址以外,函数getpeername() 和getsockname()一样。


12.建立链接
    #include<sys/socket.h>
    connect(int sockfd, const struct sockaddr* addr, socklen_t len);
    返回值:
    成功返回0,出错返回则返回-1
    connect函数的参数。
    
    sockfd:
        这个值是通过socket函数返回的一个套字节描述符。
    addr:
        可以通过 sockaddr_in这个结构体得到。这个结构体中包含如下成员。
        struct sockaddr_in{
            sa_family_t sin_family;
            in_port_t sin_port;
            struct in_addr sin_addr;
            
        }
    //其中端口号的初始化如下:
    htons(uint16_t hostint16); hostint16:就是要转换的ip地址。
    
    //ip地址转换。
    inet_ntop(int domain, const void * restrict addr, char* restrict str, socklen_t size);

#include<sys/socket.h>
int listen(int sockfd, int backlog)
    参数backlog提供类一个提示,用于表示该进程所要入队列的连接请求数量, 其实际值由系统决定。
    但上限由<sys/socksocket.h> 中 SOMAXCONN指定。
   
    一旦服务器调用了listen, 套字节就能接收连接请求。使用函数accept获得连接请求并建立连接。
#include<sys/socket.h>
    int accpet(int sockfd, struct  sockaddr * restrict addr, socklen_t *restrict len);
函数accpet()所返回的文件描述符号和原始

//设置socket选项。
    int    setsockopt(int sockfd, int level,  int optname, const void * optval , socklen_t optlen);
    int getsockopt(int sockfd, int level, int optname, const void *optval, socklen_t, optlen);如果返回成功则为0,若出错返回-1.














































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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值