Winsock的编程
在网络通讯中由于网络拥挤或者一次发送的数据过大等原因,经常会发生交换的数据在短时间内不能传送完,
收发的数据不能返回的现象,这种现象我们叫做阻塞。
Winsock对有可能阻塞的函数提供了二种处理方式————阻塞和非阻塞方式
阻塞方式:收发数据的函数在被调用后一直要到传送完毕或者出错才能返回,在阻塞期间,除了等待网络操
作的完成不能进行任何操作。
非阻塞方式:函数被调用后立即返回,当网络操作传送完成后,由winsock给应用程序发送一个消息,通知操
作完成,此时可根据发送的消息传出的参数判断操作是否正常
注意:
在编程的时候,应该尽量使用非阻塞方式
(1)int PASCALFAR WSAStartUp(WORD wVersionRequest,LPWSADATA lpWSAData) 初始化函数
//parm1:将要使用的Windows sockets Api版本,word高位字节定义的是此版本号,低位是主版本号
//parm2:指向WSADATA资料的指针
//return:成功返回0,失败返回可能值:WSASYSNOTREADY->网络没有准备好,WSAVERBOTSUPPORTED->WInsock
//的版本信息号不支持,WSAEINPROGRESS->一个阻塞式的winsock1.1存在进程中,WSAEPROCLIM->已经达到winsock
//使用量的上限,WSAEFAULT->lpWSAData不是一个有效的指针。
(2)SOCKET socket(int af,int Type,int proctocol) 创建一个SOCKET
//parm1:指address family地址族,一般为AF_INET表示Internet上的Socket
//parm2:是socket的类型,一般有TCP的流链接方式SOCK_STREAM和UDP的数据报文方式SOCK_DGRAM
//parm3:表示对二种类型的socket分别采用缺省的TCP和UDP传输协议,一般为0
//return:返回windows分配给程序的SOCKET编号,失败返回INVALID_SOCKET
(3)int bind(SOCKET s,strut sockaddr_in* name,int namelen)(服务端)创建的socket指定通讯对象
//通过Ip和端口号确定具体的通讯对象,端口号为0-65536,在Internet上1024以下的端口号被常用的FTP,Telnet
//等占用,所以我们要填写大于1024以上的端口号.TCP和UDP的端口号是独立的,使用相同的端口号没有干扰
(4)int Listen(SOCKET s,int backlog)(服务端)设置等待链接状态
//parm2:等待链接的队列长度,可取1-5,超过这个长度的链接请求将被拒绝
(5)SOCKET accept(SOCKET s,stuct sockaddr_in *addr,int *addrlen) (服务端)接受链接请求
//阻塞方式下:当没有链接请求时,就进入等待状态,知道有一个请求到达为止。accept接收到链接请求后,会为
//这个链接建立一个新的Socket来与对方通讯,并把它作为返回值。新建的socket与原来的socket有相同的特性,包
//括端口号,原来的Socket将被释放,所以一般将参数中的socket成为监听socket,只负责链接不负责通话,返回的
//socket称为会话socket,只负责与客户端通话
//parm1:监听socket负责链接
//parm2:返回客户端的结构体
(6)int connect(SOCKET s,struct sockaddr_in* name,int namelen)(客户端)主动提出连接请求
//连接失败返回SOCKET_ERROR
(7)int send(SOCKET s,char* buf,int len,int flags)
(8)int recv(SOCKET s,char* buf,int len,int flags)
//flags:一般为0
//在流式方式下超过你指定的长度,剩下的将在下一个recv读出,在数据报文方式下,剩下的将全部丢弃
(9)closesocket(SOCKET s) 关闭socket
流的方式如上
////////////////////////////////////////////////////////////////////
数据报文方式:
客户端可服务端相同->WSAStartup()->socket()->recvfrom()||sendto()->closesocket(s)
///////////////////////////////////////////////////////////////////
Winsock的异步模式
(1)int WSAAsynSelect(SOCKET s,HWND hWnd,unsigned int wMsg,long IEvent) 通过此函数来实现非阻塞通信
//只针对一个socket,如果有多个请执行多次
//hWnd:接收Winsock消息的窗口句柄
//非阻塞方式下wMsg向窗口发出消息名称,用户可以任意定义
//iEvent是被指定的网络事件->FD_READ,FD_WRITE,FD_OOB......
(2)int PASCAL FAR ioctlsocket(SOCKET s,long cmd,u_long FAR*argP)控制Socket的模式
//s:socket的识别码
//cmd:指令名称FIONBIO:开关non-block模式,FIONREAD:socket一次可读取的资料量,SIOCATMARK:OOB资料是否
//已经读完
//argp:指向cmd的参数指标
//return:成功返回0,失败返回SOCKET_ERROR,呼叫WSAGetLasrError可得知原因
WSAAsyncSelect(s,hWnd,0,0)->ioctlsocket()
(3)WSAGetLastError()检查产生SOCKEt_ERRor的原因 列如connect返回error得出原因WSAEWOULDBLOCK表明有可能无法与
远距离的服务器连接