SOCKET函数详解(My整理)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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()。