Winsock函数参考手册
本系统(WinKing)提供之 Windows Sockets API 介面乃是依照 1993年1月20日
公布之 WINSOCK 第1.1版(如附录)中所定义之函式 (routine); 包括了30个
Berkeley Software Distribution (BSD) 的函式以及16个符合 Windows
Message-driven 特性的函式。
BSD 函式包括:
accept() bind() closesocket() connect()
getpeername() getsockname() getsockopt() htonl()
htons() inet_addr() inet_ntoa() ioctlsocket()
listen() ntohl() ntohs() recv()
recvfrom() select() send() sendto()
setsockopt() shutdown() socket() gethostname()
gethostbyaddr() gethostbyname()
getprotobyname() getprotobynumber()
getservbyname() getservbyport()
Microsoft Windows-specific Extensions 函式包括:
WSAAsyncGetHostByAddr() WSAAsyncGetHostByName()
WSAAsyncGetProtoByName() WSAAsyncGetProtoByNumber()
WSAAsyncGetServByName() WSAAsyncGetServByPort()
WSAAsyncSelect() WSACancelAsyncRequest()
WSACancelBlockingCall() WSACleanup()
WSAGetLastError() WSAIsBlocking()
WSASetBlockingHook() WSASetLastError()
WSAStartup() WSAUnhookBlockingHook()
这些 API 介面适用於 Internet Protocol Suite (IPS,通常称之为 TCP/IP),
支援 Stream (TCP) 及 Datagram (UDP) Socket。
Stream (TCP) Socket 提供「双向」、「可靠」、「有次序」、「不重覆」
之资料传送。
Datagram (UDP) Socket 则提供「双向」之沟通,但没有「可靠」、「有次
序」、「不重覆」等之保证; 所以使用者可能会收到无次序、重覆之资料,
甚至资料在传输过程中也可能会遗漏。
[Blocking 与 Non-blocking 模式]
Blocking 模式:使用者呼叫此一模式之函式时,会进入此函式之内部,直到
条件或资料完全符合时再回到呼叫点。
Non-blocking 模式:使用者呼叫此一模式之函式时,进入此函式之内部,
依当时之条件或资料做适当之回覆,并不会停留在函式之内部到条件或资料
完全符合後才回应。
使用者必需注意的是,WINSOCK 定义之 Blocking 模式与一般 Unix 的不太相
同。WINSOCK定义允许应用程式在呼叫 Blocking 函式的同时,依旧能够处理其
它讯息 (Messages),包括Keyboard 及 Mouse 的事件;但是此时应用程式除了
能用 WSACancelBlockingCall() 函式来取消原先之 locking 动作或用
WSAIsBlocking() 函式来检查目前是否有 Blocking 动作仍在进行外,
「不可以」在原先呼叫之 Blocking 函式完成前再呼叫其它的 Socket 函式,
不然後者会失败且产生WSAINPROGRESS 的错误。
使用者呼叫 WSACancelBlockingCall()函式所取消的 Blocking 动作若不是
accept() 或者 select()的话,那麽之後唯一可呼叫的 Socket 函式只有
closesocket(),因为取消一个 Socket 的Blocking 动作会使其变成未定
(Indeterminate) 状态。
[Async (非同步) 模式]
使用者呼叫此一模式的函式时,并不会马上得到要求的资料;而是当要求的
动作完成後,系统再透过另一种方式来通知呼叫者。其好处是使用者不需等
到答覆後才可以再做其它的动作或要求。
WINSOCK定义的 Async 模式是以「PostMessage」的方式告知使用者其要求
已经完成;所以在呼叫此类函式时,必须告知 Windows Sockets DLL一些资
讯,包括接受讯息的视窗 handle及讯息编号等。
[函式概说]
[BSD Socket 程式库]
(1) accept():接受某一Socket的连接要求,以完成 Stream Socket 的连接。
格 式: SOCKET PASCAL FAR accept( SCOKET s,
struct sockaddr FAR *addr,
int FAR *addrlen );
参 数: s Socket的识别码
addr 存放来连接的彼端的位址
addrlen addr的长度
传回值: 成功 - 新的Socket识别码
失败 - INVALID_SOCKET (呼叫 WSAGetLastError() 可得知原因)
说明: Server 端之应用程式呼叫此一函式来接受 Client 端要求之
Socket 连接动作;如果Server 端之 Socket 是为 Blocking 模式,且没有人
要求连接动作,那麽此一函式会Block 函式马上回覆错误。accept() 函式的答
覆值为一新的 Socket,此 Socket 不可再用来接受其它的连接要求;但是原
先之 Socket 仍可接受其他人的连接要求。
(2) bind():指定 Socket 的 Local 位址 (Address)。
格 式: int PASCAL FAR bind( SOCKET s,
const struct sockaddr FAR *name,
int namelen );
参 数: s Socket的识别码
name Socket的位址值,其格式为
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
namelen name的长度
传回值: 成功 - 0
失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明: 此一函式是指定 Local 位址及 Port 给某一未定名之 Socket。
使用者若不在意位址或 Port 的值,那麽他可以设定位址为 INADDR_ANY,及
Port 为 0;那麽Windows Sockets 会自动将其设定适当之位址及 Port
(1024 到 5000之间的值),使用者可以在此 Socket 真正连接完成後,呼
叫 getsockname() 来获知其被设定的值。
(3) closesocket():关闭某一Socket。
格 式: int PASCAL FAR closesocket( SOCKET s );
参 数: s Socket 的识别码
传回值: 成功 - 0
失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明: 此一函式是用来关闭某一 Socket。
若是使用者原先对要关闭之 Socket 设定 SO_DONTLINGER,则在呼叫
此一函式後,会马上回覆,但是此一 Sokcet 尚未传送完毕的资料会继
续送完後才关闭。
若是使用者原先设定此 Socket 为 SO_LINGER,则有两种情况:
(a) Timeout 设为 0 的话,此一 Socket 马上重新设定 (reset),未传完或
未收到的资料全部遗失。
(b) Timeout 不为 0 的话,则会将资料送完,或是等到 Timeout 发生後才
关闭。
(4) connect():要求连接某一Socket到指定的对方。
格 式: int PASCAL FAR connect( SOCKET s,
const struct sockaddr
FAR *name,
int namelen );
参 数: s Socket 的识别码
name 此 Socket 想要连接的对方位址
namelen name的长度
传回值: 成功 - 0
失败 - SOCKET_ERROR (呼叫WSAGetLastError()可得知原因)
说明: 此函式用来向对方要求建立连接。若是指定的对方位址为 0 的话,
会传回错误值。当连接建立完成後,使用者即可利用此一 Socket 来做传送或
接收资料之用了。
(5) getpeername():获取已连接成功之 Socket 的对方位址。
格 式: int PASCAL FAR getpeername( SOCKET s,
struct sockaddr FAR *name,
int FAR *namelen );
参 数: s Socket 的识别码
name 此 Socket 连接的对方位址
namelen name 的长度
传回值: 成功 - 0
失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明: 此函式可用来取得已连接成功的 Socket 的彼端之位址资料。
(6) getsockname():获取 Socket 的 Local 位址资料。
格式: int PASCAL FAR getsockname( SOCKET s,
struct sockaddr FAR *name,
int FAR *namelen );
参 数: s Socket 的识别码
name 此 Socket 的 Local 位址
namelen name 的长度
传回值: 成功 - 0
失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明: 此函式是用来取得已设定位址或已连接之 Socket 的本端位址资料。
若是此 Socket 被设定为 INADDR_ANY,则需等真正建立连接成功後才会传回
正确的位址。
(7) getsockopt():要求某一 Socket 目前状态设定的资料。
格式: int PASCAL FAR getsockopt( SOCKET s,
int level,
int optname,
char FAR *optval,
int FAR *optlen );
参 数: s Socket 的识别码
level 选项设定的 level
optname 选项名称
optval 选项的设定值
optlen 选项设定值的长度
传回值: 成功 - 0
失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明: 此函式用来获取目前 Socket的某些状态设定值。
WINSOCK 提供之 level 只有 SOL_SOCKET 及 IPPROTO_TCP optname
则有以下 之选择:(参见WINSOCK 第 29、30 页之定义)
Value Type
-----------------------------------------------
SO_ACCEPTCONN BOOL
SO_BROADCAST BOOL
*SO_DEBUG BOOL
SO_DONTLINGER BOOL
*SO_DONTROUTE BOOL
*SO_ERROR int
*SO_KEEPALIVE BOOL
SO_LINGER struct linger FAR*
SO_OOBINLINE BOOL
*SO_RCVBUF int
SO_REUSEADDR BOOL
*SO_SNDBUF int
SO_TYPE int
TCP_NODELAY BOOL
(* 表暂不提供此功能选项)
(8) htonl():将一 32 位元 u_long 的值由 host 的排列方式转换成
network 的排列方式。
格 式: u_long PASCAL FAR htonl( u_long hostlong );
参 数: hostlong 一个 32 位元 host 排列方式的数目
传回值: 一个 32 位元 network 排列方式的数目
说明: 因为 network 的排列方式与 host 的排列方式可能不同,
所以我们需要此一函式来做转换。
(9) htons():将一 16 位元u_short 的值由 host 的排列方式转换成
network 的排列方式。
格 式: u_short PASCAL FAR htons( u_short hostshort );
参 数: hostshort 一个 16 位元 host 排列方式的数目
传回值: 一个 16 位元 network 排列方式的数目
说明: 因为 network 的排列方式与 host 的排列方式可能不同,
所以我们需要此一函式来做转换。
(10) inet_addr():将字串格式的位址转换成 32 位元 unsigned long 的格式。
格 式: unsigned long PASCAL FAR inet_addr( const char FAR *cp );
参 数: cp 一个代表位址的「点格式」(dotted) 字串
传回值: 成功 - 一个代表 Internet 位址的 unsigned long
失败 - INADDR_NONE
说明: 此函式将一「点格式」的位址字串转换成适用之Intenet位址。
「点格式」字串可为以下四种方式之任一:
(i) a.b.c.d (ii) a.b.c (iii) a.b (iv) a
(11) inet_ntoa():将一网路位址转换成「点格式」字串。
格 式: char FAR * PASCAL FAR inet_ntoa( struct in_addr in );
参 数: in 一个代表 Internet 位址的结构
传回值: 成功 - 一个代表位址的「点格式」(dotted) 字串
失败 - NULL
说明: 此函式将一 Internet 位址转换成「a.b.c.d」字串格式。
(12) ioctlsocket():控制 Socket 的模式。
格 式: int PASCAL FAR ioctlsocket( SOCKET s,
long cmd,
u_long FAR *argP );
参 数: s Socket 的识别码
cmd 指令名称
argP 指向 cmd 参数的指标
传回值: 成功 - 0
失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明: 此函式用来获取或设定 Socket 的运作参数。其所提供的指令有:
(参见 WINSOCK 第 1.1 版 35、36 页)
FIONBIO -- 开关 non-blocking 模式
FIONREAD -- 自 Socket 一次可读取的资料量
SIOCATMARK -- OOB 资料是否已被读取完 (*暂不提供此功能)
(13) listen():设定 Socket 为监听状态,准备被连接。
格 式: int PASCAL FAR listen( SOCKET s, int backlog );
参 数: s Socket 的识别码
backlog 未真正完成连接前(尚未呼叫 accept() 前)
彼端的连接要求的最大个数
传回值: 成功 - 0
失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明: 使用者可利用此函式来设定 Socket 进入监听状态,并设定最多
可有多少个在未真正完成连接前的彼端的连接要求。(目前最大值限制为 5, 最
小值为1)
(14) ntohl():将一 32 位元 u_long 的值由 network 排列方式转换成
host 排列方式。
格 式: u_long PASCAL FAR ntohl( u_long netlong );
参 数: netlong 一个 32 位元 network 排列方式的数目
传回值: 一个 32 位元 host 排列方式的数目
说明: 因为 network 的排列方式与 host 的排列方式可能不同,
所以我们需要此一函式来做转换。
(15) ntohs():将一 16 位元 u_short 的值由 network 排列方式转换成
host 排列方式。
格 式: u_short PASCAL FAR ntohs( u_short netshort );
参 数: netshort 一个 16 位元 network 排列方式的数目
传回值: 一个 16 位元 host 排列方式的数目
说明: 因为 network 的排列方式与 host 的排列方式可能不同,
所以我们需要此一函式来做转换。
(16) recv():自 Socket 接收资料。
格 式: int PASCAL FAR recv( SOCKET s,
char FAR *buf,
int len,
int flags );
参 数: s Socket 的识别码
buf 存放接收到的资料的暂存区
len buf 的长度
flags 此函式被呼叫的方式
传回值: 成功 - 接收到的资料长度 (若对方 Socket 已关闭,则为 0)
失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明: 此函式用来自连接式的 Datagram Socket 或 Stream Socket
接收资料。对 Stream Socket 言,我们可以接收到目前有效的 (available)
资料,但其数量不超过 len 的大小。若是此 Socket 设定 SO_OOBINLINE,
且有 out-of-band 的资料未被读取,那麽只有 out-of-band 的资料被取出。
对 Datagram Socket 言,只取出第一个 datagram;若是该 datagram 大於使
用者提供的储存空间,那麽只有该空间大小的资料被取出,多馀的资料
将遗失,且回覆错误的讯息。 flags 的值可为 MSG_PEEK、MSG_OOB
(*暂不提供此功能)的组合。(参考 WINSOCK 第1.1版41 页)
(17) recvfrom():读取一个 Datagram,并储存资料来源的位址。
格 式: int PASCAL FAR recvfrom( SOCKET s,
char FAR *buf,
int len,
int flags,
struct socketaddr FAR *from,
int FAR *fromlen );
参 数: s Socket 的识别码
buf 存放接收到的资料的暂存区
len buf 的长度
flags 此函式被呼叫的方式
from 资料来源的位址
fromlen from 的大小
传回值: 成功 - 接收到的资料长度 (若对方 Socket 已关闭,则为 0)
失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明: 此函式用来读取资料并记录资料来源的位址。
对 Stream Socket 言,其作用与 recv() 相同,参数 from 及 fromlen 将不
被用到。
(18) select():检查一或多个 Sockets 是否处於可读、可写或错误的状态。
格 式: int PASCAL FAR select( int nfds,
fd_set FAR *readfds,
fd_set FAR *writefds,
fd_set FAR *exceptfds,
const struct timeval FAR *timeout );
参 数: nfds 此参数在此并无作用
readfds 要被检查是否可读的 Sockets
writefds 要被检查是否可写的 Sockets
exceptfds 要被检查是否有错误的 Sockets (*暂无作用)
timeout 此函式该等待的时间。若为 NULL 时,
表示 blocking,此函式会等到有事件发生。
传回值: 成功 - 符合条件的 Sockets 总数 (若 Timeout 发生,则为 0)
失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明: 使用者可利用此函式来检查 Sockets 是否有资料可被读取,
或是有空间可以写入,或是有错误发生。
(19) send():使用连接式的 Socket 传送资料。
格 式: int PASCAL FAR send( SOCKET s,
const char FAR *buf,
int len,
int flags );
参 数: s Socket 的识别码
buf 存放要传送的资料的暂存区
len buf 的长度
flags 此函式被呼叫的方式
传回值: 成功 - 送出的资料长度
失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明: 此函式适用於连接式的 Datagram 或 Stream Socket 来传送资料。
对 Datagram Socket 言,若是 datagram 的大小超过限制,则将不会送出
任何资料,并会传回错误值。若是传送 (transport) 系统内之储存空间不
够存放这些要传送的资料,send() 将会被 block 住,除非该 Socket 被设
定为 non-blocking 模式。使用者亦须注意 send()函式执行完成,并不表
示资料已经成功地送抵对方了。 flags 的值可设为 MSG_DONTROUTE
(*暂不提供此功能)及 MSG_OOB 的组合。(参见 WINSOCK第1.1版48页)
(20) sendto():将资料送到指定的目的地。
格 式: int PASCAL FAR sendto( SOCKET s,
const char FAR *buf,
int len,
int flags,
const struct sockaddr FAR *to,
int tolen );
参 数: s Socket 的识别码
buf 存放要传送的资料的暂存区
len buf 的长度
flags 此函式被呼叫的方式
to 资料要送达的位址
tolen to 的大小
传回值: 成功 - 送出的资料长度
失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明: 此函式适用於 Datagram 或 Stream Socket 来传送资料到指定的位址。
对 Datagram Socket 言,若是 datagram 的大小超过限制,则将不会送出
任何资料,并会传回错误值。对 Stream Socket 言,其作用与 send() 相
同;参数 to 及 tolen 在此并无作用。 若是传送 (transport) 系统内之储
存空间不够存放这些要传送的资料,sendto() 将会被 block 住,除非该
Socket 被设定为 non-blocking 模式。使用者亦须注意 sendto() 函式执行
完成,并不表示资料已经成功地送抵对方了。 flags 的值可设为 MSG_DONTROUTE
(*暂不提供此功能)及 MSG_OOB 的组合。(参见 WINSOCK第1.1版51页)
(21) setsockopt():设定 Socket 的状态。
格 式: int PASCAL FAR setsockopt( SOCKET s,
int level,
int optname,
const char FAR *optval,
int optlen );
参 数: s Socket 的识别码
level 选项设定的 level
optname 选项名称
optval 选项的设定值
optlen 选项设定值的长度
传回值: 成功 - 0
失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明: 此函式用来设定 Socket 的一些选项,藉以更改其动作。
可更改的选项有: (参见WINSOCK第1.1版54页)
Value Type
-----------------------------------------------
SO_BROADCAST BOOL
*SO_DEBUG BOOL
SO_DONTLINGER BOOL
*SO_DONTROUTE BOOL
*SO_KEEPALIVE BOOL
SO_LINGER struct linger FAR*
SO_OOBINLINE BOOL
*SO_RCVBUF int
SO_REUSEADDR BOOL
*SO_SNDBUF int
TCP_NODELAY BOOL
(* 表暂不提供此功能选项)
(22) shutdown():停止 Socket 接收/传送的功能。
格 式: int PASCAL FAR shutdown( SOCKET s, int how );
参 数: s Socket 的识别码
how 代表该停止那些动作的标帜
传回值: 成功 - 0
失败 - SOCKET_ERROR (呼叫 WSAGetLastError()可得知原因)
说明: 此函式用来停止 Socket 的後续接收或传送的功能。
若 how 的值为 0,则不再接收资料。
若 how 的值为 1,则不再允许传送资料。
若 how 的值为 2,则不再接收且不再传送资料。
shutdown() 函式并没有将 Socket 关闭,所以该 Socket 所占用之资源必
须在呼叫closesocket() 之後才会释放。
(23) socket():建立Socket。
格 式: SOCKET PASCAL FAR socket( int af,
int type,
int protocol );
参 数: af 目前只提供 PF_INET(AF_INET)
type Socket 的型态 (SOCK_STREAM、SOCK_DGRAM)
protocol 通讯协定(如果使用者不指定则设为0)
传回值: 成功 - Socket 的识别码
失败 - INVALID_SOCKET(呼叫 WSAGetLastError() 可得知原因)
说明: 此函式用来建立一 Socket,并为此 Socket 建立其所使用的资源。
Socket 的型态可为 Stream Socket 或 Datagram Socket。
(24) gethostbyaddr():利用某一 host 的位址来获取该 host 的资料。
格 式: struct hostent FAR * PASCAL FAR
gethostbyaddr( const char FAR *addr, int len, int type );
参 数: addr network 排列方式的位址
len addr 的长度
type PF_INET(AF_INET)
传回值: 成功 - 指向 struct hostent 的指标
struct hostent {
char FAR * h_name;
char FAR * FAR * h_aliases;
short h_addrtype;
short h_length;
char FAR * FAR * h_addr_list;
}
失败 - NULL (呼叫 WSAGetLastError() 可得知原因)
说明: 此函式是利用位址来获取 host的其他资料,如 host 的名称、
别名,位址的型态、长度等。
(25) gethostbyname():利用某一 host 的名称来获取该 host 的资料。
格 式: struct hostent FAR * PASCAL FAR
gethostbyname( const char FAR *name );
参 数: name host 的名称
传回值: 成功 - 指向 struct hostent 的指标
struct hostent {
char FAR * h_name;
char FAR * FAR * h_aliases;
short h_addrtype;
short h_length;
char FAR * FAR * h_addr_list;
}
失败 - NULL (呼叫 WSAGetLastError() 可得知原因)
说明: 此函式是利用 host 名称来获取其他的资料,如 host 的位址、
别名,位址的型态、长度等。
(26) gethostname():获取目前使用者使用的 host 的名称。
格 式: int PASCAL FAR gethostname( char FAR *name, int namelen );
参 数: name 用来存放 host 名称的暂存区
namelen name 的大小
传回值: 成功 - 0
失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明: 此函式用来获取 host 的名称。
(27) getprotobyname():依照通讯协定 (protocol) 的名称来获取该通讯协定
的其他资料。
格 式: struct protoent FAR * PASCAL FAR
getprotobyname( const char FAR *name );
参 数: name 通讯协定名称
传回值: 成功 - 一指向 struct protoent 的指标
struct protoent {
char FAR * p_name;
char FAR * FAR * p_aliases;
short p_proto;
}
失败 - NULL (呼叫 WSAGetLastError() 可得知原因)
说明: 利用通讯协定的名称来得知该通讯协定的别名、编号等资料。
(28) getprotobynumber():依照通讯协定的编号来获取该通讯协定的其他资料。
格 式: struct protoent FAR * PASCAL FAR
getprotobynumber( int number );
参 数: number 以 host 排列方式的通讯协定编号
传回值: 成功 - 一指向 struct protoent 的指标
struct protoent {
char FAR * p_name;
char FAR * FAR * p_aliases;
short p_proto;
}
失败 - NULL (呼叫 WSAGetLastError() 可得知原因)
说明: 利用通讯协定的编号来得知该通讯协定的名称、别名等资料。
(29) getservbyname():依照服务 (service) 名称及通讯协定来获取该服务
的其他资料。
格 式: struct servent * PASCAL FAR
getservbyname( const char FAR *name,
const char FAR *proto );
参 数: name 服务名称
proto 通讯协定名称
传回值: 成功 - 一指向 struct servent 的指标
struct servent {
char FAR * s_name;
char FAR * FAR * s_aliases;
short s_port;
char FAR * s_proto;
}
失败 - NULL (呼叫 WSAGetLastError() 可得知原因)
说明: 利用服务名称及通讯协定来获得该服务的别名、使用的port编号等。
(30) getservbyport():依照服务 (service) 的 port 编号及通讯协定来获取
该服务的其他资料。
格 式: struct servent * PASCAL FAR
getservbyport( int port, const char FAR *proto );
参 数: port 服务的 port 编号
proto 通讯协定名称
传回值: 成功 - 一指向 struct servent 的指标
struct servent {
char FAR * s_name;
char FAR * FAR * s_aliases;
short s_port;
char FAR * s_proto;
}
失败 - NULL (呼叫 WSAGetLastError() 可得知原因)
说明: 利用 port 编号及通讯协定来获得该服务的名称、别名等。