socket编程(一)

socket编程 (一)#

创建socket

#include<sys/types.h>
#include<sys/socket.h>
int socket(int __domain,int __type,int __protocol)

__domain参数告诉系统使用哪个底层协议族。对TCP/IP协议族而言,该参数应该设置为PF_INET(Protocol Family of Internet,用于IPv4)或者PF_INET6(用于IPv6);对于UNIX本地域协议族而言,该参数应该设置为PF_UNIX。

__type参数指定服务类型。服务类型主要有SOCK_STREAM服务(流服务)和SOCK_UGRAM(数据包)服务。对TCP/IP协议族而言,其取值SOCK_STREAM表示传输层使用TCP协议,取SOCK_DGRAM表示传输层使用的是UDP协议。

自linux内核版本2.6.17开始type参数可以接收上述服务类型和下面两个重要的标志相与的值:SOCK_NOBLOCK和SOCK_CLOEXEC。它们分别表示将新创建的socket设为非阻塞的,以及用fork调用创建子进程时在子进程中关闭该socket。

__protocol参数是在前两个参数构成的协议集合下,在选择一个具体的协议。几乎在所有情况下,我们都应该把它设置为0,表示使用默认协议。

socket系统调用成功时返回一个socket文件描述符,失败则返回-1并设置errno。

命名socket

创建socket时,我们给它指定了地址族,但是并未指定使用该地址族中的那个具体socket地址。将一个socket与socket地址绑定称为给socket命名。在服务器程序中,我们通常要命名socket,因为只有命名后客户端才知道该如何连接它。客户端通常不需要命名socket,而是采用匿名的方式,即使用操作系统自动分配的socket地址。命名socket的系统调用是bind,其定义如下

	#include<sys/types.h>
	#include<sys/socket.h>
	int bind(int __fd,__CONST_SOCKADDR_ARG __addr,socklen_t __len)

bind将__addr所指的socket地址分配给未命名的__fd文件描述符,__len参数指出该socket地址的长度。
bind成功时返回0,失败时返回-1并设置errno。其中两种常见的errno是EACCES和EADDRINUSE,他们的含义分别为:

EACCES,被绑定的地址是受保护的地址,仅超级用户可以访问,比如普通用户将socket绑定到知名服务端口(0——1023)上时,bind将返回EACCESA错误。

EADDRINUSE,被绑定的地址正在使用中。比如将socket绑定到一个处于TIME_WAIT状态的socket。

监听socket

socket被命名之后,还不能马上接收客户连接,我们需要使用如下系统调用来创建一个监听队列一存放待处理的客户连接:

	#include<sys/socket.h>
	int listen(int __fd,int __n)

__参数指定被监听的socket。__参数提示内核监听队列的最大长度。监听队列的长度如果超过__n,服务器将不受理新的客户连接,客户端也将收到ECONNREFUSED错误信息。在内核2.2之前,__n参数是指所有处于半连接(SYN_RCVD)和完全连接状态(ESTABLISHED)的socket的上限。但自内核版本2.2之后,它只表示处于完全连接状态的socket的上限,处于半连接状态的socket的上限则有/proc/sys/net/ipv4/tcp_max_syn_backlog内核参数定义。__n参数的典型值是5。

listen成功是返回0,失败返回-1并设置errno。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值