Socket 函数说明
1.1 库函数综述
1.1.1 套接字函数
表 1.1 Windows Sockets 1.1 版本Berkeley Sockets函数
函数名说明
accept()确认外来连接,并将它与一个立即建立的数据套接字联系起来。原始套
接字返回到监听状态
bind() 给未命名套接字赋一个本地名
closesocket()从进程对象参考表中删去一个套接字,只有当SO_LINGER设置时才阻塞connect()在指定套接字上初始化连接
getpeername() 获取与指定套接字连接的对等方的名字
getsockname() 获取指定套接字的当前名字
getsockopt() 获取与指定套接字相关的选项
htonl() 将一个32位数从主机字节顺序转换为网络字节顺序
htons() 将一个16 位数从主机字节顺序转换为网络字节顺序
inet_addr() 将一个用网际标准点分表示法表示的字符串地址转换成网际地址值
inet_ntoa() 将一个网际地址值转换成一个用点分十进制表示法表示的字符串地址ioctlsocket() 为套接字提供控制
listen() 在指定套接字上监听外来连接
ntohl() 将一个32位数从网络字节顺序转换为主机字节顺序
ntohs() 将一个16 位数从网络字节顺序转换为主机字节顺序
recv()从一个连接的套接字上接收数据
recvfrom()从一个连接或未连接的套接字上接收数据
select()执行多路同步I/O
send()给一个连接套接字发送数据
sendto()给一个连接或未连接套接字发送数据
setsockopt() 设置与指定套接字相关的选项
shutdown() 关闭全双工连接的一部分
socket() 建立一个通讯用的末端点,返回一个套接字
注:标红函数作用在阻塞套接字上可以阻塞。
这些函数根据功能的不同可以分为如下几类:
(1) 套接字函数。此类函数包括socket(),bind(),getpeername(),getsockname()和closesocket(),它们主要完成创建,关闭套接字功能,以及对套接字命名与名字获取。
(2) 网络连接函数。此类函数包括listen() ,accept(),connect()和shutdown(),它们完成网络连接(如虚电路)的建立与关闭。此类函数中有部分可阻塞。
(3) 数据传输函数。此类函数包括send(),recv() ,sendto()和recvfrom() ,它们完成网络数据的发送与接收,全部是可以阻塞的函数。
(4) 字节定序函数。此类函数包括htonl(),htons(),ntohl()和ntohs(),它们完成主机/网络之间数据字节顺序的转换。
(5) 地址转换函数。此类函数包括inet_addr(),inet_ntoa(),它们完成网络字符串地址和Internet 地址之间的转换。
(6) 套接字控制函数。此类函数包括getsockopt(),setsockopt(),ioctlsocket()和select(),它们设置/获取套接字的选项,控制/检测套接字的工作状态。其中select()函数在必要时可能阻塞。
只使用了上述函数Berkeley Sockets 源程序基本上可以不加修改地移植到Windows Sockets 环境中来。但是,移植过来的程序有一个最大的问题是“阻塞”。在Berkeley Sockets 中,套接字默认的工作模式是操作处于阻塞方式,一个阻塞操作可能阻塞整个Windows 环境。在非抢先Windows环境,强烈推荐程序员使用非阻塞(异步)操作,也就是说,推荐使用Windows Sockets 提供的异步选择函数代替可能阻塞的select()函数,并且用网络事件消息来驱动可能阻塞的网络连接函数(accept()和connect())和数据传输函数,这样设计的程序能更好地工作。
1.1.2 数据库函数
Windows Sockets定义了如表1.2 所示的“数据库”函数:
表 1.2 Windows Sockets 1.1 版本定义的“数据库”函数
函数名说明
gethostbyaddr() 通过网络地址获取主机名字和地址等信息
gethostbyname() 通过主机名字获取主机名字和地址等信息
gethostname()获取本地主机名
getprotobyname() 通过协议名获取协议名和协议号等信息
getprotobynumber() 通过协议号获取协议名和协议号等信息
getservbyname() 通过服务名获取服务的名字和端口等信息
getservbyport() 通过端口获取服务的名字和端口等信息
注:标红函数在某些条件下可以阻塞。
提供这类函数是为了获取网络特定的信息,在最初的Berkeley版本中,它们是作为在文本数据库文件中寻找信息的机构。在Windows Sockets实现中,可能使用了不依赖于本地数据库文件的方法(如域名服务),但是对应用程序来说请求这些信息的格式是一致的,并且对应用程序来说是透明的。
调用这些函数所获得的信息存放在由Windows Sockets实现分配的一个结构中,函数返回此结构的地址。因此,应用程序可以通过此结构指针获取所需要的信息,但它决不能试图修改此结构,更不能释放结构的任一部分。另外,对一个线程来说,Windows Sockets实现只分配了结构的一个备份,任何Windows Sockets API 调用都可能修改此结构。也就是说,结构指针指向的数据只在此线程的下一次Windows Sockets API 调用之前才是正确的,应用程序应该在发布任何其它Windows Sockets API 调用之前将任何需要的信息拷贝出来。
数据库函数除gethostname()之外都是阻塞的,Windows Sockets提供它们是为了Berkeley Sockets网络程序的可移植性。在设计实现Windows Sockets 应用程序时,推荐使用Windows Sockets 提供的数据库函数的异步版本。
1.2 标准Socket 函数
1.2.1 accept()
语法:SOCKET WSAAPI
accept ( IN SOCKET s,
OUT struct sockaddr FAR* addr,
OUT int FAR* addrlen );
此函数用于从套接字上接收一个连接。它提取挂在套接字s 上的连接队列中的第一个连接,创建一个和s 有相同属性(包括使用函数WSAAsyncSelect()或WSAEventSelect()注册的异步事件,但不包括监听套接字的套接字组ID)的新数据套接字,并返回一个指向新套接字的句柄。如果连接队列上没有等待的连接,并且套接字没有标志为非阻塞,那么accept() 阻塞调用直到出现一个连接。如果套接字标志为非阻塞,并且队列上没有等待的连接,那么accept()返回错误WSAEWOULDBLOCK。新创建的数据套接字不能用来接收更多的连接,它只能用于数据传输;原来的套接字仍然打开,处于监听连接状态。
参数描述:
s,这是一个套接字描述符,该套接字在用作accept()函数的参数前必须先调用过listen()函数,此时它正处于监听连接的状态。
addr ,一个可选的指向缓冲区的指针,用来接收连接实体的地址,在通讯层使用。addr的确切格式由套接字创建时建立的地址族决定。
addrlen ,一个可选的指向整数的指针,它调用时含有地址addr指向的空间的大小,返回时含有返回的地址的确切长度(字节数)。
返回值:如果没有错误发生,accept()返回一个SOCKET类型的值,表示接收到的套接字的描述符。否则返回值INVALID_SOCKET,错误码可通过调用WSAGetLastError()函数得到。
错误码:
WSANOTINITIALISED :未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN: Windows Sockets 实现检测到网络系统已经失败。
WSAEFAULT: 参数addrlen 太小(小于结构sockaddr 的大小),或参数addr不是用户地址空间的合法部分。
WSAEINTR:此(阻塞)调用已被WSACancelBlockingCall()函数取消。WSAEINPROGRESS:一个阻塞的Windows Sockets 操作正在进行。
WSAEINVAL:在accept()调用之前没有执行过listen()。
WSAEMFILE:accept()队列入口空,但没有文件描述符可用(即打开的文件描述符过多)。WSAENOBUFS:无缓冲区空间可用。
WSAENOTSOCK:描述符s不是套接字描述符。
WSAEOPNOTSUPP:s 指向的套接字不是一种支持面向连接服务类型的套接字。WSAEWOULDBLOCK:套接字标志为非阻塞,但现在没有接收到连接。
注释:该调用只能和基于连接的套接字类型如SOCK_STREAM 一起使用。如果参数addr 和/或addrlen 等于NULL,那么没有关于接收套接字的远程地址信息返回。
参见:bind(), connect(), listen(), select(), socket(), WSAAsyncSelect(), WSAAccept()。
1.2.2 bind()
语法:int WSAAPI
bind ( IN SOCKET s,
IN const struct sockaddr FAR* name,
IN int namelen );
此函数用于未连接的数据报或流套接字,它将一本地地址与套接字连接,即建立半相关。当一套接字用socket()创建后,它存在于一名字空间(地址族), 但它没有赋予名字。bind()通过将一本地名字赋予一未命名的套接字, 建立起套接字的本地连接(主机地址/端口号)。
参数描述:
s,指示未连接的数据报或流套接字的描述符。
name,赋给套接字的本地地址(名字)。结构sockaddr 定义如下:
struct sockaddr { u_short sa_family;
char sa_data[14];
}; //除sa_family 外,其它内容都以网络字节顺序表示。namelen,地址缓冲区长度。
返回值:如果没有错误发生,bind()返回0。否则返回值SOCKET_ERROR,错误码可通过调用WSAGetLastError()函数得到。
错误码:
WSANOTINITIALISED:未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN :Windows Sockets 实现检测到网络系统已经失败。WSAEADDRINUSE:指定的地址已使用(参见setsockopt()中的SO_REUSEADDR 套接字选项)。WSAEADDRNOTAVAIL:对于本机器来说,指定的地址是非法地址(WinSock 2)。WSAEFAULT:参数namelen 太小(小于结构sockaddr 的长度);参数name 或namelen 不是用户地址空间的合法部分;参数name 包含了相关的地址族来说是不正确的地址
格式;参数name 指向的内存块的前两个字节与套接字描述符s 相关的地址族不
匹配。
WSAEINPROGRESS:一个阻塞的Windows Sockets 操作正在进行。WSAEAFNOSUPPORT:此套接字不能使用指定地址族中的地址(WinSock 1.1)。WSAEINVAL:此套接字已经捆扎到了一个地址。
WSAENOBUFS:无缓冲区空间可用,连接太多。
WSAENOTSOCK:此描述符不是套接字描述符。
注释:在Internet地址族中,一个名字有几个部分。对于SOCK_DGRAM和SOCK_STREAM类型的套接字来说,名字分为三部分:主机地址,协议号(分别默认设置为UDP和TCP),以及一个标志应用程序的端口号。在WinSock 2 中,参数name 并不严格地解释为指向“sockaddr”结构的指针,但为了与Windows Sockets的兼容性仍用这种表示。服务提供者可以把它当作一个指向长度为namelen的内存块而自由处理,在此内存块的前两个字节(对应结构sockaddr 定义中的sa_family 元素)必须为包含建立套接字的地址族,否则将产生错误WSAEFAULT。
如果应用程序不关心赋予它的地址,则可指定一个等于常数INADDR_ANY的网际地址,和/或等于0 的端口。如果网际地址等于INADDR_ANY,任何合适的网络接口都可用,这就简化了在多宿主机上的应用程序设计。当一个服务器向几个网络提供服务时,这将变得很重要。在不指定地址的情况下,服务器可以接收发向其端口的所有UDP数据包和TCP 连接请求,而不必关心请求是从哪一个网络接口到达的。如果端口指定为0,Windows Sockets 实现将为应用程序指定一界于1024 和5000 之间的端口值。应用程序可在bind() 后使用getsockname()来得到赋给它的地址,但要注意的是,对于网际地址等于INADDR_ANY 的情况,getsockname()只有当套接字连接后才填入网际地址(Internet address),原因是当主机是多地址家族时,几个网际地址都是合法的。对客户应用程序来说,不鼓励将其绑扎到一个指定的端口,因为这样存在与已
经使用了该端口的其它套接字冲突的危险。
由于Windows Sockets 只支持AF_INET 地址域,因此名字缓冲区的格式只能是sockaddr_in 结构。此结构在winsock.h 中定义如下:
struct in_addr{ u_long s_addr; };
struct sockaddr_in{ u_char sin_len;
u_char sin_family; // 只能置为AF_INET
u_short sin_port; //应用程序必须连接的端口号
struct in_addr sin_addr; // sin_addr 字段为主机网际地址
char sin_zero[8]; }; // sin_zero 扩展未用,必须全为0
注意,此结构的任何字段均为网络字节顺序。
在WinSock 2,支持的地址族得到扩展,因此结构sockaddr不只解释为sockaddr_in,根据不同的地址族,它有不同的确切格式。
参见:WSACancelBlockingCall(), connect(), listen(), getsockname(), setsockopt(), socket()。
1.2.3 closesocket()
语法:int WSAAPI
closesocket ( IN SOCKET s ); // s,待关闭的套接字描述符
此函数关闭套接字s,并释放分配给该套接字的资源,以后对s 的引用都将产生错误WSAENOTSOCK。如果s 涉及一个打开的TCP 连接,该连接被释放。
返回值:如果没有错误发生,closesocket()返回0。否则返回值SOCKET_ERROR,错误码可通过调用WSAGetLastError()函数得到。
错误码:
WSANOTINITIALISED:未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN:Windows Sockets 实现检测到网络系统已经失败。
WSAENOTSOCK:此描述符不是套接字描述符。
WSAEINPROGRESS:一个阻塞的Windows Sockets 操作正在进行。
WSAEINTR:此(阻塞)调用已被WSACancelBlockingCall()函数取消。WSAEWOULDBLOCK:套接字标志为非阻塞并且SO_LINGER 设置为非零超时。
注释:closesocket()函数的语义受套接字选项SO_LINGER 和SO_DONTLINGER 的影响,具体见下表(默认情况下是允许SO_DONTLINGER):
选项SO_DONTLINGER SO_LINGER SO_LINGER
间隔不用零非零关闭类型Graceful Hard Graceful
等待关闭?No No Yes
如果SO_LINGER设置(例如,linger结构的l_onoff域非零)并且超时间隔为零(l_linger为零),那么即使队列数据尚未发送或确认,closesocket()函数也不会阻塞。这称作强制(“hard”或“abortive”)关闭,因为套接字的虚电路立即复位,任何未发送的数据都将丢失,并且在虚电路远程方的任何recv()调用都将以WSAECONNRESET失败。在这种情况下,套接字不进入TCP 状态机的三次握手流程,系统资源被立即释放。这对于服务器应用程序非正常退出后希望能立即启动很有用,当正常通信中不鼓励使用。
如果SO_LINGER设置超时间隔为非零,closesocket()函数将阻塞,直到剩余的数据都发送完毕或直到超时退出,这称作“雅致”(graceful )关闭。注意如果套接字设置为非阻塞并且SO_LINGER设置为非零超时,调用closesocket()将失败,错误码为WSAEWOULDBLOCK。
如果SO_DONTLINGER 设置在流套接字上(例如,linger 结构的l_onoff 域为零), closesocket()调用将立即返回。然而,排队等待传送的任何数据如果可能的话都将在该套接字关闭前发送出去,这也称作“雅致”关闭。注意在这些情况下,Windows Sockets 实现可能会在任意时间内不释放套接字和其他资源, 这可能影响希望使用全部可用套接字的应用程序。如果应用程序要确保连接上的所有数据都被发送或接收到,则应该在调用closesocket() 函数之前调用shutdown()函数。
下面给出closesocket()函数的小结:
?如果SO_DONTLINGER 允许(默认设置),且不会出现错误WSAEWOULDBLOCK──连接在后台“雅致”关闭;
?如果SO_LINGER允许并且超时间隔为0,则总是立即返回──连接被重置或终止;
?如果SO_LINGER允许并且超时间隔非0:
──对于阻塞套接字,阻塞到所有数据发送完或超时间隔到时;
──对于非阻塞套接字,立即返回并且指示错误WSAEWOULDBLOCK。
参见:accept(), socket(), ioctisocket(), setsockopt(),WSAAsyncSelect(),WSADuplicateSocket()。
1.2.4 connect()
语法:int WSAAPI
connect ( IN SOCKET s,
IN const struct sockaddr FAR* name,
int namelen );
此函数用来与对等方建立一个连接。如果套接字s 没有绑扎,则系统赋予本地相关一个唯一值,并且套接字被表示为已绑扎的。
参数描述:
s,用来表示发出连接请求的套接字的描述符。
name,指向一个socket address结构的指针,该结构含有对等方的套接字的地址。
namelen , name指向的socket address结构的字节数。
返回值:如果没有错误发生,connect()返回0。否则返回值SOCKET_ERROR,错误码可通过调用WSAGetLastError()函数得到。对于阻塞套接字来说,返回值表示连接试图是否成功.对于非阻塞套接字来说,连接试图不一定马上完成。当connect()返回SOCKET_ERROR,并且WSAGetLastError()返回WSAEWOULDBLOCK 时,应用程序可以:
1.利用select()函数,通过检查套接字是否可写来判断连接请求是否完成。
2.如果应用程序已使用WSAAsyncSelect()函数注册了对连接事件的兴趣,则当连接操作完成
时应用程序将收到FD _CONNECT通知(无论成功与否)。
3.如果应用程序已使用WSAEventSelect()函数注册了对连接事件的兴趣,则当连接操作完成
时相应的事件对象将设置信号(无论成功与否)。
对于一个非阻塞套接字来说,在连接试图完成之前,任何对该套接字的connect()调用都将以错误码WSAEALREADY 失败,在连接成功之后则返回错误码WSAEISCONN 。由于Windows Sockets 1.1 规范在定义当连接请求正在处理时调用connect()函数返回的错误值有二义性,其返回值对于不同的Windows Sockets实现其值不同,因此不推荐应用程序采用多次调用connect()函数的方式来检测连接是否完成。如果应用程序员一定要这么做,为了确保程序的可靠运行,他们在处理错误码WSAEALREADY 的同时,还必须准备处理WSAEINVAL 和WSAEWOULDBLOCK 错误码。
如果返回值指出连接试图失败(例如WSAECONNREFUSED ,WSAENETUNREACH ,WSAETIMEDOUT等),则应用程序可对该套接字再次调用connect()函数。
错误码:
WSANOTINITIALISED:未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN:Windows Sockets 实现检测到网络系统已经失败。
WSAEADDRINUSE:套接字的本地地址已被使用,并且该套接字没有使用SO_REUSEADDR 来设置允许地址重用。此错误经常发生在函数bind()调用时,但当bind()函数使
用通配地址(包括ADDR_ANY)并且在connect()函数调用时需要“提交”一
个指定地址时,此错误能够延迟到connect()函数。
WSAEINTR:阻塞的WinSock 1.1 调用为WSACancelBlockingCall()函数撤消。WSAEINPROGRESS:一个阻塞的Windows Sockets 1.1 操作正在进行。
WSAEALREADY:一个非阻塞的connect()调用已经在指定的套接字上进行(WinSock 2)。WSAEADDRNOTAVAIL:远程地址非法(如ADDR_ANY)。
WSAEAFNOSUPPORT:此套接字不能使用指定地址族中的地址。WSAECONNREFUSED:连接请求被目的主机拒绝。
WSAEDESTADDRREQ:要求目标地址(WinSock 1.1)。
WSAEFAULT:参数name或namelen不是用户地址空间的合法部分;参数namelen太小(小于结构sockaddr的长度);参数name包含了相关的地址族来说是不正确的地址格式。WSAEINVAL :此套接字没有捆扎到一个地址,或套接字为监听套接字,或者指定的目的地址与套接字从属的强制组不一致。
WSAEISCONN:此套接字已经建立了连接(只对面向连接的套接字有效)。
WSAEMFILE:无文件描述符可用(WinSock 1.1)。
WSAENETUNREACH:此主机现在不能到达网络。
WSAENOBUFS:无缓冲区空间可用,此套接字不能被连接。
WSAENOTSOCK:此描述符不是套接字描述符。
WSAETIMEDOUT:连接请求超时,未能建立连接。
WSAEWOULDBLOCK:套接字处于非阻塞模式,并且连接不能立即完成,它并不表明一个错误情况。
WSAEACCES:由于setsockopt()时未允许SO_BROADCAST,无法将一个数据报套接字与一个广播地址连接。
注释:客户程序在流套接字上调用connect()函数来建立与服务器的连接,服务器必须有一个空闲的被动接口。否则,connect()函数将以错误码WSAECONNREFUSED 失败。
对于流套接字(类型SOCK_STREAM),connect()函数用来初始化与参数name(套接字名字空间中的地址)指示的外部主机的活动连接。当connect()调用成功完成后,套接字就可以收发数据了。如果结构name的地址域全为0,则返回错误WSAEADDRNOTAVAIL。
流套接字只能调用connect()函数一次,多次调用将以错误码WSAEISCONN 失败。数据报套接字(类型SOCK_DGRAM)可以重复调用connect()函数来变换连接,它设置与数据报套接字数据传送的默认目标,供以后的send()/WSA Send()和recv()/WSARecv()函数使用。数据报套接字可以通过连接一个无效地址,例如空地址(即全部字段清零)来结束连接。
对于无连接的套接字来说,name可以是任何合法的地址,包括广播地址。然而,要连接到一个广播地址,套接字必须使用setsockopt()函数的SO_BROADCAST选项来允许广播,否则connect()函数将以错误码WSAEACCES失败。
对于处于阻塞模式的套接字s,connect()函数阻塞调用者,直到建立起连接或有错误被接收到。对于非阻塞套接字s ,如果返回值是SOCKET_ERROR, 并且错误码为WSAEWOULDBLOCK,那么应用程序可以使用select()函数来检查套接字s 是否可写来判定连接请求是否完成;如果应用程序使用了基于消息的WSAAsyncSelect()/WSAEventSelect()函数来指示感兴趣的连接事件,那么当连接操作完成后,应用程序将收到FD_CONNECT消息。
参见:accept(), bind(), getsockname(), socket(), select(), WSAAsyncSelect(), WSAConnect()。
1.2.5 getpeername()
语法:int WSAAPI
getpeername ( IN SOCKET s,
OUT struct sockaddr FAR* name,
IN OUT int FAR* namelen );
此函数用来获取与套接字连接的对等方的地址,它检索与套接字s连接的对等方的名字,并把它存在sockaddr结构的name域中。此函数只能用于已连接的数据报或流套接字。对于数据报套接字,只有在先前的connect()调用中指定的对等方的名字被返回,而不会返回先前的sendto()调用指定的名字。
参数描述:
s, 标识已连接的套接字的描述符。
name, 指向连接的套接字网际地址的指针,该结构由getpeername()在返回之前填写,name的确切格式由通信发生的区域决定。
namelen, 指向name所指结构大小的指针。它在返回时含有返回名字的实际字节数。
返回值:如果没有错误发生,getpeername()返回0。否则返回值SOCKET_ERROR,错误码可通过调用WSAGetLastError()函数得到。
错误码:
WSANOTINITIALISED:未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN:Windows Sockets 实现检测到网络系统已经失败。
WSAEFAULT:参数name 或namelen不是用户地址空间的合法部分,或参数namelen不够大。WSAEINPROGRESS:一个阻塞的Windows Sockets 操作正在进行。
WSAENOTCONN:套接字没有连接。
WSAENOTSOCK:此描述符不是套接字描述符。
参见:bind(), socket(), getsockname()。
1.2.6 getsockname()
语法:int WSAAPI
getsockname ( IN SOCKET s,
OUT struct sockaddr FAR* name,
IN OUT int FAR* namelen );
此函数用来获取套接字的本地名。它检索指定套接字描述符的当前名字,并放入name,它用于参数s 指定的一个已绑扎并且/或者已连接的套接字,返回与该套接字相连的本地地址。
当调用connect()函数之前没有先调用bind()函数时,该调用特别有用;它提供了唯一一种用来确定系统设置的本地连接的方法。
参数描述:
s,一个已绑扎bind()套接字的描述符。
name,接收套接字的地址(名字)的缓冲区指针。
namelen,指向name缓冲区大小的指针,返回时,它含有返回名字的实际字节数。
返回值:如果没有错误发生,getsockname()返回0。否则返回值SOCKET_ERROR,错误码可通过调用WSAGetLastError()函数得到。
错误码:
WSANOTINITIALISED:未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN:Windows Sockets实现检测到网络系统已经失败。
WSAEFAULT:参数name或namelen不是用户地址空间的合法部分,参数namelen不够大。WSAEINPROGRESS:一个阻塞的Windows Sockets操作正在进行。
WSAENOTSOCK:此描述符不是套接字描述符。
WSAEINVAL:套接字没有使用bind()绑扎到一个地址,或套接字在bind()调用时地址指定为ADDR_ANY,并且连接仍没有建立。
注释:流套接字只有在成功调用了bind(),connect()或accept()之后才真正与一名字联系。如果该套接字没有与一地址连接,调用返回其地址族,其它字段置为零。例如,一个网际地址域中的未连接套接字将会导致name 所指的sockaddr_in结构中的sin_family字段被置为AF_INET,其它字段全置为零。如果套接字被绑扎为INADDR_ANY,这指示任何主机IP地址都可用于套接字,则getsockname()不一定返回主机IP 地址的信息,除非该套接字已经用connect() 或accept() 建立了连接。Windows Sockets 应用程序一定不要假定IP 地址可从INADDR_ANY改变,这是因为对于一多宿主机来说,用于套接字的IP 地址是不可知的,除非该套接字是已连接的。如果此套接字使用的是无连接协议,除非I/O 正在该套接字上发生,否则得不到地址。
参见:bind(), socket(), getpeername()。
1.2.7 getsockopt()
语法:int WSAAPI
getsockopt ( IN SOCKET s, //套接字描述符
IN int level, //仅持SOL_SOCKET/IPPROTO_TCP层
IN int optname, //要检索的套接字选项的名字
OUT char FAR* optval, //指向查询选项返回值的缓冲区
IN OUT int FAR* optlen ); //指向optval 缓冲区大小的指针此函数用来获取套接字选项。它检索与任何类型、任何状态的套接字相连的套接字选项的当前值,并把结果存入optval。选项可能在多个协议层存在,但它们总是表现在最高的“socket”层。选项影响套接字操作,例如一个操作是否阻塞、包的路由选择、带外数据传输等。
返回值:如果没有错误发生,getsockname()返回0。否则返回值SOCKET_ERROR,错误码可通过调用WSAGetLastError()函数得到。
错误码:
WSANOTINITIALISED:未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN:Windows Sockets实现检测到网络系统已经失败。
WSAEFAULT:参数optval 或optlen 不是用户地址空间的合法部分,或参数optlen不够大。WSAEINPROGRESS:一个阻塞的Windows Sockets操作正在进行。
WSAEINVAL:level 未知或非法。
WSAENOTPROTOOPT:未知或不支持的选项。特别地,SOCK_STREAM类型的套接字不支SO_BROADCAST,而SOCK_DGRAM 类型的套接字不支持
SO_ACCEPTCONN,SO_DONTLINGER,SO_KEEPALIVE,SO_LINGE和SO_OOBINLINE。WSAENOTSOCK:此描述符不是套接字描述符。
注释:与选择的选项相关联的返回值放在缓冲区optval中,由optlen 指向的整数指针开始应含有该缓冲区的大小,返回时,它被赋予返回值的长度大小。对于SO_LINGER,这将是结构linger 的大小;对于其他选项,它将是一整形值的长度。如果选项从未由setsockopt()设置,则getsockopt()返回该选项的默认值。
getsockopt()支持下表所列选项,TYPE 标志optval 指向的数据类型。TCP_NODELAY选项使用IPPROTO_TCP层,其它选项使用SOL_SOCKET层。
值类型含义默认值SO_ACCEPTCONN BOOL 套接字正在监听(listen())FALSE,除非
WSPListen()已
经被执行
SO_BROADCAST BOOL 套接字被设置用来发传广播消息FALSE
SO_DEBUG BOOL 允许Debugging FALSE
SO_DONTLINGER BOOL 如为真,SO_LINGER 选项被关闭TRUE
SO_DONTROUTE BOOL 路由选择关闭FALSE
SO_ERROR int 获取错误状态,并清除错误。0
SO_GROUP_ID GROUP 保留为将来的套接字组使用:套接字从属的组ID NULL
SO_GROUP_PRIORITY int 保留为将来的套接字组使用:套接字组中套接字
的相对优先级
SO_KEEPALIVE BOOL 正发送“keep a live(保持活动)”信息FALSE
SO_LINGER struct linger FAR * 返回当前linger 选项l_onoff 为0
SO_MAX_MSG_SIZE unsigned int 基于消息的套接字类型的最大外出(发送)消息
长度。对基于流的套接字无意义依赖于实现
SO_OOBINLINE BOOL 在正常的数据流中接收带外数据FALSE
SO_PROTOCOL_INFO WSAPROTOCOL_INFO 此套接字绑扎的协议的协议信息依赖于协议SO_RCVBUF int 接收缓冲区的大小依赖于实现SO_REUSEADDR BOOL 套接字可绑扎到一已在使用的地址上FALSE
SO_SNDBUF int 发送缓冲区的大小依赖于实现SO_TYPE int 套接字类型(例如,SOCK_STREAM)由socket()创建PVD_CONFIG 依赖于服务提供者服务提供者给套接字s 相关的一个不透明数据
结构。此对象存储了服务提供者当前的配置信
息。结构的确切格式由服务提供者指定
依赖于实现TCP_NODELAY BOOL 在发送聚结(coalescing)时关闭Nagle 算法依赖于实现
getsockopt()不支持的BSD 选项有:
值类型含义
SO_RCVLOWAT int 接收低潮标志(Low water)
SO_RCVTIMEO int 接收超时
SO_SNDLOWAT int 发送低潮标志
SO_SNDTIMEO int 发送超时
IP_OPTIONS 取得IP 头中的选项
TCP_MAXSEG int 取得TCP 最大段尺寸
使用不支持的选项调用getsockopt()函数将返回错误码WSAENOPROTOOPT,它由WSAGetLastError()函数返回。
参见:setsockopt(), socket(), WSAAsyncSelect(), WSAConnect(), WSAGetLastError(),
WSASetLastError()。
1.2.8 htonl()
语法:u_long WSAAPI
htonl ( IN u_long hostlong); // hostlong主机字节顺序表示的32 位无符号整数此函数将一个u_long类型数(32 位无符号整数)从主机字节顺序转换成TCP/IP 网络字节顺序。
返回值:htonl()返回一个TCP/IP 网络字节顺序表示的32 位值。
参见:htons(), ntohl(), ntohs(), WSAHtons(), WSAHtonl(), WSANtohl(), WSANtohs()。
1.2.9 htons()
语法:u_short WSAAPI
htons (IN u_short hostshort); // hostshort,主机字节顺序表示的16 位无符号整数
函数将一个u_short 类型数(16位无符号整数)从主机字节顺序转换成TCP/IP网络字节顺序。
返回值:htons()返回一个TCP/IP 网络字节顺序表示的16 位值。
参见:htonl(), ntohl(), ntohs(), WSAHtons(), WSAHtonl(), WSANtohl(), WSANtohs()。
1.2.10 inet_addr()
语法:unsigned long WSAAPI
inet_addr ( IN const char FAR * cp); //点分表示法表示的地址字符串此函数将一个用点分表示法表示的字符串地址转换成网际地址in_addr 形式。它解释由参数cp指示的字符串,该字符串代表用网际标准的点分表示法表示的网际地址。返回值是一个适用于网际地址的长整数。所有网际地址都以网络字节顺序(字节顺序从左到右)返回。
返回值:如果没有错误发生,inet_addr()返回一个无符号长整数,它用适合网际地址的二进制表示。如果传入的字符串不含有合理的网际地址,例如“a.b.c.d”地址的任何一部分超过255,则inet_addr()返回值INADDR_NONE。
注释:使用点分表示法表示的网际地址取下列形式的一种:
a.b.c.d a.b.c a.b a
如果四部分都指定了,每部分解释为一个字节数据,并从左到右赋给网际地址的四个字节。注意,当网际地址被看作Intel体系结构中的32位整数时,上述地址表示为“d.c.b.a”,这就是说,Intel 处理器中的字节顺序是从右到左的。
注意:下述标记只用于Berkeley,不能用于网际的其它部分。为了与它们的软件兼容,这些都需要特殊支持。
当指定了一个三部分的地址时,最后一部分解释为16位整数,并放入网络地址最右端的两字节中。这使得三部分地址适宜于将B类网络地址指定为“https://www.doczj.com/doc/2813938826.html,.host”。
当指定了一个两部分的地址时,最后一部分解释为24 位整数,并放入网络地址最右端的三字节中。这使得两部分地址适宜于将A 类网络地址指定为“net.host”。
当只指定了一部分时,该值直接存入网络地址,毋需进行字节的重新安排。点分表示法中作为地址的数字可以是十进制、十六进制或八进制,这些数字按C语言语法进行解释。以0x 打头表示十六进制,以0 打头表示八进制,以非零打头表示十进制,最常用的是点分十进制表示法。
参见:inet_ntoa()。
1.2.11 inet_ntoa()
语法:char FAR * WSAAPI
inet_ntoa ( IN struct in_addr in); // in,表示主机网际地址的结构
此函数将一个网际地址转换成点分十进制表示法表示的字符串。它接受由参数in 指定的网际地址结构,返回以点分表示法如“a.b.c.d”表示的地址的ASCII 字符串。
返回值:如果没有错误发生,inet_ntoa()返回一个字符指针,该指针指向含有以点分十进制表示法表示的正文地址的静态缓冲区;否则返回NULL。
注释:值得注意的是,inet_addr()返回的字符串保存在Windows Sockets实现分配的内存中,应用程序不应对内存是如何分配的做任何假定。该数据一直保持有效直到同一线程的下一个Windows Sockets API 调用。这样,在下一个Windows Sockets API 调用前,数据应当备份出来。参见:inet_addr()。
1.2.12 ioctlsocket()
语法:int WSAAPI
ioctlsocket ( IN SOCKET s, // s,套接字描述符
IN long cmd, // cmd,在套接字s上执行的命令
IN OUT u_long FAR* argp ); // argp,指向cmd命令的参数的指针此函数控制套接字模式,它用于处在任何状态的任何套接字,用来获取或检索与套接字相关的,独立于协议和通讯子系统的操作参数。
返回值:成功结束则ioctlsocket()返回0。否则它返回SOCKET_ERROR,错误码可通过调用WSAGetLastError()函数得到。
错误码:
WSANOTINITIALISED:未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN:Windows Sockets实现检测到网络系统已经失败。
WSAEINVAL:cmd 是非法命令,或者argp是cmd不可接受的参数,或者此命令不能应用于套接字支持的类型。
WSAEINPROGRESS:一个阻塞的Windows Sockets操作正在进行。
WSAENOTSOCK:此描述符不是套接字描述符。
WSAEFAULT:参数argp不是用户地址空间的合法部分。
注释:此函数是Berkeley Sockets中ioctl()的子集。特别地,没有与FIOASYNC相当的命令,而
SIOCATMARK 是唯一支持的套接字层命令。它支持的命令描述如下:
FIONBIO:
设置或禁止套接字s上的非阻塞模式。argp指向一个无符号长整数,如设置套接字为非阻塞模式则为非零值,禁止非阻塞时为零值。当套接字建立时,它工作于阻塞模式(即非阻塞模式禁止),这与BSD套接字一致。函数WSAAsyncSelect()或WSAEventSelect()自动地设置套接字为非阻塞模式。如果WSAAsyncSelect()或WSAEventSelect()已经在一个套接字执行过,那么使用ioctlsocket()将套接字设置为阻塞模式的任何企图都将以错误码WSAEINVAL 失败。为了将套接字设置为阻塞模式,应用程序必须先用WSAAsync Select()带参数lEvent 值为0 的调用来禁止WSAA syncSelect()的作用,或用WSAEventSelect()带参数lNetworkEvents值为0 的调用来禁止WSAEventSelect()的作用
FIONREAD:
检测可从套接字s 中立即读出的数据量。argp指向ioctlsocket()存放结果的无符号整数。如果s 是SOCK_STREAM类型,FIONREAD返回可由一次recv()读出的总数据量;这通常与套接字上排队的总数据量一致。如果s 是SOCK_DGRAM 类型,FIONREAD 返回在套接字上排队的第一个数据报的大小。
SIOCATMARK:
检测是否所有的带外数据都已读出。这只适用于SOCK_STREAM类型的套接字,并且它们被设置为在正常数据流中接收任何带外数据(SO_OOBINLINE)时有作用。如果没有带外数据等待读,该操作返回TRUE;否则返回FALSE,并且在套接字上执行的下一个recv()或recvfrom() 将接收“mark(标记)”之前的部分或全部数据。应用程序可用SIOCATMARK 操作查看是否还有剩余数据。如果在“紧急”(带外)数据之前存在任何正常数据,它们都将按顺序接收,recv()或recvfrom()不会在同一个调用中混合带外数据和正常数据。argp指向一个布尔型变量,ioctlsocket()在其中存入返回值。
参见:socket(), setsockopt(), getsockopt(), WSAAsyncSelect(), WSAEventSelect(), WSAIoctl()。
1.2.13 listen()
语法:int WSAAPI
listen ( IN SOCKET s, // s标识一个已绑扎、没有连接的套接字描述符IN int backlog); // backlog,未处理连接队列的最大长度
此函数只用于流套接字,它执行两个操作:
1).若没有为s 调用过bind(),则listen()完成套接字s所必须的连接。
2).建立长度为backlog的连接请求队列来存放即将到来的连接请求。
返回值:如果没有错误发生,listen()返回0。否则它返回SOCKET_ERROR,错误码可通过调用WSAGetLastError()函数得到。
错误码:
WSANOTINITIALISED:未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN:Windows Sockets实现检测到网络系统已经失败。
WSAEADDRINUSE:套接字的本地地址已被使用,并且该套接字没有使用SO_REUSEADDR 来设置允许地址重用。此错误经常发生在函数bind()调用时,但当bind()函数使用通
配地址(包括ADDR_ANY)并且在listen()函数调用时需要“提交”一个指定
地址时,此错误能够延迟到listen()函数。
WSAEINPROGRESS:一个阻塞的Windows Sockets 操作正在进行。
WSAEINVAL:套接字没有使用bind()绑扎或已经连接。
WSAEISCONN:套接字已经连接。
WSAEMFILE:无描述符可用。
WSAENOBUFS:无缓冲区空间可用。
WSAENOTSOCK:此描述符不是套接字描述符。
WSAEOPNOTSUPP:套接字不是listen()操作支持的类型。
注释:listen()调用表明套接字准备好接收客户连接请求。它将主动套接字变为被动套接字,一旦变换后,s 将再不能作为主动套接字来初始化连接请求。调用listen()是服务器接收一个连接请求的四个步骤中的第三步。它在调用socket()函数分配一个流套接字,且调用bind() 函数给s 连接一个名字之后调用,而且一定要在函数accept()之前调用。
此函数用于同一时刻有多个连接请求的服务器:如果一个连接在请求到达时队列已满,此连接请求被忽略,并且客户将收到WSAECONNREFUSED 指示的错误。
当没有可用描述符时,listen()试图继续执行下去,它接收连接直到队列变空为止。如果又
有可用描述符(系统释放了一些描述符),稍后调用的listen()或accept()将队列重新填到当前的或最近的“backlog(后备日志)”,如果可能的话,恢复对外来连接的监听。
应用程序可以对同一个套接字调用多次listen()函数,其结果是更新了监听套接字的当前“后备日志”。如果未处理的连接比新的backlog值还多,则超出部分被重置或丢弃。
在WinSock 1.1中,bac klog的最大值是5。如果backlog小于1,则backlog 被置为1;若backlog大于SOMAXCONN(定义在winsock.h中,值为5),则backlog 被置为SOMAXCONN。在WinSock 2中,没有指定具体值,它由服务提供者决定。
参见:accept(), connect(), socket()。
1.2.14 ntohl()
语法:u_long WSAAPI ntohl (IN u_long netlong );//32位无符号整数(网络字节顺序) 此函数将一个u_long类型的数(32 位无符号整数)从TCP/IP 网络字节顺序转换成主机字节顺序。
返回值:ntohl()返回主机字节顺序表示的32 位值。
参见:htonl(), htons(), ntohs(), WSAHtons(), WSAHtonl(), WSANtohl(), WSANtohs()。
1.2.15 ntohs()
语法:u_short WSAAPI ntohs (IN u_short netshort ); // 16 位无符号整数(网络字节顺序) 此函数将一个u_short类型的数(16位无符号整数)从TCP/IP 网络字节顺序转换成主机字节顺序。
返回值:ntohs()返回主机字节顺序表示的16 位值。
参见:htonl(), htons(), ntohl(), WSAHtons(), WSAHtonl(), WSANtohl(), WSANtohs()。
1.2.16 recv()
语法:int WSAAPI
recv ( IN SOCKET s, // s,已连接的套接字描述符
OUT char FAR* buf, // buf,指向接收输入数据缓冲区的指针
IN int len, // len,buf 参数所指缓冲区的长度
IN int flags ); // flags,指定调用的方式
此函数用于在参数s指定的已连接的数据报或流套接字上读取输入数据。
flags,指定调用的方式,它可用来与套接字相关的选项一起影响函数的功能。就是说,recv()函数的意义由套接字选项和flags参数共同决定。flags 可取下列值:
MSG_OOB,读取套接字上的带外数据。
MSG_PEEK,查看输入数据,数据被拷入缓冲区中, 但不从输入队列中清除。
返回值:如果没有错误发生,recv()返回收到的字节数。如果连接被关闭,返回0。否则它返回SOCKET_ERROR,错误码可通过调用WSAGetLastError()函数得到。
错误码:
WSANOTINITIALISED:未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN:Windows Sockets实现检测到网络系统已经失败。
WSAEFAULT:参数buf不是用户地址空间的合法部分。
WSAENOTCONN:套接字未建立连接。
WSAEINTR:(阻塞)调用被WSACancelBlockingCall()函数取消。
WSAEINPROGRESS:一个阻塞的Windows Sockets操作正在进行。
WSAENETRESET:在操作进行时“keep-alive”活动检测到一个失败,连接被中断。WSAENOTSOCK:此描述符不是套接字描述符。
WSAEOPNOTSUPP:MSG_OOB被指定,但是套接字不是流风格的(如SOCK_STREAM类型),此套接字相关的通讯域不支持带外数据;或套接字是单向的,只支持发送操作。WSAESHUTDOWN:套接字已经shutdown,recv()不可能在套接字上执行了how参数SD_RECEIVE 或SD_BOTH的shutdown()调用后执行。
WSAEWOULDBLOCK:套接字被标识为非阻塞,但接收操作将被阻塞。
WSAEMSGSIZE:数据报太大,以致不能装入指定的缓冲区,数据报被截断。WSAEINVAL:套接字没有使用bind()绑扎;或指定了未知标志;或套接字的SO_OOBINLINE属性允许却指定了MSG_OOB 标志;或参数len为0或负数。WSAECONNABORTED:虚电路因超时或其它失败而中断。
WSAETIMEOUT:连接因网络失败或对等方系统不能响应而丢弃。
WSAECONNRESET:虚电路被远程方复位。
注释:此函数用在参数s指定的连接套接字或已绑扎的无连接套接字上,用来读取进来的数据。
套接字的本地地址必须已知。对于服务器方应用程序来说,这常常通过显式地调用bind()函数完成,或调用accept()/WSAAccept()函数附带完成。客户方应用程序不鼓励对套接字使用显式的绑扎,它可以通过函数connect()、WSAConnect()、sendto()、WSASendTo()或WSAJoinLeaf()来将套接字附带变为绑扎的。
无论是连接还是无连接套接字,此函数都严格限制可接收的接收消息来源地址。此函数只返回从连接中指定的远程地址到来的消息,从其它地址到来的消息被丢弃。
对于流风格套接字(如SOCK_STREAM类型),最多可返回最大缓冲区长度的信息。如果套接字被设置用于在正常数据流中接收带外数据(套接字选项SO_OOBINLINE), 并且带外数据未读取, 那么只返回带外数据。应用程序可使用ioctlsocket()或WSAIoctl()函数的SIOCATMARK 命令来查看是否还有带外数据未读出。
对于基于消息的套接字(如SOCK_DGRAM类型),数据从函connect()指定的目的地址的第一个排队数据报中抽取出来,最多可有最大缓冲区长度的信息。如果数据报比提供的缓冲区大,则缓冲区填以数据报的第一部分,recv()返回错误码WSAEMSGSIZE。对于不可靠协议(如UDP),多余的数据就丢失了;对于可靠协议,数据被服务提供者保留,直到它们被使用了足够大的缓冲区的recv()调用读取。
如果套接字上没有输入数据,那么除非是非阻塞模式,否则recv()函数将一直等待数据的到来,此时将返回SOCKET_ERROR错误,错误码设为WSAEWOULDBLOCK。应用程序可通过调用select()、WSAAsyncSelect()或WSAEventSelect()函数来查看何时有数据到来。
如果套接字是面向连接的, 并且远程方已“雅致”地关闭了连接,所有数据也已经被接收,则recv()立即返回,接收0字节数据。如果连接被复位,recv()将失败,错误码为WSAECONNRESET。参见:recvfrom(), read(), send(), select(), WSAAsyncSelect(), socket()。
1.2.17 recvfrom()
语法:int WSAAPI
recvfrom ( IN SOCKET s, //套接字描述符
OUT char FAR* buf, //指向接收输入数据缓冲区的指针
IN int len, // buf 参数指向的缓冲区的长度
IN int flags, // flags,指定调用的方式
OUT struct sockaddr FAR* from, //任选指针,它指示源地址缓冲区
IN OUT int FAR* fromlen );//任选指针,它指示from长度此函数用于在参数s指定的套接字(可能已连接)上读取输入数据,并捕获发送数据的地址,存入源地址缓冲区。
flags,指定调用的方式,它可用来与套接字相关的选项一起影响函数的功能。就是说,recvfrom() 函数的意义由套接字选项和flags参数共同决定。flags可取下列值:
MSG_OOB 读取套接字上的带外数据。
MSG_PEEK 查看输入数据,数据被拷入缓冲区中, 但不从输入队列中清除。
返回值:如果没有错误发生,recvfrom()返回收到的字节数。如果连接被关闭,返回0。否则它返回SOCKET_ERROR,错误码可通过调用WSAGetLastError()函数得到。
错误码:
WSANOTINITIALISED:未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN:Windows Sockets实现检测到网络系统已经失败。
WSAEFAULT:参数buf或from不是用户地址空间的合法部分;或参数fromlen 太小,不能容下对等方地址。
WSAEINTR:(阻塞)调用被WSACancelBlockingCall()函数取消。
WSAEINPROGRESS:一个阻塞的Windows Sockets 操作正在进行。
WSAEINVAL:套接字没有使用bind()绑扎;或指定了未知标志;或套接字的SO_OOBINLINE属性允许却指定MSG_OOB标志;或参数len为0 或负数。
WSAEISCONN :套接字已连接。此函数不允许在已连接套接字上使用,不管套接字是面向连接的还是无连接的。
WSAENETRESET:在操作进行时“keep-alive”活动检测到一个失败,连接被中断。WSAENOTSOCK:此描述符不是套接字描述符。
WSAEOPNOTSUPP:MSG_OOB被指定,但是套接字不是流风格的(如SOCK_STREAM 类型),此套接字相关的通讯域不支持带外数据;或套接字是单向的,只支持发送操作。WSAESHUTDOWN:套接字已经shutdown,recv()不可能在套接字上执行了how 参数为SD_RECEIVE 或SD_BOTH的shutdown()调用后执行。
WSAEWOULDBLOCK:套接字被标识为非阻塞,但接收操作将被阻塞
WSAEMSGSIZE:数据报太大,以致不能装入指定的缓冲区,数据报被截断WSAECONNABORTED:虚电路因超时或其它失败而中断
WSAETIMEOUT:连接因网络失败或对等方系统不能响应而丢弃。
WSAECONNREST:虚电路被远程方复位。
注释:此函数用在参数s指定的连接套接字或已绑扎的无连接套接字上,用来读取进来的数据。套接字的本地地址必须已知。对于服务器方应用程序来说,这常常通过显式地调用bind()函数完成,或调用accept()/WSAAccept()函数附带完成。客户方应用程序不鼓励对套接字使用显式的绑扎,它可以通过函数connect()、WSAConnect()、sendto()、WSASendTo()或WSAJoinLeaf()来将套接字附带变为绑扎的。
无论是连接还是无连接套接字,此函数都严格限制可接受的接收消息来源地址。此函数只返回从连接中指定的远程地址到来的消息,从其它地址到来的消息被丢弃。
流风格套接字(如SOCK_STREAM类型),最多可返回最大缓冲区长度的信息。如果套接字被设置用于在正常数据流中接收带外数据(套接字选项SO_OOBINLINE), 并且带外数据未读取, 那么只返回带外数据。应用程序可使用ioctlsocket()或WSAIoctl()函数的SIOCATMARK 命令来查看是否还有带外数据未读出。对于SOCK_STREAM 套接字,from 和fromlen参数被忽略。
对于基于消息的套接字,数据从第一个排队的数据报中抽取出来,最多可有最大缓冲区长度的信息。如果数据报比提供的缓冲区大,则缓冲区填以数据报的第一部分,recvfrom()返回错误码WSAEMSGSIZE。对于不可靠协议(如UDP),多余的数据被丢失。
如果from非零,且套接字是SOCK_DGRAM 类型,发送数据的对等方的网络地址被拷入对应的结构sockaddr中。fromlen指向的值被初始化为该结构的大小,返回时被改变为存入此处的地址的实际大小。
如果套接字上没有输入数据,那么除非是非阻塞模式,否则recvfrom()函数将一直等待数据的到来,此时将返回SOCKET_ERROR 错误,错误码设为WSAEWOULDBLOCK。应用程序可通过调用select()、WSAAsyncSelect()或WSAEventSelect()函数来查看何时有数据到来。
如果套接字是面向连接的, 并且远程方已“雅致”地关闭了连接,recvfrom()将立即返回,接收0字节数据。如果连接被复位,recv()将失败,错误码为WSAECONNRESET。
参见:recv(), send(), select(), WSAAsyncSelect()。
1.2.18 select()
语法:int WSAAPI
select ( IN int nfds,
IN OUT fd_set FAR * readfds,
IN OUT fd_set FAR * writefds,
IN OUT fd_set FAR * exceptfds,
IN const struct timeval FAR * timeout );
此函数用来检测一个或多个套接字的状态。对每一个套接字来说,这个调用可以请求读、写或错误状态方面的信息。请求给定状态的套接字集合由一个fd_set 结构指示。在返回时,此结构被更新,以反映那些满足特定条件的套接字的子集,同时,select()函数返回满足条件的套接字的数目。
参数描述:
nfds,此变量被忽略,包括它只是为了兼容性。
readfds,指向要检测是否可读的套接字集合的可选指针。
writefds,指向要检测是否可写的套接字集合的可选指针。
exceptfds,指向要检测是否出错的套接字集合的可选指针。
timeout,指向select()函数等待的最大时间的结构指针,如果设为NULL则为阻塞操作。
返回值:select()返回包含在fd_set结构中已准备好的套接字描述符的总数目,如果是限制时间到了仍没有准备好的套接字描述符则返回0 ,或者是发生错误则返回SOCKET_ERROR,
并且错误码可通过调用WSAGetLastError()函数得到。
错误码:
WSANOTINITIALISED:未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN:Windows Sockets 实现检测到网络系统已经失败。
WSAEFAULT:WinSock实现不能为内部操作分配必要的资源,或参数readfds,writefds,exceptfds 或timeval不是用户地址空间的合法部分。
WSAEINVAL:参数timeout的值不合法,或三个描述符参数都为NULL。
WSAEINTR:此阻塞调用被WSACancelBlockingCall()函数取消。
WSAEINPROGRESS:一个阻塞的Windows Sockets操作正在进行。
WSAENOTSOCK:有一个描述符集合包含了一个不是套接字的入口。
注释:参数readfds标识那些要检测是否可读的套接字。如果一个套接字正在监听listen(),在它收到一个进来的连接请求时它将被标记为可读的,此时accept()调用可确保无阻塞完成。对于其它套接字,可读意味着排队的数据可用来读,或者SOCK_STREAM类型的套接字意味着此套接字对应的虚拟套接字已经关闭,因此recv()、recvfrom()、WSARecv()或WSARecvFrom()函数都可确保无阻塞完成。
对于面向连接的套接字,可读也可能意味着接收到对等方的关闭请求。如果如果虚电路被“雅致”关闭,并且所有数据被接收,则recv()立即返回,所读取的字节为0。如果虚电路被重置,那么recv()立即返回错误码WSAECONNRESET 。如果套接字选项设置了SO_OOBINLINE(参见setsockopt()),则带外数据的到来也将被检测。
参数writefds 标识那些要检查是否可写的套接字。如果一个套接字正在连接(connect(),非阻塞方式),可写意味着成功地建立了连接;其它情况,可写意味着一个send()、sendto()、WSA Send()或WSASendto()调用将在无阻塞情况下完成。然而,对于阻塞套接字来说,如果要发送的数据长度len超出了系统的可用的输出缓冲区长度,发送操作也可能阻塞。(没有说明此担保在多长时间内是合法的, 特别是在多线程环境中)。
参数exceptfds 标识那些待检测是否有带外数据出现或者任何异常的错误条件的套接字。注意带外数据只有在选项SO_OOBINLINE为FALSE时才报告。对一个SOCK_STREAM来说,连接被对等方中断或由于KEEPALIVE失败将由一个异常指示。如果一个套接字正在连接(connect(),非阻塞方式), 连接失败也在exceptfds中指示。
如果没有感兴趣的套接字描述符,readfds,writefds 或exceptfds 可以给定为NULL,但至少有一个非空。
下面给出套接字在select()函数返回的集合中存在的条件小结:
readfds:
2 如果在监听(listen()ing),则有为处理连接到来,accept()将成功返回;
2 有数据可读(如果SO_OOBINLINE允许则包括OOB 数据);
2 连接被关闭/重置/终止。
writefds:
2 如果正连接(connect()ing),则说明连接已经成功;
2 数据可以被发送。
exceptfds:
2 如果正连接(connect()ing),连接试图失败;
2 有OOB数据可读(只在SO_OOBINLINE 禁止时有效)。
为了操作套接字描述符集合, 在头文件winsock.h中定义了一组操作fd_set结构的宏,它们是:
FD_CIR(s, *set) 从集合中删除描述符s
FD_ISSET(s, *set) 如果描述符s是集合中的一个元素,则返回非0;否则返回0
FD_SET(s, *set) 增加描述符到集合中
FD_ZERO(*set) 初始化集合为NULL集
变量FD_SETSIZE决定集合中最多可容纳的描述符数目(在winsock.h中,FD_SETSIZE的默认值为64,它可通过在#include winsock.h之前通过定义#define FD_SETSIZE 为其他值来修改)。在内部,fd_set表示为一个SOCKET的数组,最后合法的入口后跟一个设置为INVALID_SOCKET的元素。
参数timeout 控制多长时间select()将完成。如果timeout为一个null指针,select() 将无限阻塞,直到至少一个描述符满足特定的条件。否则,timeout指向一个结构timeval,它描述select()在返回前等待的最大时间。如果结构timeval 初始化为{0,0},select()将立即返回;这用来获取选择的套接字的状态。如果是这种情况, 那么select()调用被认为是非阻塞方式,并且适用对非阻塞调用的标准假设。例如,不必调用阻塞处理例程,并且Windows Sockets 实现不必放弃控制权。
参见:WSAAsyncSelect(), accept(), connect(), recv(), recvfrom(), send(), WSAEventSelect()。
1.2.19 send()
语法:int WSAAPI
send ( IN SOCKET s, // s,已连接的套接字描述符
IN const char FAR * buf, // buf,指向存有发送数据的缓冲区的指针
IN int len, // len,缓冲区 b uf 中数据长度
IN int flags ); // flags,指定调用的方式
此函数用于在参数s指定的已连接的数据报或流套接字上发送输出数据。
flags ,指定调用的方式,它可用来与套接字相关的选项一起影响函数的功能。就是说,send()函数的意义由套接字选项和 f lags 参数共同决定。flags 可取下述值:
MSG_DONTROUTE 指出数据不提交给路由选择。
MSG_OOB 发送带外数据。
返回值:如果没有错误发生,send()返回总共发送的字节数(注意,这可能比 len指示的长度小)。否则它返回 S OCKET_ERROR,错误码可通过调用 W SAGetLastError()函数得到。
错误码:
WSANOTINITIALISED:未初始化 W indows Sockets DLL,在使用此函数之前必须有一次成功的
WSAStartup()函数调用。
WSAENETDOWN:Windows Sockets实现检测到网络系统已经失败。
WSAEACCES:请求地址是广播地址,但是相应的 f lags没设置。
WSAENOTCONN:套接字未建立连接。
WSAEINTR:(阻塞)调用被WSACancelBlockingCall()函数取消。
WSAEINPROGRESS:一个阻塞的Windows Sockets操作正在进行。
WSAEFAULT:参数buf不是用户地址空间的一个合法部分。
WSAENETRESET:在操作进行时“keep-alive”活动检测到一个失败,连接被中断。WSAENOBUFS:无缓冲区空间可用。
WSAENOTSOCK:此描述符不是套接字描述符。
WSAEOPNOTSUPP:MSG_OOB 被指定,但是套接字不是流风格的(如SOCK_STREAM类型),此套接字相关的通讯域不支持带外数据;或套接字是单向的,只支持发送操作。WSAESHUTDOWN:套接字已经shutdown。send()不可能在套接字上执行了how参数为SD_SEND或SD_BOTH的shutdown()调用后执行。
WSAEWOULDBLOCK:套接字被标识为非阻塞,但发送操作将被阻塞。
WSAEMSGSIZE:套接字为基于消息的,消息太大,大于底层传输支持的最大值。WSAEINVAL:套接字没有使用bind()绑扎;或指定了未知标志;或套接字的SO_OOBINLINE属性允许却指定了MSG_OOB标志。
WSAECONNABORTED:虚电路因超时或其它失败而中断。
WSAECONNRESET:虚电路被远程方复位。
WSAETIMEOUT:连接因网络失败或对等方系统不能响应而丢弃。
注释:对数据报套接字来说,一定要注意一次发送的数据不能超过下层子网的最大 I P包大小,该值在 W SAStartup()返回的 W SAData结构的 i MaxUdpDg中给出。如果数据太长,不能通过下面的协议,将返回错误 W SAEMSGSIZE,并且没有数据传输。
注意,send()函数只是将数据传送到输出缓冲区,它执行成功并不意味着数据功地发送出去了。如果传输系统中没有可用缓冲区用来保存传输数据,send()将阻塞,除非套接字被设置为
非阻塞 I/O模式。在非阻塞 S OCK_ S TREAM套接字上,写的字节数可为从 1到请求的长度,这由
本地和外部主机上可用的缓冲区大小决定。select() 、WSAAsyncSelect() 或 WSAEventSelect()
函数可用来查看何时可能发送更多的数据。
参见:recvfrom(), recv(), sendto(), WSA S tartup(), socket(), WSAAsyncSelect(), WSAEventSelect()。
1.2.20 sendto()
语法:int WSAAPI
sendto(
IN SOCKET s,
IN const char FAR * buf,
IN int len,
IN int flags,
IN const struct sockaddr FAR * to,
IN int tolen );
此函数用于在参数s指定的数据报或流套接字上向指定目的地发送输出数据。
参数描述:
s,套接字描述符。
buf,指向存有发送数据的缓冲区的指针。
len,缓冲区buf中数据长度。
flags,指定调用的方式,它可用来与套接字相关的选项一起影响函数的功能。就是说,sendto() 函数的意义由套接字选项和flags参数共同决定。flags 可取下述值:
MSG_DONTROUTE 指出数据不提交给路由选择。
MSG_OOB 发送带外数据。
to,指向目的套接字地址的任选指针。
tolen,to 参数所指地址的长度。
返回值:如果没有错误发生,sendto() 返回总共发送的字节数(注意,这可能比len指示的长度小)。否则它返回SOCKET_ERROR,错误码可通过调用WSAGetLastError()函数得到。错误码:
WSANOTINITIALISED:未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN:Windows Sockets 实现检测到网络系统已经失败。
WSAEACCES:请求地址是广播地址,但是相应的flags没设置。
WSAENOTCONN:套接字未建立连接。
WSAEINTR:(阻塞)调用被WSACancelBlockingCall()函数取消。WSAEINPROGRESS:一个阻塞的Windows Sockets 操作正在进行。
WSAEFAULT:参数buf或to不是用户地址空间的一个合法部分,或者参数to太小(小于结构sockaddr的长度)
WSAENETRESET:在操作进行时“keep-alive”活动检测到一个失败,连接被中断。WSAENOBUFS:无缓冲区空间可用。
WSAENOTSOCK:此描述符不是套接字描述符。
WSAEOPNOTSUPP:MSG_OOB被指定,但是套接字不是流风格的(如SOCK_STREAM 类型),此套接字相关的通讯域不支持带外数据;或套接字是单向的,只支持发送
操作。
WSAESHUTDOWN:套接字已经shutdown。send()不可能在套接字上执行了how 参数为
SD_SEND或SD_BOTH 的shutdown()调用后执行。WSAEWOULDBLOCK:套接字被标识为非阻塞,但发送操作将被阻塞。WSAEMSGSIZE:套接字为基于消息的,消息太大,大于底层传输支持的最大值。WSAEHOSTUNREACH:主机此时不能到达远程主机。
WSAEINVAL:套接字指定了未知标志;或套接字的SO_OOBINLINE 属性允许却指定了MSG_OOB标志。
WSAECONNABORTED:虚电路因超时或其它失败而中断。
WSAECONNRESET:虚电路被远程方复位。
WSAETIMEOUT:连接因网络失败或对等方系统不能响应而丢弃。WSAEADDRNOTAVAIL:指定的地址在本地机器不可用。
WSAEAFNOSUPPORT:此套接字不能使用指定地址族的地址。WSAEDESTADDRREQ:要求目标地址。
WSAENETUNREACH:主机此时不能到达网络。
注释:对数据报套接字来说,一定要注意一次发送的数据不能超过下层子网的最大IP 包大
小,该值在WSAStartup()返回的WSAData结构的iMaxUdpDg 中给出。如果数据太长,不能通过下面的协议,将返回错误WSAEMSGSIZE,并且没有数据传输。
注意,sendto()函数只是将数据传送到输出缓冲区,它执行成功并不意味着数据成功地发送出去了。如果传输系统中没有可用缓冲区用来保存传输数据,sendto()将阻塞,除非套接字被设置为非阻塞I/O模式。在非阻塞SOCK_STREAM套接字上,写的字节数可为从1 到请求的长度,这由本地和外部主机上可用的缓冲区大小决定。select(),WSA AsyncSelect() 或WSAEventSelect()函数可用来查看何时可能发送更多的数据。
sendto()函数通常用在SOCK_DGRAM套接字上,用于向参数to指定的对等方套接字发送数据报。对于SOCK_STREAM 套接字,to和tolen参数被忽略,在这种情况下,sendto() 等同于send()。
为了发送广播消息(仅用于SOCK_DGRAM套接字),参数to中的地址需要用特殊的IP 地址INADDR_BROADCAST(在winsock.h中定义)和一定的端口号构成。通常广播数据报不应超长,否则就会出现碎片,这意味着数据报的数据部分(不包括头)不应超过512 字节。参见:recvfrom(), recv(), send(), WSAStartup(), socket(), WSAAsyncSelect(), WSAEventSelect() 。
1.2.21 setsockopt()
语法:int WSAAPI
setsockopt ( IN SOCKET s,
IN int level,
IN int optname,
IN const char FAR * optval,
IN int optlen );
此函数为套接字相关的选项设置当前值,套接字可以是任何类型,可以处于任何状态。尽管选项可存在于多个协议层次,但是它们总是表现在最高的“socket”层。选项影响套接字操作,如加急数据是否在正常数据流中接收、广播消息是否可以在套接字上发送等。
参数描述:
s,套接字描述符。
level,选项定义的层次,只支持SOL_SOCKET和IPPROTO_TCP。
optname,指定套接字选项的名字。
optval,指向请求选项数据缓冲区的指针。
optlen,选项数据optval缓冲区的长度。
返回值:如果没有错误发生,setsockopt()返回0。否则它返回值SOCKET_ERROR,错误码可通过调用WSAGetLastError()函数得到。
错误码:
WSANOTINITIALISED:未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN:Windows Sockets实现检测到网络系统已经失败。WSAEINPROGRESS:一个阻塞的Windows Sockets操作正在进行。
WSAENOTCONN:在设置了SO_KEEPALIVE 时连接已被复位。
WSAEFAULT:参数optval不是进程地址空间的合法部分,或参数optlen 太小。WSAENETRESET:在操作进行时“keep-alive”活动检测到一个失败,连接被中断。WSAENOTSOCK:此描述符不是套接字描述符。
WSAENOPROTOOPT:未知或不支持的选项。特别地,SOCK_STREAM 类型的套接字不支持SO_BROADCAST;而SOCK_DRAGM类型的套接字不支持
SO_DONTLINGER, SO_KEEPALIVE, SO_LINGER 和SO_OOBINLINE。
WSAEINVAL:参数level不合法,或参数optval 中的信息不合法。
注释:套接字选项有两种类型:设置或禁止特征/行为的布尔(Boolean )选项,以及要求整数值或结构的选项。为了设置一个布尔选项,optval 应指向一个非零整数;如果禁止此选项,optval 应指向一个等于零的整数。对布尔选项来说,optlen 应该等于整型数的长度。对于其它选项,optval 指向一个包含了选项要求值的整数或结构,并且optlen 为此整数或结构的长度。
当套接字上有未发送数据并执行closesocket()调用时,其动作由SO_LINGER 选项控制。关于SO_LINGER设置影响closesocket()语义的描述请参见closesocket()函数的说明。应用程序通过使用下面列出的结构linger(由参数optval 指定)来设置要求的行为:
struct linger { intl_onoff; intl_linger;}
为了设置SO_LINGER 选项,应用程序应该设置l_onoff 为非零值,设置l_ linger 为0 或要求的超时(单位:秒),并调用setsockopt()函数。要设置SO_DONTLINGER(禁止SO_LINGER),l_onoff 应该设置为0,并调用setsockopt()函数。
一般来说,系统默认采用SO_DONTLINGER方式,即当套接字在关闭时,closesocket() 不等待立即返回,但套接字资源也可能不立即释放。如果此时重新启动应用程序,则在调用bind()函数将以错误码WSAEADDRINUSE 失败返回,应用程序无法继续执行。为了解决这一问题,使套接字在关闭后系统能够立即释放套接字资源,我们可以使用SO_LINGER 选项,并且使l_onoff 为1 且l_linger 为0,即“hard(强制)”关闭。相关程序片段为:struct linger ling1;
newsock = accept(mainsock, &addr, &len);
ling1.l_onoff = 1;
ling1.l_linger = 0;
setsockopt(newsock, SOL_SOCKET, SO_LINGER, &ling1, sizeof(ling1));
套接字一般默认为不能绑扎bind()到一个已经使用的本地地址。然而,它偶尔会要求用这种方式“重用”一个地址。既然每一个连接是通过本地地址和远程地址来唯一地识别的,那么在远程地址不同时,两个套接字绑扎到同一个本地地址就不存在问题。为了通知Windows Sockets 实现不必因为套接字上的bind()调用所要求的地址被其它套接字使用而禁止,应用程序应该在调用bind()之前为此套接字设置SO_REUSEADDR 套接字选项。注意此选项只在bind()调用时解释:因此在不绑扎到地址的套接字上设置此选项是不必要的(也无害的),并且在bind()函数之后设置或取消此选项对此套接字或其它套接字都没影响。
应用程序可能通过打开SO_KEEPALIVE 套接字选项开关来请求Windows Sockets 实现允许在TCP连接上使用“保持运行(keepalive)”包。TCP使用一个叫做“保持运行计时器”(keepalive timer)的计时器,该计时器监视那些可能由于匹配系统崩溃或超时而被断开的空闲连接。若此选项有效,将定时向匹配者发送一个保持运行包。这主要用于允许服务器关闭那些已经消失的连接,这是用户未关闭连接就离开所造成的后果。此选项仅对流套接字有意义。如果连接因为“保持运行”的原故而被丢弃,那么在此套接字上进行的任何调用都将返回错误码WSAENETRESET,并且后续的调用将以WSAENOTCONN失败。
选项TCP_NODELAY 取消Nagle 算法(RFC896)。Nagle 算法用来减少主机的小包发送数量,它通过缓冲未确认的发送数据直到能够发送一个全长度的包来做到这一点。然而,对某些应用程序来说,此算法可能妨碍性能,可以用TCP_NODELAY 选项来关闭它。既然设置TCP_NODELAY 选项可能对网络性能有很大的消极影响,应用程序一般不要设置它,除非这样做的影响是很好理解的,并且是必要的。TCP_NODELAY是IPPROTO_TCP 层唯一支持的选项;所有其他选项都使用SOL_SOCKET层。
setsockopt()支持下列选项。“类型”标识optval 寻址的数据类型。
值类型含义
SO_BROADCAST BOOL 允许在套接字上传输广播消息。
SO_DEBUG BOOL 记录调试信息。
SO_DONTLINGER BOOL 在有数据等待发送时不阻塞关闭。设置此选项等价于用l_onoff
值为0 来设置SO_LINGER选项。
SO_DONTROUTE BOOL 绕开路由选择:直接发送到接口。
SO_GROUP_PRIORITY int 保留为将来的套接字组使用:套接字组中套接字的相对优先级。SO_LINGER struct linger FAR * 若有未发送的数据则延迟关闭。
SO_OOBINLINE BOOL 在正常数据流中接收带外数据。
SO_RCVBUF int 指定接收缓冲区长度
SO_REUSEADDR BOOL 允许套接字绑扎到一个已在使用的地址上(参见bind())。
SO_SNDBUF int 指定发送缓冲区长度
PVD_CONFIG 依赖于服务提供
者服务提供者给套接字s 相关的一个不透明数据结构。此对象存储了服务提供者当前的配置信息。结构的确切格式由服务提供者指定
setsockopt()不支持的Berkeley Sockets 选项:
值类型含义
SO_ACCEPTCONN BOOL 套接字正在监听
SO_ERROR int 取错误状态并清除
SO_RCVLOWAT int 设置接收低潮标志
SO_RCVTIMEO int 接收超时
SO_SNDLOWAT int 设置发送低潮标志
SO_SNDTIMEO int 发送超时
SO_TYPE int 套接字类型
IP_OPTIONS 设置IP 头中可选域
参见:WSAAsyncSelect(), bind(), getsockopt(), ioctlsocket(), socket(), WSAEventSelect()。
1.2.22 shutdown()
语法:int WSAAPI
shutdown ( IN SOCKET s,
IN int how );
此函数用来切断一个双向连接的接收、发送部分或全部连接。
参数描述:
s,套接字描述符。
how,断路情况,有0,1,2 三种不同情况:如果how 为0(SD_RECEIVE),套接字上后续的接收将被禁止,这对低层的协议没有影响。对TCP套接字来说,由于数据不能递交到用户,如果有数据在套接字上排队等待接收,或有后续数据到达,则连接被重置。对UDP 来说,进来的数据报被接收并排队。这些情况都没有ICMP错误包产生。如果how 为1(SD_SEND),后续的发送被禁止。对TCP 套接字来说,将发送一个FIN。设置how 为2(SD_BOTH)将同时禁止发送和接收。
返回值:如果没有错误发生,shutdown()返回0 。否则它返回值SOCKET_ERROR,错误码可通过调用WSAGetLastError()函数得到。
错误码:
WSANOTINITIALISED:未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN:Windows Sockets 实现检测到网络系统已经失败。
WSAEINVAL:参数how不合法,或与套接字类型不一致(如SD_SEND在UNI_RECV套接字类型上使用)。
WSAEINPROGRESS:一个阻塞的Windows Sockets 操作正在进行。WSAENOTCONN:套接字未连接(只对面向连接的套接字)。
WSAENOTSOCK:此描述符不是套接字描述符。
注释:不管套接字上SO_LINGER是否设置,shutdown()函数都不会阻塞。应用程序不应该在shutdown()一个套接字之后再去使用它。注意shutdown()并不关闭套接字,与套接字相关的资源并没有释放,除非执行一个closesocket()调用。
为了确保在一个连接的套接字上的所有数据在它关闭前能够被发送/接收,应用程序应该采用“雅致”的断连,如使用下面的步骤:
?调用WSAAsyncSelect()函数注册FD_CLOSE 事件通知;
?使用用参数how=SD_SEND 调用shutdown()函数;
?当接收到FD_CLOSE事件时,调用recv()函数直到接收到0 字节,或返回错误码SOCKET_ERROR;
?调用closesocket()函数
参见:connect(), socket()。
1.2.23 socket()
语法:SOCKET WSAAPI
socket ( IN int af,
IN int type,
IN int protocol );
此函数建立一个套接字,它给指定的地址族、数据类型和协议分配一个套接字描述符以及相关的资源。
参数描述:
af,一种地址格式描述。现在支持的格式只有AF_INET,它是ARPA 网际地址格式。type,要建立的套接字的类型描述。
protocol,套接字使用的特定协议,如果调用者不希望指定协议,则置为0,使用默认的连接模式。
返回值:如果没有错误发生,socket()返回一个与建立的套接字相关的描述符。否则它返回值INVALID_SOCKET,错误码可通过调用WSAGetLastError()函数得到。
错误码:
WSANOTINITIALISED:未初始化Windows Sockets DLL,在使用此函数之前必须有一次成功的WSAStartup()函数调用。
WSAENETDOWN:Windows Sockets实现检测到网络系统已经失败。WSAEAFNOSUPPORT:不支持指定的地址族。
WSAEINPROGRESS:一个阻塞的Windows Sockets操作正在进行。
WSAEMFILE:无多余的描述符可用。
WSAENOBUFS:无缓冲区空间可用,套接字不能建立。WSAEPROTONOSUPPORT:不支持指定协议。
WSAEPROTOTYPE:对此套接字来说,指定协议是错误的类型。WSAESOCKTNOSUPPORT:在此地址族中不支持指定套接字类型。
Proe中的部分函数关系 一、函数关系 sin 正弦Cos 余弦tan 正切asin 反正弦acos 反余弦atan 反正切sinh 双曲线余弦cosh 双曲线正弦tanh 双曲线正切spar 平方根exp e的幂方根abs 绝对值log 以10为底的对数ln 自然对数 ceil 不小于其值的最小整数floor 不超过其值的最大整数 二、齿轮公式 alpha=20 m=2 z=30 c=0.25 ha=1 db=m*z*cos(alpha) r=(db/2)/cos(t*50) theta=(180/pi)*tan(t*50)-t*50 z=0 三、蜗杆的公式da=8为蜗杆外径m=0.8 为模数angle=20压力角 L=30长度q直径系数d分度圆直径f齿根圆直径n实数
其中之间的关系 q=da/m-2 d=q*m df=(q-2.4)*m n=ceil(2*l/(pi*m)) 在可变剖面扫描的时候运用公式sd4=trajpar*360*n 在扫描切口的时候绘制此图形,其中红色的高的计算公式是sd5=pi*m/2 五、方向盘的公式sd4=sd6*(1-(sin(trajpar*360*36)+1)/8) 其中sd4是sd6的(3/4或者7/8),sin(trajpar*360*36的意思是转过360度且有36个振幅似的 六、凸轮的公式sd5=evalgraph("cam2",trajpar*360) r=150 theta=t*360 z=9*sin(10*t*360) 在方向按sin(10*t*360)的函数关系,9为高的9倍10为10个振幅似的 七、锥齿轮公式 m=4模数z =50齿轮齿数z-am=40与之啮合的齿轮齿数angle=20压力角b=30齿厚long分度圆锥角 d分度圆直径da齿顶圆直径df齿根圆直径db基圆直径关系:long=atan(z/z-am) d=m*z da=d+2*m*cos(long)
高中常用函数性质及图像 一次函数 (一)函数 1、确定函数定义域的方法: (1)关系式为整式时,函数定义域为全体实数; (2)关系式含有分式时,分式的分母不等于零; (3)关系式含有二次根式时,被开放方数大于等于零; (4)关系式中含有指数为零的式子时,底数不等于零; (5)实际问题中,函数定义域还要和实际情况相符合,使之有意义。 (二)一次函数 1、一次函数的定义 一般地,形如y kx b =+(k ,b 是常数,且0k ≠)的函数,叫做一次函数,其中x 是自变量。当0b =时,一次函数y kx =,又叫做正比例函数。 ⑴一次函数的解析式的形式是y kx b =+,要判断一个函数是否是一次函数,就是判断是否能化成以上形式. ⑵当0b =,0k ≠时,y kx =仍是一次函数. ⑶当0b =,0k =时,它不是一次函数. ⑷正比例函数是一次函数的特例,一次函数包括正比例函数. 2、正比例函数及性质 一般地,形如y=kx(k 是常数,k≠0)的函数叫做正比例函数,其中k 叫做比例系数. 注:正比例函数一般形式 y=kx (k 不为零) ① k 不为零 ② x 指数为1 ③ b 取零 当k>0时,直线y=kx 经过三、一象限,从左向右上升,即随x 的增大y 也增大;当k<0时,?直线y=kx 经过二、四象限,从左向右下降,即随x 增大y 反而减小. (1) 解析式:y=kx (k 是常数,k ≠0) (2) 必过点:(0,0)、(1,k ) (3) 走向:k>0时,图像经过一、三象限;k<0时,?图像经过二、四象限 (4) 增减性:k>0,y 随x 的增大而增大;k<0,y 随x 增大而减小 (5) 倾斜度:|k|越大,越接近y 轴;|k|越小,越接近x 轴 3、一次函数及性质 一般地,形如y=kx +b(k,b 是常数,k≠0),那么y 叫做x 的一次函数.当b=0时,y=kx +b 即y=kx ,所以说正比例函数是一种特殊的一次函数. 注:一次函数一般形式 y=kx+b (k 不为零) ① k 不为零 ②x 指数为1 ③ b 取任意实数 一次函数y=kx+b 的图象是经过(0,b )和(- k b ,0)两点的一条直线,我们称它为直线y=kx+b,它可以看作由直线y=kx 平移|b|个单位长度得到.(当b>0时,向上平移;当b<0时,向下平移)
计算机二级考试MS_Office应用Excel函数 =公式名称(参数1,参数2,。。。。。) =sum(计算范围) =average(计算范围) =sumifs(求和范围,条件范围1,符合条件1,条件范围2,符合条件2,。。。。。。) =vlookup(翻译对象,到哪里翻译,显示哪一种,精确匹配) =rank(对谁排名,在哪个范围里排名) =max(范围) =min(范围) =index(列范围,数字) =match(查询对象,范围,0) =mid(要截取的对象,从第几个开始,截取几个) =int(数字) =weekda y(日期,2) =if(谁符合什么条件,符合条件显示的内容,不符合条件显示的内容) =if(谁符合什么条件,符合条件显示的内容,if(谁符合什么条件,符合条件显示的内容,不符合条件显示的内容)) SUM函数 简单求和。 函数用法 SUM(number1,[number2],…) =SUM(A1:A5)是将单元格 A1 至 A5 中的所有数值相加; =SUM(A1,A3,A5)是将单元格 A1,A3,A5 中的数字相加。 SUMIFS函数 根据多个指定条件对若干单元格求和。 函数用法 SUMIFS(sum_range, criteria_range1, criteria1, [criteria_range2, criteria2], ...) 1) sum_range 是需要求和的实际单元格。包括数字或包含数字的名称、区域或单元格引用。忽略空白值和文本值。 2) criteria_range1为计算关联条件的第一个区域。 3) criteria1为条件1,条件的形式为数字、表达式、单元格引用或者文本,可用来定义将对criteria_range1参数中的哪些单元格求和。例如,条件可以表示为32、“>32”、B4、"苹果"、或"32"。 4)criteria_range2为用于条件2判断的单元格区域。 5) criteria2为条件2,条件的形式为数字、表达式、单元格引用或者文本,可用来定义将对criteria_range2参数中的哪些单元格求和。 4)和5)最多允许127个区域/条件对,即参数总数不超255个。 VLOOKUP函数 是Excel中的一个纵向查找函数,按列查找,最终返回该列所需查询列序所对应的值。
Creo(PROE)中关系式的理解 一)关系式中可以用下列数学函数式表达: 1)、正弦 sin( ) 2)、余弦 cos( ) 3)、正切 tan( ) 4)、反正弦 asin( ) 5)、反余弦 acos( ) 6)、反正切 atan( ) 7)、双曲线正弦 sinh( ) 8)、双曲线余弦 cosh( ) 9)、双曲线正切 tanh( ) 以上九种三角函数式所使用的单位均为“度”。 10)、平方根 sqrt( ) 11)、以10为底的对数 log( ) 12)、自然对数 ln( ) 13)、e的幂 exp( ) 14)、绝对值 abs( ) 15)、不小于其值的最小整数(上限值) ceil( ) 16)、不超过其值的最大整数(下限值) floor( ) 可以给函数ceil和floor加一个可选的自变量,用它指定要圆整的小数位数。 带有圆整参数的这些函数的语法是: ceil(parameter_name或number, number_of_dec_places) floor (parameter_name 或 number, number_of_dec_places) 其中的parameter_name或number意为参数名称或者一个带小数位的精确数值 后面跟随着的number_of_dec_places意为十进位的小数位数,是可选值: A)可以被表示为一个数或一个使用者自定义参数。如果该参数值是一个实数,则被截尾成为一个整数。 B)它的最大值是8。如果超过8,则不会舍入要舍入的数(第一个自变量),并使用其初值。C)如果不指定它,则功能同前期版本一样。 使用不指定小数部分位数的ceil和floor函数,其举例如下: ceil (10.2) 值为11 floor (10.2) 值为 10
在ProE中,我们的关系可以直接很多系统已经预定义好的函数,通过这些函数我们可以来进行一些特定的运算得到所期望的值,下面我们就对一些常用函数进行一个概括和总结,方便大家在使用的时候查阅。 1.数学函数 在proe中,我们可以使用丰富的数学函数,常用的函数列表如下: sin()、cos()、tan()函数 这三个都是数学上的三角函数,分别使用角度的度数值来求得角度对应的正弦、余弦和正切值,比如: A=sin(30) A=0.5? B=0.866?B=cos(30) ?C=tan(30) C=0.577 asin()、acos()、atan()函数 这三个是上面三个三角函数的反函数,通过给定的实数值求得对应的角度值,如:A=asin(0.5) A=30? B=60?B=acos(0.5) C=26.6?C=atan(0.5)
sinh()、cosh()、tanh()函数 在数学中,双曲函数类似于常见的(也叫圆函数的)三角函数。基本双曲函数是双曲正弦“sinh”,双曲余弦“cosh”,从它们导出双曲正切“tanh”等。 sinh / 双曲正弦:sinh(x) = [e^x - e^(-x)] / 2 cosh / 双曲余弦:cosh(x) = [e^x + e^(-x)] / 2 tanh / 双曲正切:tanh(x) = sinh(x) / cosh(x)=[e^x - e^(-x)] / [e^x + e^(-x)] 函数使用实数作为输入值 log()函数 求得10为底的对数值,如: A=log(1) A=0;? A=1;?A=log(10) ?A=log(5) A=0.6989...; ln()函数 求得以自然数e为底的对数值,e是自然数,值是2.718...;如: A=ln(1) A=0;? ?A=ln(5) A=1.609...;
一.正比例函数的性质 1.定义域:R(实数集) 2.值域:R(实数集) 3.奇偶性:奇函数 4.单调性:当k>0时,图像位于第一、三象限,y随x的增大而增大(单调递增);当k<0时,图像位于第二、四象限,y随x的增大而减小(单调递减) 5.周期性:不是周期函数。 6.对称轴:直线,无对称轴。、 二.一次函数图像和性质 一般地,形如y=kx+b(k、b是常数,且k≠0?)的函数,?叫做一次函数(?linear function).一次函数的定义域是一切实数. 当b=0时,y=kx+b即y=kx(k是常数,且k≠0?).所以说正比例函数是一种特殊的一次函数. 当k=0时,y等于一个常数,这个常数用c来表示,一般地,我们把函数y=c(c是常数)叫做常值函数(constant function)它的定义域由所讨论的问题确定. 一般来说, 一次函数y=kx+b(其中k、b是常数,且k≠0)的图像是一条直线. 一次函数y=kx+b的图像也称为直线y=kx+b. 一次函数解析式y=kx+b称为直线的表达式. 一条直线与y轴的交点的纵坐标叫做这条直线在y轴上的截距,简称直线的截距. 一般地,直线y=kx+b(k0)与y轴的交点坐标是(0,b).直线y=kx+b(k0)的截距是b. 一次函数的图像: k>0 b>0 函数经过一、三、二象限 k>0 b<0 函数经过一、二、三象限 k<0 b>0 函数经过一、二、四象限