sock编程学习1

        面试经常问到IPC机制,但没一次想到套接字。管道、先进先出、消息对立、信号量、共享内存、套接字,这些都是在同一台机子上运行的进程。不同的机子上运行的进程同性机制必须用套接字了。
 1、套接字描述符:
            套接字是通信端点的抽象,在unix系统中套接字是由文件描述符实现的
      int socket(int domain, int type, int protocol);
            domain确定通信的特性,各个域的常熟都以AF_开头,指地址组(address family)。(AF_INET,AF_INET6,AF_UNIX,AF_UNSPEC)
            type确定套接字的类型,SOCK_DGRAM,SOCK_RAW,SOCK_SEQPACKET,SOCK_STREAM。SOCK_RAW套接字提供一个借口用于直接访问下面的网络层。
            套接字是双向的,可以用shutdown来禁止套接字上的输入输出:
      int shutdown(int sockfd, int how);       how是SHUT_RD,SHUT_WR,SHUT_RDWR。
   2、字节序    (大对大,小对小)
      TCP/IP协议栈采用大端字节序。
      处理器和网络字节序转换
      #include <arpa/inet.h>
      uint32_t htonl(uint32_t hostint32);
      uint16_t htons(uint16_t hostint16);
      uint32_t ntohl(uint32_t netint32);
      uint16_t ntohs(uint16_t netint16);
      3、地址格式  
            通用地址格式:
      struct sockaddr{
          sa_family_t sa_family;
          char            sa_data[];
          .........

      }

       Internet addresses are defined in <netinet/in.h>. In the IPv4 Internet domain (AF_INET), a socket address is represented by asockaddr_in structure

   struct in_addr {
     in_addr_t       s_addr;       /* IPv4 address */
   };

   struct sockaddr_in {
     sa_family_t    sin_family;   /* address family */
     in_port_t      sin_port;     /* port number */
     struct in_addr sin_addr;     /* IPv4 address */
   };
     IP地址在二进制和字符串之间的转换:

    #include <arpa/inet.h>

    const char *inet_ntop(int domain, const void* restrict addr, char *restrict str, socklen_t size);

                                                                     Returns: pointer to address string on success, NULL on error

   int inet_pton(int domain, const char *restrict str,  void *retrcit addr);

                                                                    Returns: 1 on success, 0 if the format is invalid, or 1 on error

The inet_ntop function converts a binary address in network byte order into a text string;inet_pton converts a text string into a binary address in network byte order.
4、地址查询

      查询主机信息gethostent:

      #include <netdb.h>

     struct hostent *gethostent(void);

       Returns: pointer if OK, NULL on error

     void sethostent(int stayopen);

     void endhostent(void);

   struct hostent {
     char   *h_name;       /* name of host */
     char  **h_aliases;    /* pointer to alternate host name array */
     int     h_addrtype;   /* address type */
     int     h_length;     /* length in bytes of address */
     char  **h_addr_list;  /* pointer to array of network addresses */
     .
     .
     .
   };
      
  struct netent *getnetbyaddr(uint32_t net, int type); 
  struct netent *getnetbyname(const char *name);

  struct netent {
     char     *n_name;      /* network name */
     char    **n_aliases;   /* alternate network name array pointer */
     int       n_addrtype;  /* address type */
     uint32_t  n_net;       /* network number */
     .
     .
     .
    };
        此处省略一部分函数及结构体的介绍,因为现在一般都用新的函数 getaddrinfo

    The getaddrinfo function allows us to map a host name and a service name to an address.          ------------map映射,主机名和服务名对地址的映射

        #include <sys/socket.h>

        #include <netdb.h>

        int getaddrinfo(const char *restrict host,  const char *restrict service, const struct addrinfo *restrict hint, struct addrinfo **restrict res);

                                                                                                                                                 return : 0 if OK, 非0则是错误码

      We need to provide the host name, the service name, or both. If we provide only one name, the other should be a null pointer. The host name can be either a node name or the host address in dotted-decimal notation.

   struct addrinfo {
     int               ai_flags;       /* customize behavior */
     int               ai_family;      /* address family */
     int               ai_socktype;    /* socket type */
     int               ai_protocol;    /* protocol */
     socklen_t         ai_addrlen;     /* length in bytes of address */
     struct sockaddr  *ai_addr;        /* address */
     char             *ai_canonname;   /* canonical name of host */
     struct addrinfo  *ai_next;        /* next in list */
     .
     .
     .
   };


      服务器名可以是个端口号“字符串”。如果service在/etc/services文件里没有登记的话,要不得在/etc/services下登记服务。

Flag

Description

AI_ADDRCONFIG

Query for whichever address type (IPv4 or IPv6) is configured.

AI_ALL

Look for both IPv4 and IPv6 addresses (used only with AI_V4MAPPED).

AI_CANONNAME

Request a canonical name (as opposed to an alias).

AI_NUMERICHOST

Return the host address in numeric format.

AI_NUMERICSERV

Return the service as a port number.

AI_PASSIVE

Socket address is intended to be bound for listening. //当service是端口号的时候需要制定监听

AI_V4MAPPED

If no IPv6 addresses are found, return IPv4 addresses mapped in IPv6 format.

       getaddrinfo函数的错误处理不能用perror strerror  有专门的gai_strerror

       #include <netdb.h>                   const   char*  gai_strerror(int error);.

      getnameinfo将地址转换成主机名或者服务名。

      套接字与地址绑定:

     与客户端套接字关联的地址没有太大意义,但服务器需要给接受客户端请求的套接字绑定个众所周知的地址。

     客户端为服务器保留一个地址并且在/etc/services或者摸个名字服务中注册。

     int    bind( int sockfd, const struct sockaddr *addr, socklen_t len);                      0 if OK, 1 on error

    The port number in the address cannot be less than 1,024 unless the process has the appropriate privilege 

    For the Internet domain, if we specify the special IP address INADDR_ANY, the socket endpoint will be bound to all the system's network interfaces


        getsockname发现绑定到一个套接字的地址。

        int getsockname( int  sockfd, struct sockaddr *restrict addr,  socklen_t *restrict alenp);

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

        int getpeername(int sockfd, strcut sockaddr *restrict addr, socklen_t  *restrict addr);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值