下面以WinSock 2.0版本为例,介绍Socket的基本数据结构和函数。数据结构给出了套接字结构、协议字段如IP地址结构等的定义。函数给出了用户程序进行网络编程的接口。这些数据结构和函数包含在头文件WinSock 2.h中。
1.Socket主要数据结构
下面以各协议层地址结构为例说明Socket定义的数据结构。这些地址结构有通信域类型、套接字结构、IP地址和主机地址。
1)Socket地址结构。定义通信域和通用的套接字地址。
sockaddr结构是Socket地址结构的较为一般的定义,其中的14字节协议地址sa_data根据地址类型sa_family的不同而不同。BSDSocket支持4种地址类型,在WinSock中依然保留了这个结构,但WinSock只支持Internet协议,因此在下面定义了更有针对性的地址结构sockaddr_in。
2)TCP/IP套接字结构。套接字在TCP/IP中就是IP地址+端口号。在其他协议中可以是网络地址+主机名等。
这个结构更利于网际域的使用,sin_zero用来将sockaddr_in结构填充到与sockaddr结构同样长度,因此,两种结构可相互转化。这里需要注意的是字节顺序,在初始化sockaddr_in结构变量时,要根据结构中每个变量后面的注释的不同字节顺序赋值。
3)IP地址结构。用于存储IP地址信息。注意IP地址的存储是网络字节顺序。
4)主机地址信息。对主机信息的描述,如主机名、别名、IP地址等。
这个结构用于存储本地的IP地址信息。在实际编程中,常调用gethostbyname()函数获取主机名,再根据主机名调用gethostbyname()函数,就获得了本机的IP地址,该函数返回的便是一个hostent结构的指针。
2.Socket主要函数
WinSock提供了一系列API函数,用户程序可以调用这些函数,创建套接字的类型,与对方进行套接字连接,通过套接字发送和接收数据,最后关闭连接。
(1)SOCKET WSAAPI socket(int af,int type,int protocol)
功能:创建一个套接字。
说明:参数af指定通信发生的区域(AF_UNIX、AF_INET、AF_NS、AF_IMPLINK),对WinSock来说,它只支持AF_INET;type指出了要建立的套接字类型(SOCK_STREAM、SOCK_DGRAM、SOCK_RAW);protocol指定该套接字使用的特定协议,如果用户没有特别要求,该项置0,使用默认链接模式。创建成功,函数返回一个16位的socket描述符,它是一个指向内部数据结构的指针,类似文件描述符(句柄)。
(2)int WSAAPI bind(SOCKET s,const struct sockaddr FAR * name,int namelen)
功能:将套接字地址(主机地址和端口号)与所建立的套接字关联起来。
说明:参数s是函数socket()调用返回的套接字描述符;name是要绑定到s上的地址结构,它以sockaddr结构的形式给出,而WinSock中更常用的地址结构是sockaddr_in,因此,在调用bind()实现地址绑定时,要注意两种地址结构的转化;namelen表明了name的长度。
(3)int WSAAPI connect(SOCKET s,conststruct sockaddr FAR * name,int namelen)
功能:用于客户端连接服务器。
说明:该函数用于面向连接的客户端连接服务器,它和服务器端的accept()函数共同完成服务器和客户端的连接(面向连接的TCP方式)。参数s是套接字描述符;name是要连接的服务器地址信息;namelen是name的长度。
(4)int WSAAPI send(SOCKET s,const char FAR * buf,int len,int flags)(www.daowen.com)
功能:用于面向连接的数据发送。
说明:参数s为已连接的套接字描述符;buf指向发送数据缓冲区;len指定待发送数据的长度;flags指定传输控制方式,包括MSG_OOB、MSG_PEEK、MSG_DONTROUTE或是其中几项的组合,一般默认为0。如果函数执行成功,则返回总共发送的字节数,否则返回SOCKET_ERROR。如果send()函数返回值与参数len不相等,则剩余的未发送信息需要再次发送。
(5)int WSAAPI recv(SOCKET s,char FAR * buf,int len,int flags)
功能:用于面向连接的数据接收。
说明:参数s与flags和函数send()相同;buf是指向接收数据缓冲区的指针;len是这个缓冲区的大小。如果函数执行成功,则返回总共接收到的字节数,如果连接被关闭,则返回0,发生错误返回SOCKET_ERROR。
其他一些主要函数还有listen(在服务器端监听客户端的连接)、accept(用于在服务器端接受客户的连接请求)、sendto(用于无连接的UDP数据发送,无需事先建立连接)、re-cvfrom(用于无连接的数据接收)、closesocket(关闭套接字)。
3.辅助函数
在编写socket应用程序的时候,一些辅助函数是必不可少的,例如,获得本机IP地址信息、IP地址格式转换等。下面主要介绍几个常用的辅助函数。
(1)int WSAAPI gethostname(char FAR * name,int name len)
功能:获得主机名。
说明:参数name是一个存放主机名字的字符数组;namelen是这个数组的长度。调用函数返回后,主机名存储在name中,程序中便可以使用它来获得本地IP地址信息。常见用法如下。
函数执行后,主机名便存储在字符数组hostname中。
(2)struct hostent FAR * WSAAPI gethostbyname(const char FAR * name)
功能:域名解析函数,根据主机名获得主机地址信息。
说明:参数name便是主机名,函数执行后返回一个hostent结构的指针,该结构中存储了主机的所有IP地址信息,如果返回NULL,则出现错误。应用实例如下。
在这里需要注意的是,在前面定义的主机地址信息结构hostent中的变量h_addr_list是存放主机IP地址列表的一个数组。其中存放的每个IP地址都是以网络字节序存放的,这一点在编程时要注意。关于网络序与主机序之间的转换,socket提供个4个函数。分别如下。
在实际编写Socket程序时,正确合理地利用上述4个函数是十分重要的。
(3)unsigned long WSAAPI inet_addr(const char FAR * cp)
功能:IP地址格式转换。把点分十进制表示的IP地址字符串转换成32位长整数。
说明:该函数用于把数字和小数点组成的字符串表示的IP地址格式转化为一个长整数。参数cp是需要转化的IP地址字符串,如“192.168.1.100”。返回的值是一个长整数,注意,这个长整数存储IP地址是以网络字节顺序存储的。相反过程的函数是inet_ntoa。
此外,使用WinSock编写程序时必须使用两个函数:WSAStartup()和WSACleanup。WinSock的启动必须通过调用函数WSAStartup()实现,用它来完成WinSock DLL的初始化,协商版本和分配必要的资源。WSACleanup与WSAStartup()函数相对应,用于释放分配的资源。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。