采用面向连接的协议(如TCP)时,服务器处理的请求比较复杂,并不是简单的请求应答所能解决的,面且大多数TCP服务器是并发服务器,因此往往要经过反复的交互。典型的套接字接口调用流程:
客户端 服务端
------------------------ --------------------------------------
| 调用Socket(),建立流式| |调用Socket(),建立流式套接字,比如:C|
| 套接字,比如:C | --------------------------------------
------------------------ | 1
--------------------------------------
| |调用Bind()将套接字C与本地址址、端口 |
| | 绑定 | | --------------------------------------
| | 2
| --------------------------------------
| |调用Listen()通知底层协议(TCP),服务 |
| |器已经准备接收数据 |
| --------------------------------------
| | 3
| --------------------------------------
| |调用Accept()准备接收客户端连接 |
| --------------------------------------
| | 4
| --------------------------------------
------------------- |连接建立,accept()调用返回,得到新的|
|调用Connect(),使 | 请求 |数据套接字,比如B,B只能用于数据传输|
|套接字C与远程主机| ---- |原套接字C仍然打开,处于监听连接状态 |
|建立连接 | 连接 -------------------------------------
------------------- |
| 数据交换 | 5
--------------------- -------------------------------------
|调用Send()/Recv(), | |调用Send()/Recv(), 在套接字C上读写 |
|在套接字C上读写数据| |数据直到数据交换完成 |
|直到数据交换完成 | | |
--------------------- -------------------------------------
| | 6
| -------------------------------------
| |调用CloseSocket(),关闭套接字B |
| -------------------------------------
| | 7
| |
---------------------- -------------------------------------
|调用结束,关闭套接 | | |
|字C,结束此次连接会 | |调用CloseSocket(),关闭套接字C |
|话 | | |
---------------------- -------------------------------------
面向连接的服务器一般是并发服务器。在Windows平台上,我们往往在调用Accept()函数返回C后,会创建一个请求/应答执行线程,将C作为参数之一传递给该线程,由该线程来完成客户端与服务器端复杂的请求应答工作,面主线程会再次调用Accept()函数,以接收新的客户端连接请求。