Winsock的服务是以动态链接库Winsock DLL实现的,所以使用之前必须先调用下面这个函数对Winsock DLL初始化,协商Winsock的版本支持,并分配必要的资源;
int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);
参数wVersionRequested指定欲加载的Winsock版本:高位字节是副版本,低位字节是主版本;用MAKEWORD(高字节,低字节)来获取wVersionRequested正确值;
应用程序关闭套接字后,还应用调用WSACleanup函数终止对Winsock DLL的使用,并释放资源,以备下一次使用
int WSACleanup (void);
下面这个函数可以用来捕获最近一次操作所产生的错误(各种错误代码都是以WSAE开头)
int WSAGetLastError (void);
服务端行为:
- 调用socket函数创建一个套接字
- 调用bind函数绑定上面的套接字
- 调用listen函数监听客户端的连接请示
- 调用accept函数来接受客户端的请示,并创建一个新的SOCKET套接字进行数据传输,而步骤1的套接字继续监听客户请示
- 调用send和recv函数来与客户端通讯
客户端行为:
- 调用socket函数创建一个套接字
- 调用connect函数请示与服务端的连接
- 调用send和recv与服务端通讯
附——以上各个函数的原型声明:
SOCKET socket(
int af,
int type,
int protocol
);
af——Address family specification,一般取AF_INET
type——Type specification for the new socket,一般取SOCK_STREAM或SOCK_DGRAM
protocol——Protocol to be used with the socket that is specific to the indicated address family,一般取0表示TCP/IP
int bind(
SOCKET s,
const struct sockaddr FAR *name,
int namelen
);
struct sockaddr { u_short sa_family; char sa_data[14]; };
该结构随选择的协议不同而变化,所以一般选择与该结构大小相同的sockaddr_in
struct sockaddr_in{ short sin_family; unsigned short sin_port; struct in_addr sin_addr; char sin_zero[8]; };
sin_family一般取值为AF_INET
sin_port为端口号,若取为0则系统会为之分配1024-5000中的唯一值;同时需要将端口由主机序转换为网络序,使用下面的函数:
u_short htons(
u_short hostshort
);
sin_addr用于将一个IP地址保存为一个4字节的数,它是unsiged long类型
struct in_addr { union { struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b; struct { u_short s_w1,s_w2; } S_un_w; u_long S_addr; } S_un; };
sin_zero只充当填充项的职责,以使sockaddr_in结构与sockaddr结构长度一样;函数inet_addr可将一个点式IP地址转换成一个
32位的无符号长整型。若取值为INADDR_ANY则可以监听任意客户的连接请示
unsigned long inet_addr(
const char FAR *cp
);
int listen(
SOCKET s,
int backlog
);
backlog指能受理的客户请示数的最大值
SOCKET accept(
SOCKET s,
struct sockaddr FAR *addr,
int FAR *addrlen
);
sockaddr结构用来存放客户端的相关信息
int connect(
SOCKET s,
const struct sockaddr FAR *name,
int namelen
);
int recv(
SOCKET s,
char FAR *buf,
int len,
int flags
);
int send(
SOCKET s,
const char FAR *buf,
int len,
int flags
);
int sendto(
SOCKET s,
const char FAR *buf,
int len,
int flags,
const struct sockaddr FAR *to,
int tolen
);
int recvfrom(
SOCKET s,
char FAR* buf,
int len,
int flags,
struct sockaddr FAR *from,
int FAR *fromlen
);