socket编程之socket()

1 socket()

socket() 创建用于通信的终结点,并返回引用该终结点的文件描述符。成功调用返回的文件描述符是当前未被调用socket()的进程占用的最小的文件描述符。

1.1 包含头文件
#include <sys/types.h>
#include <sys/socket.h>    //包含域参数所需要的各种网络协议
1.2 函数主体
int socket(int domain, int type, int protocol);
//例如:
int clt = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);  

参数解释:

  • int domain

域参数指定通信域,即选择用什么样的通信协议,包括 AF_UNIX,、AF_LOCAL、AF_INET、AF_INET6、AF_IPX、AF_ALG等等。目前主要使用的为**AF_LOCAL(用于本地进程间的通信)、AF_INET(用于IPv4协议)。**其余的有需要时在做补充。

  • int type

套接字具有指示的类型,该类型指定通信语义,包括SOCK_STREAM、SOCK_DGRAM、SOCK_SEQPACKET、SOCK_RAW 、SOCK_RDM等。目前主要使用的为**SOCK_STREAM(实现TCP字节流通信。可能支持带外数据传输机制。)、SOCK_DGRAM(实现UDP数据报通信)。**其余的有需要时在做补充

从 Linux 2.6.27 开始,类型参数还可以实现对socket的进一步控制,通过按为OR操作实现以下操作:

SOCK_NONBLOCK : 设置socket为非阻塞类型,在此处设置可以节省对fcntl的额外调用,进一步减小开销
SOCK_CLOEXEC  : 在进程调用exec函数族时,文件描述符就会自动关闭,无需手动关闭。   

这里对SOCK_CLOEXEC和带外数据(out-of-band data)作进一步解释(新手可以不看):

在多进程的场景中,在fork()函数后,由于子进程会拷贝父进程几乎所有的内容,这其中就包括了父进程打开的文件描述符,因此子进程和父进程使用的是相同的文件描述符。但是,当子进程执行exec()函数族时,由于子进程会使用新的内容覆盖父进程所有的数据,这其中就包括打开的文件描述符,此时打开的文件描述符就无法关闭了,因此在调用exec函数族前需要手动关闭文件描述符。而设置此参数即可以避免这种情况

带外数据(out-of-band data)是指建立连接双方中的一方有重要的事情需要及时通知对方,这种数据成为带外数据,发送优先级要高于带内数据(在消息缓存队列中排队的数据成为“带内数据”),带外数据发送不需要建立新的连接。对带外数据的实现一般使用BSD的紧急数据指针方式,需要接收方通过判断read()函数的返回值来判断带外数据。

  • int protocol

用来指定协议的特类型,一般设置为0,表示接收协议的任何类型,后续的处理由应用程序自己实现。

1.3 返回值

成功后,将返回新套接字的文件描述符。出错时,返回 -1,并正确设置 errno,错误类型如下:

错误类型解释
EACCES创建指定类型和/或协议的套接字的权限被拒绝。
EAFNOSUPPORT不支持指定的地址系列。
EINVAL未知的协议,或协议系列不可用。或类型中的标志无效。
EMFILE已达到每个进程对打开的文件描述符数的限制。
ENFILE已达到系统范围内对打开的文件总数的限制。
ENOBUFS or ENOMEM可用内存不足。 在释放足够的资源之前,无法创建套接字。
EPROTONOSUPPORT此域中不支持协议类型或指定的协议。
1.4 结束

socket()函数介绍至此结束,虽然这个函数的使用一般来说并不会出错,但是建议养成良好的编程习惯,每次调用都对器返回值进行判断。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值