怎么优雅的正常断开TCP连接

如何优雅的正常断开TCP连接
我写了个简单的网络程序, 就是服务器和客户端连接上后就不断的互相收发数据,不停的发,直到关闭socket.

程序运行后发现一个问题,就是如果我发送命令停止服务器或者客户端时,程序立即关闭socket,这时候可能还有没来得及接受的数据,所以,就会出现最后的数据丢掉了。

现在请教如何优雅的断开连接,让c/s两端不会因为closesocket而丢失数据。这个正常断开连接的步骤应该怎样?网络上全是非正常断开的处理,我找正常断开的步骤。

先谢谢各位捧场了
------解决方案--------------------
使用setsockopt设置linger

TCP连接断开的时候调用closesocket函数,有优雅的断开和强制断开两种方式.
  那么如何设置断开连接的方式呢?是通过设置socket描述符一个linger结构体属性。
  linger结构体数据结构如下:
  struct linger
  {
  int l_onoff;
  int l_linger;
  };
  有三种组合方式:
  第一种
  l_onoff = 0;
  l_linger忽略
  这种方式下,就是在closesocket的时候立刻返回,底层会将未发送完的数据发送完成后再释放资源,也就
  是优雅的退出。
  第二种
  l_onoff非零
  l_linger = 0;
  这种方式下,在调用closesocket的时候同样会立刻返回,但不会发送未发送完成的数据,而是通过一个REST包强制的关闭socket描述符,也就是强制的退出。
  第三种
  l_onoff非零
  l_linger > 0
  这种方式下,在调用closesocket的时候不会立刻返回,内核会延迟一段时间,这个时间就由l_linger得值来决定。如果超时时间到达之前,发送完未发送的数据(包括FIN包)并得到另一端的确认,closesocket会返回正确,socket描述符优雅性退出。否则,closesocket会直接返回错误值,未发送数据丢失,socket描述符被强制性退出。需要注意的时,如果socket描述符被设置为非堵塞型,则closesocket会直接返回值。
------解决方案--------------------
默认都会graceful的.closesocket后,对方会继续收到有效数据,然后recv个长度0,也关掉socket.
------解决方案--------------------

bool GracefulCloseSocket(SOCKET sock)
{
    char buff[512] = {0};

    if (shutdown(sock, SD_SEND) != SOCKET_ERROR)
while (recv(sock, buff, sizeof(buff), 0) > 0) ;
else
return false
closesocket(sock);
return true;
}


这个应该算是优雅的关闭吧
------解决方案--------------------
这里主要涉及到TCP/IP缓冲区 和 全双工连接的半关闭。

连接的一端A先发完数据后,可以先用shutdown(..., SHUT_WR)函数半关闭连接,A会把发送缓存中的数据发送完,然后发送FIN,对方B回返回ACK,此时,A还可以接受数据,(如果调用close的话,默认会丢弃接受缓冲区,这就是造成A接受到得数据不完整的一个方面;)
但对方不会立刻发送FIN来结束它的传输,所以,对方可以先发完数据,然后也通过shutdown来关闭剩下一半的连接。(而A调用的是close的话,B来不及把剩下的发完。这是流失数据的留一个原因。)

服务器端同时开始接受和发送,也就是处在全双工工作状态,应该用shutdown函数来一半一半关闭。