SOCKET 函数使用(译)

源自:http://man7.org/linux/man-pages/man2/socket.2.html

函数名

socket – 为通信创建一个节点。

定义

 #include <sys/types.h>          /* See NOTES */
 #include <sys/socket.h>
 int socket(int domain, int type, int protocol);

描述

socket函数创建一个通信节点,并返回一个描述符。

参数domain 指的是通信地址,这个决定了 protocol 用于通信的协议。具体的通信协议在<sys/socket.h>中定义,

目前定义的协议有:

       AF_UNIX, AF_LOCAL   本地协议              unix(7)
       AF_INET             IPv4 网络协议         ip(7)
       AF_INET6            IPv6 网络协议         ipv6(7)
       AF_IPX              IPX - Novell 协议
       AF_NETLINK          内核用户接口设备协议    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

socket通信中有type参数,标明通信的方式,目前定义的通信方式有:

  1. SOCK_STREAM :双向可靠,有连接的二进制流通信,大型数据传输,也可以支持。
  2. SOCK_DGRAM :支持 数据包通信(无连接,最大长度固定的通信机制,UDP)。
  3. SOCK_SEQPACKET:提供一种双向可靠,最大长度固定的有链接的通信,每次调用时候每个消费者都需要读取整个包。
  4. SOCK_RAW:提供一种原生的网络通信方式(用于自定义通信,黑客,高级网络通信)
  5. SOCK_RDM: 可靠数据报,但是不保证传输顺序。
  6. SOCK_PACKET:过时了,不要再新程序中使用。

不是全部的通信协议都支持所有的通信方式的。Linux 2.6.27之后,type参数有了第二个作用:指定socket类型的情况下,它可能包含一些位运算或者下面的值,去修正socket的行为

  1. SOCK_NONBLOCK 在新打开的设置O_NONBLOCK 文件状态符,有了这个标志位,就不用再每次调用fcntl()了。对于socket 的recv()和send()采用非阻塞的方式,对于磁盘I/O ,非阻塞并不产生效果
  2. SOCK_CLOEXEC 在新打开的文件描述符上面设置 FD_CLOEXEC 标志位,看O_CLOEXEC 在open函数中的作用,就知道这个标志位的意义了

protocol 指定socket中用的协议。一般来说,一种socket类型,只有一种协议对应,这个时候,protocol 可以为0,但是也存在一种socket类型有多重通信协议,这个时候,就必须指定具体的通信协议。协议号指定为通信的时候被取代的“通信域”。
SOCK_STREAM 类型是双工通信的二进制流。不限制通信量的大小。在收发数据的时候,socket流必须是在连接状态的,连接是通过 connect()函数创建,连接之后,数据通过read和write或者其他的变体,比如send,recv 传输。通过close关闭会话。大数据包可以通过send发送,recv接受。

SOCK_STREAM 通信协议保证数据不会丢失或者重复,如果有数据段在一个合理的时间内不能成功发送,该连接会被认为已死,如果设置了SO_KEEPALIVE,socket协议会检查是不是有其他的符合通信协议的链路存在,如果在已断开的流里收发数据,该进程会收到SIGPIPE 信号,会令未处理该信号的进程异常退出。
SOCK_SEQPACKET 和SOCK_STREAM 类似,唯一的区别是调用read()的时候,返回的只是请求的数据量。多余的数据会被丢弃,数据报范围内的数据都会被保留。

SOCK_DGRAM和SOCK_RAW 允许发送数据包给sendto 函数,数据包通常有recvfrom接收,该函数返回下一个数据包内容,以及发送者的地址。

SOCK_PACKET 是一个过气的函数,用于从设备驱动直接接收原生的数据包,使用packet函数替代。

Leave a comment

Your email address will not be published.

*