套接字函数介绍
Windows系统提供的套接字函数通常封装在Ws2_32.dll动态链接库中,其头文件Winsock2.h提供了套接字函数的原型,库文件Ws2_32.lib提供了Ws2_32.dll动态链接库的输出节。在使用套接字函数前,用户需要引用Winsock2.h头文件,并链接Ws2_32.lib库文件。例如:
#include "winsock2.h" //引用头文件
#pragma comment (lib,"ws2_32.lib") //链接库文件
此外,在使用套接字函数前还需要初始化套接字,可以使用WSAStartup函数来实现。例如:
WSADATA wsd; //定义WSADATA对象
WSAStartup(MAKEWORD(2,2),&wsd); //初始化套接字
下面介绍网络程序开发中经常使用的套接字函数。
(1)WSAStartup函数
该函数用于初始化Ws2_32.dll动态链接库。在使用套接字函数之前,一定要初始化Ws2_32.dll动态链接库。
语法:
int WSAStartup ( WORD wVersionRequested,LPWSADATA lpWSAData );
参数说明:
wVersionRequested:表示调用者使用的Windows Socket的版本,高字节记录修订版本,低字节记录主版本。例如,如果Windows Socket的版本为2.1,则高字节记录1,低字节记录2。
lpWSAData:是一个WSADATA结构指针,该结构详细记录了Windows套接字的相关信息。
其WSADATA结构指针定义如下:
typedef struct WSAData {
WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
} WSADATA, FAR * LPWSADATA;
结构说明:
wVersion:表示调用者使用的WS2_32.DLL动态库的版本号。
wHighVersion:表示WS2_32.DLL支持的最高版本,通常与wVersion相同。
szDescription:表示套接字的描述信息,通常没有实际意义。
szSystemStatus:表示系统的配置或状态信息,通常没有实际意义。
iMaxSockets:表示最多可以打开多少个套接字。在套接字版本2或以后的版本中,该成员将被忽略。
iMaxUdpDg:表示数据报的最大长度。在套接字版本2或以后的版本中,该成员将被忽略。
lpVendorInfo:表示套接子的厂商信息。在套接字版本2或以后的版本中,该成员将被忽略。
(2)socket函数
该函数用于创建一个套接字。
语法:
SOCKET socket ( int af,int type, int protocol );
参数说明:
af:表示一个地址家族,通常为AF_INET。
tpe:表示套接字类型,如果为SOCK_STREAM,表示创建面向连接的流式套接字,为SOCK_DGRAM,表示创建面向无连接的数据报套接字,为SOCK_RAW,表示创建原始套节字。对于这些值,用户可以在Winsock2.h头文件中找到。
potocol:表示套接口所用的协议,如果用户不指定,可以设置为0。
返回值:函数返回值是创建的套接字句柄。
(3)bind函数
该函数用于将套接字绑定到指定的端口和地址上。
语法:
int bind (SOCKET s,const struct sockaddr FAR* name,int namelen );
参数说明:
s:表示套接字标识。
name:是一个sockaddr结构指针,该结构中包含了要结合的地址和端口号。
namelen:确定name缓冲区的长度。
返回值:如果函数执行成功,返回值为0,否则为SOCKET_ERROR。
(4)listen函数
该函数用于将套接字设置为监听模式。对于流式套接字,必须处于监听模式才能够接收客户端套接字的连接。
语法:
int listen ( SOCKET s, int backlog);
参数说明:
s:表示套接字标识。
backlog:表示等待连接的最大队列长度。例如,如果backlog被设置为2,此时有3个客户端同时发出连接请求,那么前2个客户端连接会放置在等待队列中,第3个客户端会得到错误信息。
(5)accpet函数
该函数用于接受客户端的连接。在流式套接字中,是由在套接字处于监听状态,才能接受客户端的连接。
语法:
SOCKET accept ( SOCKET s, struct sockaddr FAR* addr, int FAR* addrlen );
参数说明:
s:是一个套接字,它应处于监听状态。
addr:是一个sockaddr_in结构指针,包含一组客户端的端口号、IP地址等信息。
addrlen:用于接收参数addr的长度。
返回值:一个新的套接字,它对应于已经接受的客户端连接,对于该客户端的所有后续操作,都应使用这个新的套接字。
(6)losesocket函数
该函数用于关闭套接字。
语法:
int closesocket (SOCKET s);
参数说明:
s:标识一个套接字。如果参数s设置有SO_DONTLINGER选项,则调用该函数后会立即返回,但此时如果有数据尚未传送完毕,会继续传递数据,然后才关闭套接字。
(7)connect函数
该函数用于发送一个连接请求。
语法:
int connect (SOCKET s,const struct sockaddr FAR* name,int namelen );
参数说明:
s:表示一个套接字。
name:表示套接字s想要连接的主机地址和端口号。
namelen:是name缓冲区的长度。
返回值:如果函数执行成功,返回值为0,否则为SOCKET_ERROR。用户可以通过WSAGETLASTERROR得到其错误描述。
(8)htons函数
该函数将一个16位的无符号短整型数据由主机排列方式转换为网络排列方式。
语法:
u_short htons (u_short hostshort );
参数说明:
hostshort:是一个主机排列方式的无符号短整型数据。
返回值:函数返回值是16位的网络排列方式数据。
(9)htonl函数
该函数将一个无符号长整型数据由主机排列方式转换为网络排列方式。
语法:
u_long htonl ( u_long hostlong);
参数说明:
hostlong:表示一个主机排列方式的无符号长整型数据。
返回值:32位的网络排列方式数据。
(10)inet_addr函数
该函数将一个由字符串表示的地址转换为32位的无符号长整型数据。
语法:
unsigned long inet_addr (const char FAR * cp);
参数说明:
cp:表示一个IP地址的字符串。
返回值:32位无符号长整数。
(11)recv函数
该函数用于从面向连接的套接字中接收数据。
语法:
int recv (SOCKET s,char FAR* buf,int len,int flags);
参数说明:
s:表示一个套接字。
buf:表示接受数据的缓冲区。
len:表示buf的长度。
flags:表示函数的调用方式。如果为MSG_PEEK,表示查看传来的数据,在序列前端的数据会被复制一份到返回缓冲区中,但是这个数据不会从序列中移走。为MSG_OOB,表示用来处理Out-Of-Band数据,也就是外带数据。
(12)send函数
该函数用于在面向连接方式的套接字间发送数据。
语法:
int send (SOCKET s,const char FAR * buf, int len,int flags);
参数说明:
s:表示一个套接字。
buf:表示存放要发送数据的缓冲区。
len:表示缓冲区长度。
flags:表示函数的调用方式。
(13)select函数
该函数用来检查一个或多个套接字是否处于可读、可写或错误状态。
语法:
int select (int nfds,fd_set FAR * readfds,fd_set FAR * writefds,fd_set FAR * exceptfds, const struct timeval FAR * timeout);
参数说明:
nfds:无实际意义,只是为了和Unix下的套接字兼容。
readfds:表示一组被检查可读的套接字。
writefds:表示一组被检查可写的套接字。
exceptfds:被检查有错误的套接字。
timeout:表示函数的等待时间。
提示:如果我们在设计网络应用程序时使用Select I/O模型,则需要在循环中调用select函数检测网络状态。
(14)WSACleanup函数
该函数用于释放为Ws2_32.dll动态链接库初始化时分配的资源。
语法:
int WSACleanup (void);
(15)WSAAsyncSelect函数
该函数用于将网络中发生的事件关联到窗口的某个消息中。
语法:
int WSAAsyncSelect (SOCKET s, HWND hWnd,unsigned int wMsg,long lEvent);
参数说明:
s:表示套接字。
hWnd:表示接收消息的窗口句柄。
wMsg:表示窗口接收来自套接字中的消息。
lEvent:表示网络中发生的事件。
(16)ioctlsocket函数
该函数用于设置套接字的I/O模式。
语法:
int ioctlsocket(SOCKET s,long cmd,u_long FAR* argp);
参数说明:
s:表示待更改I/O模式的套接字。
cmd:表示对套接字的操作命令。如果为FIONBIO,当argp为0时,表示禁止非阻塞模式,当argp为非0时,表示设置非阻塞模式。如果为FIONREAD,表示从套接字中可以读取的数据量。为SIOCATMARK,表示是否所有的带外数据都已被读入。这个命令仅适用于流式套接字,并且该套接字已被设置为可以在线接收带外数据(SO_OOBINLINE)。
argp:表示命令参数。