socket API通俗理解

来源:互联网 发布:windows命令 编辑:程序博客网 时间:2024/06/06 07:07
1、 socket(int family,int type,int protocol) 返回sockfd C/S
family指明了协议族/域,通常AF_INET、AF_INET6、AF_LOCAL等;
type是套接口类型,主要SOCK_STREAM、SOCK_DGRAM、SOCK_RAW;
SOCK_STREAM:流套接口,对应于TCP协议,应向应用程序提供可靠地面向链接的数据传输服务。
       也称面向连接的套接口、TCP套接口等。
       SOCK_DGRAM:数据报套接口,对应于UDP协议,向应用程序提供不可靠的、非链接的数据报通信方式。
       也称为无连接套接口、面向消息套接口、UDP套接口等。
       SOCK_RAW:原始套接口,可以读写ICMP、IGMP报文,可用于从IP头起构造自己的报文。
protocol(指明使用哪个协议)一般取0使内核自动选择。
#define IPPROTO_IP              0               /* dummy for IP */
#define IPPROTO_ICMP            1               /* control message protocol */
#define IPPROTO_IGMP            2               /* group management protocol */
#define IPPROTO_GGP             3               /* gateway^2 (deprecated) */
#define IPPROTO_TCP             6               /* tcp */
#define IPPROTO_PUP             12              /* pup */
#define IPPROTO_UDP             17              /* user datagram protocol */
#define IPPROTO_IDP             22              /* xns idp */
#define IPPROTO_ND              77              /* UNOFFICIAL net disk proto */
2、int bind(int sockfd,const struct sockaddr*myaddr,socklen_t addrlen) S
成功返回0,失败-1
当socket函数返回一个描述符时,只是存在于其协议族的空间中,并没有分配一个具体的协议地址(这里指IPv4/IPv6和端口号的组合),bind函数可以将一组固定的地址绑定到sockfd上。
sockfd是socket函数返回的描述符;
myaddr指定了想要绑定的IP和端口号,均要使用网络字节序-即大端模式;
addrlen是前面struct sockaddr(与sockaddr_in等价)的长度。

3、int listen(int sockfd,int backlog) S
当listen被服务器调用时,主要做两件事:
1、当函数socket创建一个套接口时,被假设成主动套接口,是会调用connect函数发起连接的客户端套接口;
listen将未连接的套接口转化为被动套接口,指示内核应接受指向此套接口的连接请求
2、参数backlog规定了内核为此套接口排队的最大连接数
一般说来,listen在socket和bind之后,在accept之前调用

4、int connect(int sockfd,const struct sockaddr* addr,socklen_t addrlen) C
通过此函数建立于TCP服务器的连接,实际是发起三次握手过程,仅在连接成功或失败后返回。参数sockfd是本地描述符,addr为服务器地址,addrlen是socket的地址长度。
UDP的connect函数,结果与tcp调用不相同,没有三次握手过程。内核只是记录对方的ip和端口号,他们包含在传递给connect的套接口地址结构中,并立即返回给调用进程。

5、int accept(int sockfd,const struct sockaddr* addr,socklen_t addrlen) S

调用accept 后生成一个newsockfd,newsockfd用来和客户端send和recv;
老的sockfd依旧在listen。

6、int select(int maxfd,fd_set *rdset,fd_set *wrset,fd_set *exset,struct timeval *timeout);
maxfd是需要监视的最大的文件描述符值+1;
readset  用来检查可读性的一组文件描述字。
writeset 用来检查可写性的一组文件描述字。
exceptset用来检查是否有异常条件出现的文件描述字。(注:不包括错误)
timeout  它可以使select处于三种状态,第一,若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;第二,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;第三,timeout的值大于0,这就是等待的超时时间,即select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。
对于select函数的功能简单的说就是对文件fd做一个测试。
     Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect、accept、recv或recvfrom这样的阻塞程序(所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等待某个事件的发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回)。可是使用Select就可以完成非阻塞(所谓非阻塞方式non-block,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,以返回值的不同来反映函数的执行情况,如果事件发生则与阻塞方式相同,若事件没有发生则返回一个代码来告知事件未发生,而进程或线程继续执行,所以效率较高)方式工作的程序,它能够监视我们需要监视的文件描述符的变化情况——读写或是异常。

1 0
原创粉丝点击