zoukankan      html  css  js  c++  java
  • AF_INET与套接字SOCKET

    一、SOCKET——套接字

    套接字最初是为同一主机上的应用程序所创建,使得主机上运行的一个程序(又名一个进程)与另一个运行的程序进行通信。这就是所谓的进程间通信(Inter Process Communication,IPC)

    有两种类型的套接字:基于文件的和面向网络的。

    (1)基于文件的
    家族名:AF_UNIX

    又名AF_LOCAL,在POSIX1.g标准中指定,它代表地址家族(addressfamily):UNIX。其他比较旧的系统可能会将地址家族表示成域(domain)或协议家族(protocolfamily),并使用其缩写PF而非AF。类似地,AF_LOCAL(在2000~2001年标准化)将代替AF_UNIX。

    (2)面向网络的

    家族名:AF_INET

    或者地址家族:因特网。另一个地址家族AF_INET6用于第6版因特网协议(IPv6)寻址。此外,还有其他的地址家族,这些要么是专业的、过时的、很少使用的,要么是仍未实现的。在所有的地址家族之中,目前AF_INET是使用得最广泛的。

    二、套接字地址:主机-端口对

    做个比喻,套接字就像一个电话插孔,主机名和端口号就像区号和号码。
    当程序之间需要通信时,需要知道对端的主机名(IP)和端口号。
    有效的端口号范围为0~65535(小于1024的端口号预留给了系统)

    什么是Socket?

    再举一个例子:

    Lewis跟Nico两人聊QQ,QQ是一个独立的应用程序,那么它对应了两个Socket,一个在Lewis的电脑上,一个在Nico的电脑上。当Lewis对Nico说:”周末我们去开卡丁车吧!“,这句话就是一段数据,这段数据会先储存在Lewis电脑Socket上,我们在”分层网络模型“一文中提到过,TCP存在于传输层,同时,我们在”端口、IP协议“一文中又提到了TCP传输过程(三次握手建立连接,三次握手关闭连接),当Lewis的QQ和Nico的QQ连接成功后,Lewis的Socket将这段话的数据发送到Nico的电脑中,但是Nico暂时还没看到,因为数据会先存放在Nico电脑的Socket当中,然后Socket会把数据呈现给Nico看。

    到了这里不禁要问,数据传送过程中为什么要多出Socket这样东西?
    答:因为不同的应用程序对应不同的Socket,而Socket保证了QQ的数据不会到处乱跑,不会一冲动跑到MSN上去了。因为QQ和MSN两个应用程序的Socket内容是完全不同的。那么Socket里面到底是什么?
    答:Socket套接字地址!套接字地址是一个数据结构,我们仅基于TCP传输协议作为例子。套接字地址这个数据结构里面包含了:地址类型、端口号、IP地址、填充字节这4种数据。而它的数据结构原型为:

     #include <netinet/in.h>
        struct sockaddr_in{
         unsigned short         sin_family;    
         unsigned short int     sin_port;      
         struct in_addr         sin_addr;      
         unsigned char          sin_zero[8];   
      };
    

    其中:

      • sin_family表示地址类型,对于基于TCP/IP传输协议的通信,该值只能是AF_INET;
      • sin_prot表示端口号,例如:21 或者 80 或者 27015,总之在0 ~ 65535之间;
      • sin_addr表示32位的IP地址,例如:192.168.1.5 或 202.96.134.133;如果sin_addr.s_addr=0,则表示指定ip为0.0.0.0,就是本机
      • sin_zero表示填充字节,一般情况下该值为0;
        Socket数据的赋值实例:
    struct sockaddr_in Lewis;
      Lewis.sin_family      = AF_INET;
      Lewis.sin_port        = htons(80);
      Lewis.sin_addr.s_addr = inet_addr("202.96.134.133");
      memset(Lewis.sin_zero,0,sizeof(Lewis.sin_zero));

    分析:我们设置了一个名叫Lewis的套接字地址,它基于TCP/IP协议,因此sin_family的值为AF_INET,这个是雷打不动的,只要使用TCP/IP协议簇,该值就是AF_INET;htons是端口函数,以后介绍,这就表示设置了端口号为80;
    sin_addr是一个数据结构,原型是:

      struct in_addr{
         unsigned long     s_addr;
    };
    

    三、面向连接的套接字与无连接的套接字

    1、面向连接的套接字
    TCP套接字的名字SOCK_STREAM。
    特点:可靠,开销大。

    在进行通信之前必须先建立一个连接,该连接的通信提供序列化的、可靠的和不重复的数据交付,而没有记录边界。这种类型的通信也称为虚拟电路或流套接字。
    实现这种连接类型的主要协议是传输控制协议(缩写 TCP)
    为了创建 TCP套接字,必须使用 SOCK_STREAM 作为套接字类型。

    2、无连接的套接字
    UDP套接字的名字SOCK_DGRAM
    特点:不可靠(局网内还是比较可靠的),开销小。

    与虚拟电路形成鲜明对比的是数据报类型的套接字,它是一种无连接的套接字。
    在通信开始之前并不需要建立连接。此时,在数据传输过程中并无法保证它的顺序性、可靠性或重复性。数据报确实保存了记录边界,这就意味着消息是以整体发送的,而并非首先分成多个片段。
    实现这种连接类型的主要协议是用户数据报协议(缩写 UDP)。为了创建UDP套接字,必须使用SOCK_DGRAM作为套接字类型。
    UDP套接字的SOCK_DGRAM名字来自于单词“datagram”(数据报)

    参考:

    1.简单理解socket(AF_INET&SOCK_STREAM,SOCK_DGRAM)

    2.AF_INET与套接字

  • 相关阅读:
    mysql 语法
    mycat 配置简介
    redis sentinel 配置
    Spark SQL 读到的记录数与 hive 读到的不一致
    HDP3.1 中 YRAN 和 MR2 的内存大小配置的计算方式
    在 windows 下搭建 IDEA + Spark 连接 Hive 的环境
    HDP3.1 中配置 YARN 的 timeline server 使用外部的 HBase
    大规模使用 Apache Kafka 的20个最佳实践
    卸载mac版本的GlobalProtect
    js解决约瑟夫问题
  • 原文地址:https://www.cnblogs.com/gjmhome/p/13985473.html
Copyright © 2011-2022 走看看