socket函数
- 头文件: #include <sys/socket.h>
- 函数原型:int socket(int af, int type, int protocol);
- 返回值:函数调用成功,返回套接字的文件描述符,失败返回-1
socket函数调用成功会创建一个协议族为af,协议类型为type,协议编号为protocol的套接字
参数详解
参数一:af
通信协议类型,socket函数使用该参数选择通信协议族,其可以使用如下值:
- PF_UNIX,PF_LOCAL 本地通信
- AF_INET,PF_INET IPV4协议
- PF_INET6 IPV6协议
- PF_IPX IPX-Novell协议
- PF_NETLINK 内核用户界面设备
- PF_X25 ITU-T X25/ISO-8208协议
- PF_AX25 Amateur radio AX.25
- PF_ATMPVC 原始ATM PVC访问
- PF_APPLETALK Appletalk
- PF_PACKET 底层包访问
参数二:type
type用于设置套接字通信的类型,有流式套接字(SOCKET_STREAM)和数据包套接字(SOCK_DGRAM)
- SOCK_STREAM TCP连接,提供有序化的、可靠的、双向连接的字节流。支持带外数据传输
- SOCK_DGRAM UDP连接
- SOCK_SEQPACKET 序列化包,提供一个序列化的、可靠的、双向的基本连接的数据传输通道,数据长度定长。每次调用读取数据时,系统会将全部的数据读出
- SOCK_RAW 提供原始的网络协议访问
- SOCK_RDM 提供可靠的报文,不过数据可能有乱序
- SOCK_PACKET 专用类型,不能在通用程序中使用
并非所有协议族都有这些协议类型
参数三:protocol
用于制定某个协议的特定类型,即type类型中的某个类型
通常一种协议只有一种类型,那样该参数可以直接被设置为0;如果协议有多种类型,则需要指定协议类型
- SOCK_STREAM 该参数表示一个双向的字节流,与管道类似。流式套接字在进行数据收发之前必须 已经建立连接,连接使用connect函数,一旦连接可以使用read/write进行数据的读写操作
- SOCK_DGRAM和SOCK_RAW这两种套接字可以使用sendto和recvfrom收发数据,recvfrom可以接受指定IP的数据
带外数据
传输层协议使用带外数据来发送一些重要数据,如果通信一方有重要数据需要通知对方时,协议能够将这些数据快速地发送到对方
为了发送这些数据,协议一般不使用与普通数据相同的通道,而是使用另外的通道
Linux系统的套接字支持底层协议发送和接收带外数据,但是TCP协议没有真正意义上的带外数据
为了发送重要协议,TCP提供了一种紧急模式的机制,当TCP协议的URG位被设置之后,表示进入紧急模式
错误说明
并非每次创建套接字都是顺利的,创建错误的类型如下所示:
- EACCES 没有权限创建该类型的socket
- EAFNOSUPPORT 不支持的地址类型
- EINVAL 不支持此协议
- EMFILE 进程文件表溢出
- ENFILE 打开文件过多,达到系统允许的最大文件数量
- ENOBUFS/ENOMEM 内存不足
- EPROTONOSUPPORT 协议类型不存在
程序示例
#include <stdio.h>
#include <sys/socket.h>
int main()
{
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
printf("The socket fd is: %d\n", sock_fd);
}
程序运行结果如下:
The socket fd is: 3