• Linux IPC BSD socket编程基础


    头文件

    #include<unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include<sys/un.h>	 	#include <netinet/in.h>
    #include<string.h>		#include <arpa/inet.h>
    

    socket()

    //创建网络端点,返回socket文件描述符,失败返回-1设errno
    int socket(int domain, int type, int protocol);
    

    domain :协议族(protocol family)(网络通讯(IP)还是本地通讯(xxx.socket))

    • AF_LOCAL本地通讯/AF_UNIX/
    • AF_INET用于实现给予ipv4网络协议的网络协议
    • AF_INET6用于实现给予ipv6网络协议的网络协议
    • AF_IPXIPX - Novell protocols
    • AF_NETLINKKernel user interface device
    • AF_X25 ITU-T X.25 / ISO-8208 protocol
    • AF_AX25 Amateur radio AX.25 protocol
    • AF_ATMPVC Access to raw ATM PVCs
    • AF_APPLETALK Appletalk
    • AF_PACKET Low level packet interface

    type :协议(TCP还是UDP还是其他的)

    • SOCK_STREAM //流式套接字, 实现包括但不限于TCP协议,which is有序,可靠双向面向连接的字节流通信方式
    • SOCK_DGRAM //数据报套接字, 实现包括但不限于UDP协议, which is不可靠,无连接的数据报通信方式
    • SOCK_SEQPACKET
    • SOCK_RAW //原始套接字,可以编写自己的传输层协议
    • SOCK_RDM
    • SOCK_PACKET

    can be bitwised:

    • SOCK_NONBLOCK //将O_NONBLOCK文件状态标识符放在新打开的文件描述符上,将打开的文件设为非阻塞。也可以通过fcntl()达到同样的目的
    • SOCK_CLOEXEC //将 close-on-exec (FD_CLOEXEC)文件标识符放在新打开的文件描述符上。参见open()
      protocol: 特殊协议, 一般给0

    Note:
    虽然socket返回的sockfd就是一个文件描述符,但不是所有的以文件描述符为参数的函数都可以操作sockfd,比如,和管道文件一样,sockfd同样不能被lseek()操作,下面是一些以文件描述符为参数的函数在操作sockfd时的行为(取自《UNIX环境高级编程》P476)

    close()         //释放sockfd
    Dup(),dup2()   //和一般的文件描述符一样复制
    fchdir()        //失败
    fchmod()        //未指定
    fchown()        //由实现定义
    fcntl()         //支持一些命令,eg:F_DUFD,F_DUPFD_CLOEXEC,F_GETFD,F_GETFL,F_GETOWN,F_SETFD,F_SETFL,F_SETOWN
    Fdatasync()和fsync()    //
    fstat()         //由实现定义
    ftruncate()     //未指定
    ioctl()         //支持部分指令,依赖于底层驱动
    lseek()         //由实现定义,失败会设errno为ESPIPE
    mmap()          //未指定
    poll()          //正常工作
    read()/readv()  //与没有flag的recv()等价
    select()        //正常工作
    write()/writev()    //与没有flag的write()等价
    

    getsockopt()/setsockopt()

    //获得sockfd指向的socket的属性
    int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
    //设置sockfd指向的socket的属性,成功返回0,失败返回-1设errno。
    int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
    

    level :选项级别

    • SOL_SOCKET:指定设置属性在socket API层次,即通用socket选项
    • IPPROTO_IP:IP选项。
    • IPPROTO_TCP:TIP选项。

    optname:选项名

    • SO_BROADCAST:广播

    optval:存放选项值的缓冲区地址
    optlen:缓冲区长度

    准备通信地址:

    struct sockaddr{	//主要用于函数的形参类型, 很少定义结构体变量使用, 叫做通用的通信地址类型//$man bind
    	sa_family_t 	sa_family;
    	char        	sa_data[14];
    }
    struct sockaddr_un{	//准备本地通信的通信地址	//$man un.h
    	sa_family_t  	sun_family;//协议族,就是socket()的domain的AF_LOCAL
    	char         	sun_path[];//文件的路径
    }
    struct sockaddr_in{	//准备网络通信的通信地址	//$man in.h
    	sa_family_t	sin_family;   	//协议族, 就是socket()的domain的AF_INET
    	in_port_t       sin_port;   //端口号
    	struct in_addr	sin_addr;   //IP地址
    }
    struct in_addr{	
        in_addr_t	s_addr;		//整数类型的IP地址
    }
    

    htonl()/htons()/ntohl()/ntohs()

    //主机和网络字节序转换
    uint32_t htonl(uint32_t hostlong);converts the unsigned integer hostlong from  host byte order to network byte order.
    uint16_t htons(uint16_t hostshort);converts the unsigned short integer hostshort from host byte order to network byte order.
    uint32_t ntohl(uint32_t netlong);  converts the unsigned integer netlong from network byte order to host byte order.
    uint16_t ntohs(uint16_t netshort); converts the unsigned short integer netshort from network byte order to host byte
    

    inet_aton()/inet_addr()/inet_lnaof()/inet_netof()/inet_network()/inet_ntoa()/inet_makeaddr()

    //IP地址格式转换,返回对应格式的IP地址
    int 	·	inet_aton(const char *cp, struct in_addr *inp);
    in_addr_t 	inet_addr(const char *cp);			//将字符串形式的IP地址转换为整数类型
    in_addr_t 	inet_lnaof(struct in_addr in);
    in_addr_t 	inet_netof(struct in_addr in);
    in_addr_t 	inet_network(const char *cp);
    char*		inet_ntoa(struct in_addr in);		//将结构体类型的IP地址转换为字符串类型
    struct in_addr inet_makeaddr(int net, int host);
    

    bind()

    //把通信端口(可能还有地址)和socket文件描述符绑定,用在服务器端,成功返回0,失败返回-1设errno
    int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    

    sockfd: socket文件的fd(returned by socket())
    addr: 需要强制类型转换成socketaddr_un或soketaddr_in, 参见上
    addrlen: 通信地址的大小, 使用sizeof();

    Note:一个网卡一个MAC和一个ip地址,如果将地址置为INADDR_ANY(就是0),那么表示从所有的网卡接收消息,如果希望只接收特定网卡的消息,就需要将其ip地址与socket绑定

    connect():

    //初始化一个socket的连接,用在客户端,成功返回0,失败返回-1设errno
    int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
    

    sockfd: socket文件的fd(returned by socket())
    addr: 需要强制类型转换成socketaddr_un或soketaddr_in, 参见上
    addrlen: 通信地址的大小, 使用sizeof();

    shutdown()

    //将一个socket设为不活动状态。成功返回0,失败返回-1设errno
    int shutdown(int sockfd, int how);
    

    sockfd:socket文件的文件描述符
    how:shutdown的方式

    • SHUT_RD关闭socket的读端
    • SHUT_WR关闭socket的写端
    • SHUT_RDWR关闭socket的读端和写端

    当我们close(sockfd)的时候,其实是使引用该文件的文件描述符个数-1,只有当所有引用该文件的文件描述符都被close()时,这个文件才会真正被释放,比如我们在close一个文件描述符之前调用了dup()来复制这个文件描述符,那么这个文件描述符指向的文件表其实还是存在的。当这里的文件描述符指的是socketfd时也是同样的道理。而shutdown()可以直接将该sockfd指向的socket设为不活动状态,那么其他指向该socket的fd也会直接受到影响

    网络信息检索函数

    //获取主机名
    gethostname();
    
    //获取与socket相连的远程协议的地址
    getscokname()
    
    //获得本地socket协议地址
    getsockname()
    
    //根据主机名获得主机信息
    gethostbyname()
    
    //根据主机地址取主机信息
    gethostbyaddr()
    
    //根据协议名取得主机协议信息
    getprotobyname()
    
    //根据协议号取得主机协议信息
    getprotobynumber()
    
    //根据服务名取得相关服务信息
    getservbyname()
    
    //根据端口号取得相关服务信息
    getservbyport()
    
  • 相关阅读:
    Axure案例:用中继器实现便捷好用的3级菜单--转载
    我说CMMI之七:需求管理过程域--转载
    我说CMMI之六:CMMI的评估--转载
    我说CMMI之五:CMMI 4个等级的区别--转载
    我说CMMI之四:CMMI的表示方法--转载
    我说CMMI之三:CMMI的构件--转载
    我说CMMI之二:CMMI里有什么?--转载
    我说CMMI之一:CMMI是什么--转载
    PMBOK :美国的项目管理知识体系
    有关 CMMI
  • 原文地址:https://www.cnblogs.com/xiaojiang1025/p/5938001.html
Copyright © 2020-2023  润新知