(2)几个基本函数介绍

 
socket()
#include <sys/socket.h>
int socket( int family, int type, int protocol );
返回:非负描述字——成功。-1——出错
family指明协议族。
AF_INET     IPv4协议
AF_INET6    IPv6协议
AF_LOCAL    Unix域协议
AF_ROUTE    路由套接口
AF_KEY      密匙套接口
套接口类型type
SOCK_STREAM   字节流套接口
SOCK_DGRAM    数据报套接口
SOCK_RAW      原始套接口
protocol一般置为0;
不是所有的family和type的组合都是有效的
AF_INET + SOCK_STREAM = TCP
AF_INET6 + SOCKSTREAM = TCP
AF_LOCAL + SOCKSTREAM = YES
AF_INET + SOCK_DGRAM = UDP
AF_INET6 + SOCK_DGRAM = UDP
AF_LOCAL + SOCK_DGRAM = YES
AF_INET + SOCK_RAW = IPV4
AF_INET6 + SOCK_RAW = IPV6
AF_ROUTE + SOCK_RAW = YES;
AF_KEY + SOCK_RAW = YES;
 
bind()
#include <sys/socket.h>
int bind( int sockfd, const struct sockaddr *myaddr, socklen_t addrlen );
返回:0——成功, -1——出错
第二个参数是一个指向特定于协议的地址结构的指针,第三个参数是该地址结构的长度
对于TCP,调用bind可以指向一个端口号。指定一个IP地址。都指定。都不指定共4种情况
1:通配地址+0端口。 内核选择IP地址和端口
2: 通配地址+非0端口 内核选择IP地址。进程指定端口
3:本地IP地址+0端口 进程指定IP地址。内核选择端口
4: 本杜IP+非0端口   进程指定IP和端口
对于IPv4通配地址由常值INADDR_ANY来指定。其值一般为0,他通知内核选择IP地址。
struct sockdr_in servaddr;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
对于IPv6有一个in6addr_any的extern生命在<netinet/in.h>中。可以写为
struct sockdr_in6 serv;
serv.sin6_addr = in6addr_any;
 
connect()
#include <sys/socket.h>
int connect( int sockfd, const struct sockaddr *servaddr, socklen_t addrlen );
返回:0——成功, -1——出错
sockfd是由socket函数返回的套接口描述字,第二,三个参数分别是一个指向套接口地址结构的指针和该结构的大小。
套接口地址结构必须含有服务器的IP地址和端口号

如果是TCP套接口的话。函数激发TCP的三路握手过程。出错才返回。错误情况有如下几种:
1:如果TCP客户没有受到SYN分节的相应。则返回ETIMEDOUT
2:如果对客户的SYN的响应是RST,则表明该服务器主机在我们指定的端口上没有进程在的等待与之连接。
客户一收到RST。马上返回错误ECONNREFUSED;
3:如果客户发出的SYN在中间的路由器上引发了一个目的地不可达ICMP错误。在某规定时间没有响应。则把保存的消息作为EHOSTUNREACH或ENETUNREACH错误返回给进程。
 
connect()
#include <sys/socket.h>
int listen( int sockfd, int backlog );
返回:0——成功。-1——出错。
他仅被TCP服务器调用。做两件事
1:当函数socket创建一个套接口时,它被假设为一个主动套接口。也就是说他是一个将调用connect发起连接的客户套接口,将未连接的套接口转换称被动套接口,指示内核应接受指向此套接口的连接请求 。调用后导致套接口从CLOSEN状态转换到LISTEN状态
2:函数第二个参数规定了内核为此套接口排队的最大连接个数
参数backlog:
对于给定的舰艇套接口。内核要维护两个队列:
1:未完成连接队列。为每个这样的SYN分节开设一个条目,已由客户发出并到达服务器。服务器正在等待完成相应的TCP三路握手过程。这些套接口都处于SYN_RCVD状态
2:以完成连接队列,为每个以完成TCP三路握手过程的客户开设一个条目。这些套接口都处于ESTABLISHEDAA状态
  backlog   是未经过处理的连接请求队列可以容纳的最大数目。   
  即每一个连入请求都要进入一个连入请求队列,等待   
  listen   的程序调用accept()函数来接受这个连接。当系统还没有   
  调用accept()函数的时候,如果有很多连接,那么本地能够等待的最大数目就是backlog   的   
  数值。
 
accept()
accept有TCP服务器调用。从已完成连接队列头返回下一个已完成连接。
#include <sys/socket.h>
int accept( int sockfd, struct sockaddr * cliaddr, socklen_t *addrlen );
参数cliaddr和addrlen用来返回连接对方进程(客户)的协议地址。addrlen是值—结果参数。返回时是内核存在此套接口地址结构内的准确字节数。
如果函数执行成功。返回值是由内核自动生成的一个全新描述字。代表与客户的TCP连接。
第一个参数称为监听套接口(listening socket)描述字(由函数socket生成的描述字。用做bind和listen的第一个参数).把它的返回值称为已连接套接口描述字。
注意区分监听套接口和已连接套接口。一个服务器只生成一个前者直到服务器关闭。内核为每个被接受的客户连接创建一个后者完成这个客户的服务时,关闭后者
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值