网络IPC

一、接口说明

1、socket 函数

功能:创建网络套接字
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);

   /*
   domain: 协议族(某种意义上看,它指定了网络层协议)
    Name                Purpose                          Man page
   AF_UNIX, AF_LOCAL   Local communication              unix(7)
   AF_INET             IPv4 Internet protocols          ip(7)
   AF_INET6            IPv6 Internet protocols          ipv6(7)
   AF_IPX              IPX - Novell protocols
   AF_NETLINK          Kernel user interface device     netlink(7)
   AF_X25              ITU-T X.25 / ISO-8208 protocol   x25(7)
   AF_AX25             Amateur radio AX.25 protocol
   AF_ATMPVC           Access to raw ATM PVCs
   AF_APPLETALK        AppleTalk                        ddp(7)
   AF_PACKET           Low level packet interface       packet(7)
   AF_ALG              Interface to kernel crypto API

   type:(概念上将,这字段靠向传输层协议)
   
   SOCK_STREAM     Provides sequenced, reliable, two-way, connection-based byte streams.  An  out-
                   of-band data transmission mechanism may be supported.
  
   SOCK_DGRAM      Supports  datagrams  (connectionless,  unreliable  messages  of a fixed maximum
                   length).

   SOCK_SEQPACKET  Provides a sequenced, reliable, two-way connection-based data transmission path
                   for datagrams of fixed maximum length; a consumer is required to read an entire
                   packet with each input system call.

   SOCK_RAW        Provides raw network protocol access.

   SOCK_RDM        Provides a reliable datagram layer that does not guarantee ordering.

   SOCK_PACKET     Obsolete and should not be used in new programs; see packet(7).

	protocol:(具体协议,比如TCP/IP)
	具体协议,一般来说,domain和type指定完毕,protocol应该默认被推测出来;
	但是如果满足的协议有多个,需要用户指出需要的协议是哪一个
   */

2、端到端或者点到点

2.1 字节序转换

   #include <arpa/inet.h>

   uint32_t htonl(uint32_t hostlong);

   uint16_t htons(uint16_t hostshort);

   uint32_t ntohl(uint32_t netlong);

   uint16_t ntohs(uint16_t netshort);

2.2 地址类型

  • 不同操作系统,不同通信协议其地址数据格式是不同的:为了体现点到点或者端到端通信,IP网络协议都有ip字段,传输层协议有端口字段

     POSIX.1-2001, POSIX.1-2008
     /*af:AF_INET或者AF_INET6,分别表示ipv4.,ipv6*/
     /*
     	组合1:
     	(AF_INET,"192.168.1.101",struct in_addr*)
     	组合2:
     	(AF_INET6,"255.255.255.255.255.90",struct in6_addr*)
     */
     const char *inet_ntop(int af, const void *src,
                         char *dst, socklen_t size);
    
     int inet_pton(int af, const char *src, void *dst);
    

2.3、套接字与地址绑定

   int bind(int sockfd, const struct sockaddr *addr,
            socklen_t addrlen);

示例代码:


       #include <sys/socket.h>
       #include <sys/un.h>
       #include <stdlib.h>
       #include <stdio.h>
       #include <string.h>

       #define MY_SOCK_PATH "/somepath"
       #define LISTEN_BACKLOG 50

       #define handle_error(msg) \
           do { perror(msg); exit(EXIT_FAILURE); } while (0)

       int
       main(int argc, char *argv[])
       {
           int sfd, cfd;
           struct sockaddr_un my_addr, peer_addr;
           socklen_t peer_addr_size;

           sfd = socket(AF_UNIX, SOCK_STREAM, 0);
           if (sfd == -1)
               handle_error("socket");

           memset(&my_addr, 0, sizeof(struct sockaddr_un));
                               /* Clear structure */
           my_addr.sun_family = AF_UNIX;
           strncpy(my_addr.sun_path, MY_SOCK_PATH,
                   sizeof(my_addr.sun_path) - 1);

           if (bind(sfd, (struct sockaddr *) &my_addr,
                   sizeof(struct sockaddr_un)) == -1)
               handle_error("bind");

           if (listen(sfd, LISTEN_BACKLOG) == -1)
               handle_error("listen");

           /* Now we can accept incoming connections one
              at a time using accept(2) */

           peer_addr_size = sizeof(struct sockaddr_un);
           cfd = accept(sfd, (struct sockaddr *) &peer_addr,
                        &peer_addr_size);
           if (cfd == -1)
               handle_error("accept");

           /* Code to deal with incoming connection(s)... */

           /* When no longer required, the socket pathname, MY_SOCK_PATH
              should be deleted using unlink(2) or remove(3) */
       }


2.4、客户网络端口请求建立连接

   #include <sys/types.h>          /* See NOTES */
   #include <sys/socket.h>

   int connect(int sockfd, const struct sockaddr *addr,
               socklen_t addrlen);

!!!需要注意的是,因为服务器可能十分繁忙;用户建立连接的请求可能会失败(客户程序需要处理这种情况)
又及:
connect常见于面向连接的应用,但是使用SOCK_DGRAM这种非面向连接的模式也是不错的选择。这样以后发送报文的默认地址会成为connect连接指定的地址

2.5、服务器网络端口接收连接请求

  • 首先,服务器调用listen函数
    listen设置socket为被动接收连接请求模式,同时指定了可接受的连接上限(当连接超过backlog之后,客户端连接失败)

     #include <sys/types.h>          /* See NOTES */
     #include <sys/socket.h>
    
     int listen(int sockfd, int backlog);
    
  • 然后,服务器调用accept函数等待用户连接请求
    accept返回一个connet fd,表示一个建立的链接…connect fd与sockfd有着相同类型的protocol,但是彼此并不关联
    (getsockname getpeername可以获取本端或者对端的网络地址)

     #include <sys/types.h>          /* See NOTES */
     #include <sys/socket.h>
    
     int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    

3、数据传输

通过connect fd用户有多种选择实现发送数据或者接收数据

3.1 write/read

功能简单,但易用,同时具备较好的兼容性

3.2 send/sendto/sendmsg/recv/recvfrom/recvmsg

发送接口

   #include <sys/types.h>
   #include <sys/socket.h>
   /*socket处于链接状态*/
   ssize_t send(int sockfd, const void *buf, size_t len, int flags);
  /*socket 处于非链接状态*/
   ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                  const struct sockaddr *dest_addr, socklen_t addrlen);
   /*用于发送多重缓冲数据,类似writev*/        
   ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);

      send与write区别在于flags参数
在这里插入图片描述

接收接口

   #include <sys/types.h>
   #include <sys/socket.h>

   ssize_t recv(int sockfd, void *buf, size_t len, int flags);

   ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                    struct sockaddr *src_addr, socklen_t *addrlen);

   ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

flags
在这里插入图片描述
recvmsg返回flag状态
在这里插入图片描述

4、实例

4.1

4.2

4.3

5、其它

5.1 配置套接字

用户可以配置传输层,网络层等协议栈的特性

   #include <sys/types.h>          /* See NOTES */
   #include <sys/socket.h>

   int getsockopt(int sockfd, int level, int optname,
                  void *optval, socklen_t *optlen);
   int setsockopt(int sockfd, int level, int optname,
                  const void *optval, socklen_t optlen);

5.2 带外数据

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值