• 【转载】4.Linux 网络编程——套接字的介绍


    一、套接字概述

    套接字是一种通信机制(通信的两方的一种约定),凭借这种机制,不同主机之间的进程可以进行通信。我们可以用套接字中的相关函数来完成通信过程


    套接字的特性有三个属性确定,它们是:域(domain),类型(type),和协议(protocol)


    二、套接字的域

    域指定套接字通信中使用的网络介质。最常见的套接字域是 AF_INET(IPv4)或者AF_INET6(IPV6),它是指 Internet 网络,许多 Linux 局域网使用的都是该网络,当然,因特网自身用的也是它。


    三、套接字类型

    流套接字(SOCK_STREAM)

    流套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复发送,并按顺序接收。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即TCP(The Transmission Control Protocol)协议。

    数据报套接字(SOCK_DGRAM)

    数据报套接字提供了一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP(User Datagram Protocol)协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。

    原始套接字(SOCK_RAW)

    原始套接字与标准套接字(标准套接字指的是前面介绍的流套接字和数据报套接字)的区别在于:原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送数据必须使用原始套接字。


    五、套接字协议(协议类别)

    只要底层的传输机制允许不止一个协议来提供要求的套接字类型,我们就可以为套接字选择一个特定的协议。通常使用默认即可(也就是最后一个参数填“0”)


    创建套接字

    socket 系统调用创建一个套接字并返回一个描述符,该描述符可以用来访问该套接字。


    需要头文件:#include <sys/socket.h>

    int socket(int family,int type,int protocol);

    功能

    创建一个用于网络通信的 socket 套接字(描述符)

    参数

    family:协议族(AF_UNIX、AF_INET、AF_INET6、PF_PACKET等)

    最常见的套接字域是 AF_UNIX 和 AF_INET,前者用于通过 Unix 和 Linux 文件系统实现的本地套接字,后者用于 Unix 网络套接字。AF_INET 套接字可以用于通过包括因特网在内的 TCP/IP 网络进行通信的程序。微软 Windows 系统的 winsock 接口也提供了对这个套接字域的访问功能。

    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
    1. /* 
    2.  * Address families. 
    3.  */  
    4. #define AF_UNSPEC       0               /* unspecified */  
    5. #define AF_UNIX         1               /* local to host (pipes, portals) */  
    6. #define AF_INET         2               /* internetwork: UDP, TCP, etc. */  
    7. #define AF_IMPLINK      3               /* arpanet imp addresses */  
    8. #define AF_PUP          4               /* pup protocols: e.g. BSP */  
    9. #define AF_CHAOS        5               /* mit CHAOS protocols */  
    10. #define AF_IPX          6               /* IPX and SPX */  
    11. #define AF_NS           6               /* XEROX NS protocols */  
    12. #define AF_ISO          7               /* ISO protocols */  
    13. #define AF_OSI          AF_ISO          /* OSI is ISO */  
    14. #define AF_ECMA         8               /* european computer manufacturers */  
    15. #define AF_DATAKIT      9               /* datakit protocols */  
    16. #define AF_CCITT        10              /* CCITT protocols, X.25 etc */  
    17. #define AF_SNA          11              /* IBM SNA */  
    18. #define AF_DECnet       12              /* DECnet */  
    19. #define AF_DLI          13              /* Direct data link interface */  
    20. #define AF_LAT          14              /* LAT */  
    21. #define AF_HYLINK       15              /* NSC Hyperchannel */  
    22. #define AF_APPLETALK    16              /* AppleTalk */  
    23. #define AF_NETBIOS      17              /* NetBios-style addresses */  
    24. #define AF_VOICEVIEW    18              /* VoiceView */  
    25. #define AF_FIREFOX      19              /* FireFox */  
    26. #define AF_UNKNOWN1     20              /* Somebody is using this! */  
    27. #define AF_BAN          21              /* Banyan */  
    28.   
    29. #define AF_MAX          22  


    type:套接字类型(SOCK_STREAM、SOCK_DGRAM、SOCK_RAW等)

    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
    1. /* 
    2.  * Types 
    3.  */  
    4. #define SOCK_STREAM     1               /* stream socket */  
    5. #define SOCK_DGRAM      2               /* datagram socket */  
    6. #define SOCK_RAW        3               /* raw-protocol interface */  
    7. #define SOCK_RDM        4               /* reliably-delivered message */  
    8. #define SOCK_SEQPACKET  5               /* sequenced packet stream */  

    protocol:协议类别(0、IPPROTO_TCP、IPPROTO_UDP等),设为 0 表示使用默认协议。

    返回值

    成功:套接字

    失败(<0)

    创建 UDP 套接字示例:

    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
    1. int sockfd;  
    2. sockfd = socket(AF_INET, SOCK_DGRAM, 0);  
    3. if(sockfd < 0)  
    4. {  
    5.     perror("socket");  
    6.     exit(-1);  
    7. }  


    套接字地址

    每个套接字(端点)都有其自己的地址格式,对于 AF_UNIX 套接字来说,它的地址由结构 sockaddr_un 来描述,该结构体定义在头文件 sys/un.h 中,如下:

    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
    1. struct sockaddr_un {  
    2.     sa_family_t  sun_family; //套接字域  
    3.     char         sun_path[];//名字  
    4. };  

    而在 AF_INET 域中,套接字地址结构由 sockaddr_in 来指定,该结构体定义在头文件 netinet/in.h 中:
    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
    1. struct sockaddr_in {  
    2.     short int  sin_family;//套接字域  
    3.     unsigned short int   sin_port;//端口  
    4.     struct in_addr   sin_addr;  
    5. }  

    IP 地址结构 in_addr 被定义如下:

    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
    1. struct in_addr {  
    2.     unsigned long int  
    3. }
    无欲则刚 关心则乱
  • 相关阅读:
    strutr2运行流程
    ConcurrentHashMap原理分析
    面试题集锦
    jvm如何知道那些对象需要回收
    java中volatile关键字的含义
    关于Java类加载双亲委派机制的思考(附一道面试题)
    new关键字和newInstance()方法的区别
    Java中创建对象的5种方式 &&new关键字和newInstance()方法的区别
    字符串中第一个只出现一次的字符
    二进制数中1的个数
  • 原文地址:https://www.cnblogs.com/xjyxp/p/11146797.html
Copyright © 2020-2023  润新知