Winsock是一个标准的网络应用程序编程接口(API),与协议无关的接口(protocol-independent interface),而不是一个协议
Winsock接口大多继承于UNIX平台上的BSD套接字
Winsock 2更新或添加了新的API函数,会在函数名前加上WSA前缀
Winsock Headers and Libraries
1.除了Windows CE只使用Winsock 1外,其他的Windows平台都有Winsock 1 和Winsock 2两个版本
2.当使用WINSOCK2.H 编译程序时,应链上WS2_32.LIB 库;
在Windows CE 平台上开发程序时, 应包括WINSOCK.H,并使用库:WSOCK32.LIB
Initializing Winsock
1. 每个Winsock应用程序必须装载合适的Winsock DLL版本,如果在调用Winsock函数前没有加载Winsock库,则函数会返回SOCKET_ERROR
2. 通过调用WSAStartup函数来完成装载Winsock 库
int WSAStartup (
WORD wVersionRequested,
LPWSADATA lpWSAData
);
WSAStartup函数如果执行成功将返回0,否则将返回一个错误代码
当应用程序结束时,应调用WSACleanup,释放由Winsock分配的资源和取消应用程序将要做的Winsock调用。
int WSACleanup(void);
Error Checking and Handling
1.SOCKET_ERROR常量值为-1.
在应用程序中右击SOCKET_ERROR,选择Go To Definition Of SOCKET_ERROR
可在WINSOCK2.H中找到SOCKET_ERRORR的定义:
#define SOCKET_ERROR (-1)
2.当调用Winsock函数并发生错误时,可以使用WSAGetLastError函数去获得一个已发生错误代码值:
int WSAGetLastError (void);
3. 错误代码常量以WSAE做前缀
如WSAEFAULT,WSAEADDRINUSE
4. 查找错误原因:
方法1:在VC中编写Winsock应用程序时,可在菜单Tools->Error Lookup,在value后输入错误代码常量值,如10014,单击“lookup”按钮即可查询错误原因:“系统检测到在一个调用中尝试使用指针参数时的无效指针地址”。
方法2:打开MSDN,搜索错误代码常量值,如10014,在“Error Code”中也可查询相应错误原因:
WSAEFAULT
(10014)
Bad address.
The system detected an invalid pointer address in attempting to use a pointer argument of a call. This error occurs if an application passes an invalid pointer value, or if the length of the buffer is too small. For instance, if the length of an argument which is a struct sockaddr is smaller than sizeof(struct sockaddr).
Addressing a Protocol
1. 在Winsock中,应用程序通过sockaddr_in结构指定IP地址和端口信息,定义如下:
struct sockaddr_in
{
short sin_family;
u_short sin_port; //端口
struct in_addr sin_addr; //ip地址
char sin_zero[8];//
};
sin_family:协议族,必须为AF_INET,通知Winsock使用ip协议族
sin_addr:用来存储4个字节的IPV4地址,无符号长整型,
inet_addr:将点式ip地址(a.b.c.d)转换为32位无符号长整型(网络字节顺序)
unsigned long inet_addr (
const char FAR * cp
);
2.字节顺序
(1)主机字节顺序 –>网络字节顺序
u_long htonl(u_long hostlong);
int WSAHtonl(
SOCKET s,
u_long hostlong,
u_long FAR * lpnetlong
);
u_short htons(u_short hostshort);
int WSAHtons(
SOCKET s,
u_short hostshort,
u_short FAR * lpnetshort
);
(2)网络字节顺序 ->主机字节顺序
u_long ntohl(u_long netlong);
int WSANtohl(
SOCKET s,
u_long netlong,
u_long FAR * lphostlong
);
u_short ntohs(u_short netshort);
int WSANtohs(
SOCKET s,
u_short netshort,
u_short FAR * lphostshort
);
Creating a Socket
1.在WINSOCK2.H中,套接字有个单独的类型为:SOCKET
2.有两个函数可以创建套接字:socket and WSASocket.
3. SOCKET socket (
int af,
int type,
int protocol
);
af:协议族,如果只使用IPV4协议,则设为AF_INET
type:协议的套接字类型,TCP:SOCK_STREAM UDP:SOCK_DGRAM
protocol:TCP:IPPROTO_TCP,UDP:IPPROTO_UDP
如果没有错误发生,socket将返回一个新的套接字,否则将返回INVALID_SOCKET