套接字通常与占互联网主导地位的 TCP/IP 协议一起使用,但并不局限于此。TCP/IP 协议的组成部分之一,IP 协议(网际协议),把数据封装成一个个数据报(Datagram),数据的来源和目的地信息都存放在数据报的报头中。而 TCP(传输控制协议)则提供了一种可以对 IP 数据报进行可靠传输和错误检测的方法。
在 TCP/IP 协议中,通信端点由 IP 地址和端口号来定义。IP 地址包含 4 个字节,用来确定互联网上的任一台服务器。IP 地址通常显示为“由点分隔的四个十进制数字”,例如“209.86.105.231”。端口号被用来确定服务器提供的特定服务或程序。其中的一些端口号已经有标准化的定义,用于提供一些广为人知的服务。
当一个套接字和 TCP/IP 一起使用时,套接字就是 TCP/IP 通信的端点。因此,套接字指定了一个 IP 地址和一个端口号。
WSADATA,一种分子结构。这个结构被用来存储被WSAStartup函数调用后返回的Windows Sockets数据。它包含Winsock.dll执行的数据。
WSAData
结构原型
typedef struct WSAData {
WORD wVersion;
WORD wHighVersion;
#ifdef _WIN64
unsigned short iMaxSockets;
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
#else
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets;
#endif
} WSADATA;
WSADATA结构被用来保存AfxSocketInit函数返回的WindowsSockets初始化信息。
wVersion
Windows Sockets DLL期望调用者使用的Windows Sockets规范的版本。wHighVersion
这个DLL能够支持的Windows Sockets规范的最高版本。通常它与wVersion相同。
szDescription
以null结尾的ASCII字符串,Windows SocketsDLL将对Windows Sockets实现的描述拷贝到这个字符串中,包括制造商标识。
szSystemStatus
以null结尾的ASCII字符串,Windows SocketsDLL把有关的状态或配置信息拷贝到该字符串中。Windows Sockets DLL应当仅在这些信息对用户或支持人员有用时才使用它们,它不应被作为szDescription域的扩展。
iMaxSockets
单个进程能够打开的socket的最大数目。Windows Sockets的实现能提供一个全局的socket池,可以为任何进程分配;或者它也可以为socket分配属于进程的资源。这个数字能够很好地反映Windows Sockets DLL或网络软件的配置方式。应用程序的编写者可以通过这个数字来粗略地指明Windows Sockets的实现方式对应用程序是否有用。
sockaddr_in结构在WinSock2.h中定义:
struct sockaddr_in {
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
参数说明:sin_family是指定的地址族,如设定为AF_INET
Sin_port是用于设定端口号,不能直接设置为数字,常用htons函数转换
Sin_addr设置所用的IP地址,使用inet_addr函数如:inet_addr("127.0.0.1")
Size_zero[8]没有实际意义,只是为了 跟SOCKADDR结构在内存中对齐
函数原型:
int socket(int domain, int type, int protocol);
函数功能:用于创建一个socket描述符来唯一标识这个socket
参数说明:
domain:协议域,又称协议族(family)。常用的协议族有AF_INET、AF_INET6、AF_LOCAL、AF_ROUTE等。协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合,AF_INET最为常用。
type:指定Socket类型。常用的socket类型有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等。SOCK_STREAM是一种面向连接的Socket,针对于面向连接的TCP服务应用。数据报式SOCK_DGRAM是一种无连接的Socket,对应于无连接的UDP服务应用。
protocol:指定协议。常用协议有IPPROTO_TCP、IPPROTO_UDP、IPPROTO_STCP、IPPROTO_TIPC等,分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
注意:SOCK_STREAM不可以跟IPPROTO_UDP组合。当第三个参数为0时,会自动选择第二个参数类型对应的默认协议。
WSAStartup函数
WSAStartup(),本函数必须是应用程序或DLL调用的第一个Windows Sockets函数.它允许应用程序或DLL指明Windows Sockets API的版本号及获得特定Windows Sockets实现的细节.应用程序或DLL只能在一次成功的WSAStartup()调用之后才能调用进一步的Windows Sockets API函数.
函数原型:intPASCAL FAR WSAStartup ( WORD wVersionRequested, LPWSADATAlpWSAData );
参数说明:wVersionRequestedWindows Sockets API提供的调用方可使用的最高版本号.高位字节指出副版本(修正)号,低位字节指明主版本号.
lpWSAData 指向WSADATA数据结构的指针,用来接收Windows Sockets实现的细节。
WSACleanup函数
函数原型
int PASCAL FAR WSACleanup (void);
函数功能:是终止Winsock 2 DLL (Ws2_32.dll)的使用.
返回值:操作成功返回值为0;否则返回值为SOCKET_ERROR,可以通过调用WSAGetLastError获取错误代码。
在一个多线程的环境下,WSACleanup()中止了Windows Sockets在所有线程上的操作。
Bind函数
功能:socket函数并没有为套接字绑定本地地址和端口号,对于服务器端则必须显性绑定地址和端口号。bind函数主要是服务器端使用,把一个本地协议地址赋予套接字。
函数原型:
int bind(int sockfd, const struct sockaddr*myaddr, socklen_t addrlen);
参数说明:sockfd是由socket函数返回的套接口描述字,第二个参数是一个指向特定于协议的地址结构的指针,第三个参数是该地址结构的长度;
例;bind(sListen, (struct sockaddr *) &local, sizeof(SOCKADDR_IN));(struct sockaddr *)是强制类型转换;
Listen函数
函数原型:int listen(int sockfd, int backlog);
功能:监听由socket函数创建的socket描述字
sockfd:要监听的socket描述字
backlog:该socket可以排队的最大连接个数,socket()函数创建的socket默认是一个主动类型的,listen函数将socket变为被动类型的,等待客户的连接请求。
Accept函数
函数原型:int accept(int sockfd, struct sockaddr*addr, socklen_t *addrlen);
功能:接收客户端请求,生成一个socket描述符用于数据通信,俗称连接socket描述符sockfd:socket描述字,由socket()函数创建,唯一标识该socket。俗称监听socket描述符。
sockfd:套接字描述符,该套接口在listen()后监听连接。
addr:指向struct sockaddr *的指针,用于返回客户端的协议地址
addrlen:客户端协议地址的长度
返回值:
如果没有错误产生,则accept()返回一个描述所接受包的SOCKET类型的值。
Connect函数
函数原型:int connect(int sockfd, const structsockaddr *addr, socklen_t addrlen);
功能:客户端通过调用connect函数来建立与服务器的连接。
sockfd:客户端的socket描述字
addr:服务器的socket地址,用法同bind()中的addr
addrlen:socket地址的长度。
返回值:若无错误发生,则connect()返回0。否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。
Closeocket函数
函数功能:本函数关闭一个套接口。
函数原型:int PASCAL FAR closesocket( SOCKET s);
返回值:如无错误发生,则closesocket()返回0。否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。