socket函数手册.docx
《socket函数手册.docx》由会员分享,可在线阅读,更多相关《socket函数手册.docx(19页珍藏版)》请在冰豆网上搜索。
socket函数手册
socket函数手册
字节序函数
#include
/*主机序转换为网络序(short类型)*/
uint16_thtons(uint16_thost16bitvalue);
/*主机序转换为网络序(long类型)*/
uint32_thtonl(uint32_thost32bitvalue);
/*网络序转换为主机序(short类型)*/
uint16_tntohs(uint16_tnet16bitvalue);
/*网络序转换为主机序(long类型)*/
uint32_tntohl(uint32_tnet32bitvalue);
字节操纵函数
#include
/*清零*/
voidbzero(void*dest,size_tnbytes);
/*拷贝*/
voidbcopy(constvoid*src,void*dest,size_tnbytes);
/*比较*/
intbcmp(constvoid*ptr1,constvoid*ptr2,size_tnbytes);
IPv4地址转换函数
#include
/*
*字符串(x.x.x.x)转为32位网络序数值
*返回:
成功-1,失败-0
*/
intinet_aton(constchar*strptr,structin_addr*addrptr);
/*
*字符串(x.x.x.x)转为32位网络序数值
*返回:
成功-32位网络序数值,失败-INADDR_NONE(0xffffffff)
*注意:
255.255.255.255地址无法转换,不推荐使用
*/
in_addr_tinet_addr(constchar*strptr);
/*
*32位网络序数值转为字符串(x.x.x.x)
*返回:
字符串(x.x.x.x)
*注意:
返回的字符串保存在静态内存中,此函数不可重入
*/
char*inet_ntoa(structin_addrinaddr);
IPv4、IPv6通用地址转换函数
#include
/*
*地址字符串转为数值
*参数:
family-AF_INET;AF_INET6,
addrptr-sockaddr_in结构体的sin_addr的地址或sockaddr_in6结构体的sin6_addr的地址
*返回:
成功-1,失败--1,输入不是有效的地址-0
*/
intinet_pton(intfamily,constchar*strptr,void*addrptr);
/*
*数值转为地址字符串
*参数:
family-AF_INET或AF_INET6,
addrptr-sockaddr_in结构体的sin_addr的地址或sockaddr_in6结构体的sin6_addr的地址
strptr-保存转换后的地址字符串,指针不能为空,并不小于len指定的长度
len-字符串长度,中定义INET_ADDRSTRLEN(16)或INET6_ADDRSTRLEN(48)
*返回:
成功-返回strptr,失败-NULL
*/
constchar*inet_ntop(intfamily,constvoid*addrptr,char*strptr,size_tlen);
TCP套接口函数
#include
/* *创建socket套接口,指定套接口协议类型
*参数:
family-AF_UNIX(Unix域),AF_LOCOL(Unix域的POSIX名称),AF_INET(IPv4),AF_INET6(IPv6),AF_ROUTE(路由套接口),AF_KEY(密钥套接口),AF_PACKET
type-SOCK_STREAM(字节流),SOCK_DGRAM(数据报),SOCK_RAW(原始IPv4、IPv6),SOCK_PACKET(LINUX上类似BPF(BSD分组过滤器,Berkeley内核,如FreeBSD)和DLPI(数据链路提供者接口,SVR4内核,如soloris)的直接访问底层数据链路的套接口类型),SOCK_RDM(可靠传递消息),SOCK_SEQPACKET(有序分组)
protocol-0为给定family和type组合的系统默认值
返回:
成功-套接口描述字,失败--1 */
intsocket(intfamily,inttype,intprotocol);
/**TCP客户端与TCP服务器建立连接,调用此函数会触发TCP的三次握手,并建立连接。
调用此函数前,不必调用bind函数,内核会决定源IP并选择一个临时端口作为源端口。
*参数:
sockfd-套接口描述字
servaddr-包含要连接的服务器的IP和端口号的套接口地址结构
addrlen-servaddr套接口地址结构体的大小
返回:
成功-0,失败--1*/
intconnect(intsockfd,conststructsockaddr*servaddr,socklen_taddrlen);
/**将一个本地协议地址赋给套接口
参数:
sockfd-套接口描述字
myaddr-绑定的本地协议地址,对于网际协议,即IP地址和端口,如果IP地址赋值为INADDR_ANY(通配地址wildcard),则由内核去选择IP地址,如果端口赋值为0,则由内核选择一个临时端口
addrlen-地址结构体的大小
返回:
成功-0,失败--1*/
intbind(intsockfd,conststructsockaddr*myaddr,socklen_taddrlen);
/* *指示内核接受一个未连接的套接口上的连接请求
*参数:
sockfd-套接口描述字
backlog-套接口两个队列(完成连接和未完成连接)的排队最大连接个数,各个操作系统有不同的根据backlog计算排队最大连接个数的算法
返回:
成功-0,失败--1*/
intlisten(intsockfd,intbacklog);
/* *从已完成连接队列对头返回一个已完成连接,如果已完成连接队列为空,那么进程被阻塞(假设套接口为缺省的阻塞方式)
*参数:
sockfd-监听套接口描述字
cliaddr-输出参数,返回已连接的客户端的协议地址,为NULL,则不返回
addrlen-输出参数,返回套接口地址结构体的大小,为NULL,则不返回
返回:
成功-已连接套接口描述字(由内核自动生成的一个新描述字,代表与所返回客户端的TCP连接)
失败--1,EINTER-收到中断 */
intaccept(intsockfd,structsockaddr*cliaddr,socklen_t*addrlen);
#include
/* *关闭套接口,并终止TCP连接,如果为并发服务器父进程关闭已连接套接口,会将相应描述字的引用计数减一,如果计数不为0,将不会发送FIN
参数:
sockfd-套接口描述字
返回:
成功-0,失败--1
*/
intsend(SOCKETs,constcharFAR*buf,intlen,intflags);
不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据。
客户程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答。
该函数的第一个参数指定发送端套接字描述符;
第二个参数指明一个存放应用程序要发送数据的缓冲区;
第三个参数指明实际要发送的数据的字节数;
第四个参数一般置0。
这里只描述同步Socket的send函数的执行流程。
当调用该函数时,send先比较待发送数据的长度len和套接字s的发送缓冲的长度,如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR;如果len小于或者等于s的发送缓冲区的长度,那么send先检查协议是否正在发送s的发送缓冲中的数据,如果是就等待协议把数据发送完,如果协议还没有开始发送s的发送缓冲中的数据或者s的发送缓冲中没有数据,那么send就比较s的发送缓冲区的剩余空间和len,如果len大于剩余空间大小send就一直等待协议把s的发送缓冲中的数据发送完,如果len小于剩余空间大小send就仅仅把buf中的数据copy到剩余空间里(注意并不是send把s的发送缓冲中的数据传到连接的另一端的,而是协议传的,send仅仅是把buf中的数据copy到s的发送缓冲区的剩余空间里)。
如果send函数copy数据成功,就返回实际copy的字节数,如果send在copy数据时出现错误,那么send就返回SOCKET_ERROR;如果send在等待协议传送数据时网络断开的话,那么send函数也返回SOCKET_ERROR。
要注意send函数把buf中的数据成功copy到s的发送缓冲的剩余空间里后它就返回了,但是此时这些数据并不一定马上被传到连接的另一端。
如果协议在后续的传送过程中出现网络错误的话,那么下一个Socket函数就会返回SOCKET_ERROR。
(每一个除send外的Socket函数在执行的最开始总要先等待套接字的发送缓冲中的数据被协议传送完毕才能继续,如果在等待时出现网络错误,那么该Socket函数就返回SOCKET_ERROR)
注意:
在Unix系统下,如果send在等待协议传送数据时网络断开的话,调用send的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。
通过测试发现,异步socket的send函数在网络刚刚断开时还能发送返回相应的字节数,同时使用select检测也是可写的,但是过几秒钟之后,再send就会出错了,返回-1。
select也不能检测出可写了。
intrecv(SOCKETs,charFAR*buf,intlen,intflags);
不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。
该函数的第一个参数指定接收端套接字描述符;
第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
第三个参数指明buf的长度;
第四个参数一般置0。
这里只描述同步Socket的recv函数的执行流程。
当应用程序调用recv函数时,recv先等待s的发送缓冲中的数据被协议传送完毕,如果协议在传送s的发送缓冲中的数据时出现网络错误,那么recv函数返回SOCKET_ERROR,如果s的发送缓冲中没有数据或者数据被协议成功发送完毕后,recv先检查套接字s的接收缓冲区,如果s接收缓冲区中没有数据或者协议正在接收数据,那么recv就一直等待,只到协议把数据接收完毕。
当协议把数据接收完毕,recv函数就把s的接收缓冲中的数据copy到buf中(注意协议接收到的数据可能大于buf的长度,所以在这种情况下要调用几次recv函数才能把s的接收缓冲中的数据copy完。
recv函数仅仅是copy数据,真正的接收数据是协议来完成的),recv函数返回其实际copy的字节数。
如果recv在copy时出错,那么它返回SOCKET_ERROR;如果recv函数在等待协议接收数据时网络中断了,那么它返回0。
注意:
在Unix系统下,如果recv函数在等待协议接收数据时网络断开了,那么调用recv的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。
intclose(intsockfd);
获得与套接口关联的协议地址
#include
/*
*获得与套接口关联的本地协议地址
*参数:
sockfd-套接口描述字
localaddr-输出参数,返回与套接口关联的本地协议地址
addrlen-输出参数,返回套接字地址结构体的大小
* 返回:
成功-0,失败--1
*/
intgetsockname(intsockfd,structsockaddr*localaddr,socklen_t*addrlen);
/*
*获得与套接口关联的远端协议地址
*参数:
sockfd-套接口描述字
peeraddr-输出参数,返回与套接口关联的远端协议地址
addrlen-输出参数,返回套接字地址结构体的大小
* 返回:
成功-0,失败--1
*/
intgetpeername(intsockfd,structsockaddr*peeraddr,socklen_t*addrlen);
I/O复用函数
#include
#include
/*
*检查是否收到关心的套接字事件
*参数:
maxfdp1-关心的最大套接字+1
readset-关心是否可读的套接字的集合,NULL代表不关心
writeset-关心是否可写的套接字的集合,NULL代表不关心
exceptset-关心是否有异常的套接字的集合,NULL代表不关心
timeout-NULL:
永远等下去;秒数和毫秒数都为0:
不等待;指定值:
等待一段时间
*返回:
成功-就绪套接字的数目,超时-0,失败--1
*/
intselect(intmaxfdp1,fd_set*readset,fd_set*writeset,fd_set*exceptset,conststructtimeval*timeout);
/*用来设置关心套接字集合的函数*/
voidFD_ZERO(fd_set*fdset);
voidFD_SET(intfd,fd_set*fdset);
voidFD_CLR(intfd,fd_set*fdset);
intFD_ISSET(intfd,fd_set*fdset);
发送FIN函数
#include
/*
*发送FIN,关闭连接
*参数:
sockfd-要关闭连接的socket描述字
howto-关闭连接方式:
SHUT_RD-关闭连接的读这一半,不再接收数据,丢弃接收缓冲区中的未接收数据;SHUT_WR-关闭连接的写这一半,即半关闭状态,发送缓冲区中将被发送完;SHUT_RDWR-连接的读写都被关闭
*返回:
成功-0,失败--1
*/
intshutdown(intsockfd,inthowto);
套接口选项函数
注:
标志表明了该选项是否为启用或禁止类型,0-禁止,非0-启用
级别
选项名
get
set
说明
标志
数据类型
SOL_SOCKET
SO_BROADCAST
*
*
开启或禁止进程发送广播消息的能力,只适用于UDP套接口,如果目的地址为一个广播地址且本套接口选项没有设置,则返回EACCES错误
*
int
SO_DEBUG
*
*
只适用于TCP套接口,对套接口发送和接受的报文保留详细跟踪信息,可使用trpt程序进行查看
*
int
SO_DONTROUTE
*
*
对发出的报文不查询路由表,直接通过目的地址的网络地址确定本地接口后发送,如果无法由目的地址确定(即不在一个点到点链路或共享网络),则返回ENETUNREACH错误
*
int
SO_ERROR
*
当socket发生错误时,可以同访问SO_ERROR套接口选项获取该错误值(保存在so_error中),读取后so_error被复位为0,该错误被称为待处理错误(pendingerror)
int
SO_KEEPALIVE
*
*
适用于TCP套接口,启用或禁止2小时内未收到任一方向上的数据则发送保活探测报文
*
int
SO_LINGER
*
*
指定close函数对面向连接协议(如TCP和SCTP)如何操作,缺省操作是close函数立即返回,如果发送缓冲区有数据,则尝试发送给对端。
SO_LINGER选项可以改变此设置。
如果l_onoff为0,使用缺省设置。
如果l_onoff为非0且l_linger为0,则丢弃发送缓冲区中的数据并发送一个RST给对端,没有通常的四次握手终止连接
如果l_onoff为非0且l_linger为非0,则当套接口关闭时内核将拖延一段时间,如果发送缓冲区有数据,进程将被阻塞,知道所有数据发送玩且均被对方确认或延滞时间到。
如果套接口为非阻塞型,那么它将不等待close完成,即使l_linger为非0。
sturctlinger{
intl_onoff;
intl_linger;
}
SO_OOBINLINE
*
*
开启时,带外数据将被留在正常的输入队列中。
这种情况下接收函数的MSG_OOB标志不能用来读带外数据。
*
int
SO_RCVBUF
*
*
改变接收缓冲区的缺省大小,对于TCP客户端的接受缓冲区大小必须在调用connect之前设置;对于TCP服务器端必须在调用listen之前给套接口设置,新建的已连接套接口从监听套接口继承缓冲区大小。
TCP缓冲区大小至少应是相应连接的MSS值的四倍,且为MSS值的偶数倍。
int
SO_SNDBUF
*
*
改变发送缓冲区的缺省大小,同上
int
SO_RCVLOWAT
*
*
改变接收低潮标记,即select返回套接口接收缓冲区可读所需的数据量,对于TCP、UDP、SCTP套接口,缺省为1
int
SO_SNDLOWAT
*
*
改变发送低潮标记,即select返回套接口发送缓冲区可写所需的可用空间
int
SO_RCVTIMEO
*
*
改变套接口接收的超时值,时间为0代表不超时
structtimeval
SO_SNDTIMEO
*
*
改变套接口发送的超时值,时间为0代表不超时
structtimeval
SO_REUSEADDR
*
*
允许启动一个监听服务器并捆绑众所周知端口,即使以前在此端口上建立的连接仍存在;允许完全重复的捆绑:
即当一个IP地址和端口已绑定到某个套接口上时,如果传输协议支持,同样的IP和端口还可以捆绑到另一个套接口上,一般来说仅支持UDP套接口。
*
int
SO_REUSEPORT
*
*
允许完全重复的捆绑(如上详述),不过只有在想要捆绑同一IP地址和端口的每一个套接口都启用本选项才行;如果被捆绑的IP地址是一个多播地址,那么SO_REUSEADDR和SO_REUSEPORT被认为等效
*
int
SO_TYPE
*
获得套接口的类型,如SOCK_STREAM或SOCK_DGRAM
int
SO_USELOOPBACK
*
*
只适用于路由域套接口,开启时,相应套接口将接收在其上发送的任何数据报的一份拷贝
*
int
#include
/*
*获得套接口选项
*参数:
sockfd-套接字,level-级别,optname-选项名,optval-值,optlen-值的大小
*返回:
0-成功,-1-失败
*/
intgetsockopt(intsockfd,intlevel,intoptname,void*optval,socklen_t*optlen);
/*
*设置套接口选项
*参数:
sockfd-套接字,level-级别,optname-选项名,optval-值,optlen-值的大小
*返回:
0-成功,-1-失败
*/
intsetsockopt(intsockfd,intlevel,intoptname,constvoid*optval,socklen_t*optlen);
套接字控制操作
控制操作
命令
参数
返回
设置套接口为非阻塞I/O型
F_SETFL
O_NONBLOCK
成功-0,失败--1
设置套接口为信号驱动I/O型
F_SETFL
O_ASYNC
获得套接口文件标志
F_GETFL
0
成功-文件标志,失败--1
设置套接口拥有者,用于接收SIGIO和SIGURG信号
F_SETOWN
进程ID或进程组ID
成功-0,失败--1
获得套接口拥有者
F_GETOWN
0
成功-进程ID或进程组ID,失败--1
#include
/*
*套接字控制操作
*参数:
fd-套接字,cmd-命令
*返回:
依赖cmd(见上表)
*/
intfcntl(intfd,intcmd,.../*intarg*/);
UDP套接口函数
#include
/*
*接收UDP报文
*参数:
sockfd-套接字
buff-指向接收缓存的地址
nbytes-接收字节数
flags-
from-返回UDP报文发送者的套接口地址
addrlen-返回from套接口地址的大小
*返回:
成功返回接收的字节数,出错返回-1
*/
ssize_trecvfrom(intsockfd,void*buff,size_tnbytes,intflags,structsockaddr*from,socklen_t*addrlen);
/*
*发送UDP报文
*参数: