既然服务端已经很虔诚了,很真诚了,处于倾听状态,那么该是去尝试接受客户端请求的时候了,别只顾着倾听,不去接纳别人。接纳客户端请求的函数是accept, 我们先来看看函数的原型:
函数的第一个参数用来标识服务端套接字(也就是listen函数中设置为监听状态的套接字),第二个参数是用来保存客户端套接字对应的“地方”(包括客户端IP和端口信息等), 第三个参数是“地方”的占地大小。返回值对应客户端套接字标识。
实际上是这样的: accept函数指定服务端去接受客户端的连接,接收后,返回了客户端套接字的标识,且获得了客户端套接字的“地方”(包括客户端IP和端口信息等)。
accept函数非常地痴情,痴心不改:如果没有客户端套接字去请求,它便会在那里一直痴痴地等下去,直到永远(注意, 此处讨论的是阻塞式的socket. 如果是非阻塞式的socket, 那么accept函数就没那么痴情了, 而是会立即返回, 并意犹未尽地对未来的客户端扔下一句话: 我等了你, 你不来, 那就算了, 我懒得鸟你)。
可是,我不想等了,我要睡觉了。睡觉之前,最后来看看accpt函数的用法:
unsigned int sockConn = accept(sockSrv,(SOCKADDR*)&addrClient, &len);
服务端都已经accept了客户端的请求,于是客户端与服务端也就勾搭上了,可以暧昧了,可以发信息了,怎么发送呢?用send函数即可,我们来看看send函数的原型:
第一个参数是客户端对应的套接字(千万注意),第二个参数指向发送的信息所在的缓冲区(内存),第三个参数是缓冲区的大小,第四个参数一般设置为0.
send函数的返回值非常重要,如果成功,则返回发送的字节数,如果失败,则返回对应的失败码。
别只顾着send数据啊,你也得接收一些数据啊,来而不往非礼也!如何接收?请看recv函数原型:
第一个参数表示客户端对应的套接字(千万要注意),第二个参数是要保存接收数据的地方,第三个参数是保存区的大小,第四个参数一般设置为0.
如果成功,则返回接收收据的字节数,如果失败,则返回错误码。
closesocket函数的作用和socket函数的作用相反,释放为套接字分配的资源。
WSACleanup函数和WSAStartup函数的作用相反,终止对套接字库的使用。
用不着多说。