zoukankan      html  css  js  c++  java
  • shutdown()

    shutdown()是指禁止在一个套接口上进行数据的接收与发送。

    简述

    禁止在一个套接口上进行数据的接收与发送。
    Linux:
    #include<sys/socket.h>
    int shutdown(int sockfd,int how);
    linux下成功则返回0,错误返回-1,错误码errno:EBADF表示sockfd不是一个有效描述符;ENOTCONN表示sockfd未连接;ENOTSOCK表示sockfd是一个描述符而不是socket描述符。
    Windows:
    #include <winsock.h>或#include <winsock2.h>
    int PASCAL FAR shutdown( SOCKET s, int how);
    s:用于标识一个套接口的描述字。
    how:标志,用于描述禁止哪些操作。
    how的方式有三种分别是
    SHUT_RD(0):关闭sockfd上的读功能,此选项将不允许sockfd进行读操作。
    SHUT_WR(1):关闭sockfd的写功能,此选项将不允许sockfd进行写操作。
    SHUT_RDWR(2):关闭sockfd的读写功能。

    注释

    shutdown()函数用于任何类型的套接口禁止接收、禁止发送或禁止收发。
    如果how参数为0,则该套接口上的后续接收操作将被禁止。这对于低层协议无影响。对于TCP协议,TCP窗口不改变并接收前来的数据(但不确认)直至窗口满。对于UDP协议,接收并排队前来的数据。任何情况下都不会产生ICMP错误包。
    若how为1,则禁止后续发送操作。对于TCP,将发送FIN。
    若how为2,则同时禁止收和发。
    请注意shutdown()函数并不关闭套接口,且套接口所占有的资源将被一直保持到closesocket()调用。

    评注

    无论SO_LINGER设置与否,shutdown()函数不会阻塞。
    一个应用程序不应依赖于重用一个已被shutdown()禁止的套接口。特别地,一个WINDOWS套接口实现不必支持在这样的套接口上使用connect()调用。
    返回值:
    如果没有错误发生,shutdown()返回0。否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码
    错误代码:
    WSANOTINITIALISED:在使用此API之前应首先成功地调用WSAStartup()。
    WSAENETDOWN:WINDOWS套接口实现检测到网络子系统失效。
    WSAEINVAL:how参数非法
    WSAEINPROGRESS:一个阻塞的WINDOWS套接口调用正在运行中。
    WSAENOTCONN:套接口未连接(仅适用于SOCK_STREAM类型套接口)。
    WSAENOTSOCK:描述字不是一个套接口。
    扩展知识:
    Socket的close与shutdown
    close-----关闭本进程的socket id,但链接还是开着的,用这个socket id的其它进程还能用这个链接,能读或写这个socket id。
    shutdown--则破坏了socket 链接,读的时候可能侦探到EOF结束符,写的时候可能会收到一个SIGPIPE信号,这个信号可能直到socket buffer被填充了才收到。
    更多关于close和shutdown的说明:
    1. 如果有多个进程共享一个套接字,close每被调用一次,计数减1,直到计数为0时,也就是所用进程都调用了close,套接字将被释放。
    2. 在多进程中如果一个进程中shutdown(sfd, SHUT_RDWR)后其它的进程将无法进行通信. 如果一个进程close(sfd)将不会影响到其它进程. 得自己理解引用计数的用法了. 有Kernel编程知识的更好理解了.
    3. 只要TCP栈的读缓冲里还有未读取(read)数据,则调用close时会直接向对端发送RST。
    4. shutdown与socket描述符没有关系,即使调用shutdown(fd, SHUT_RDWR)也不会关闭fd,最终还需close(fd)。
    5. 可以认为shutdown(fd, SHUT_RD)是空操作,因为shutdown后还可以继续从该socket读取数据,这点也许还需要进一步证实。
    6. 在已发送FIN包后write该socket描述符会引发EPIPE/SIGPIPE。
    7. 当有多个socket描述符指向同一socket对象时,调用close时首先会递减该对象的引用计数,计数为0时才会发送FIN包结束TCP连接。shutdown不同,只要以SHUT_WR/SHUT_RDWR方式调用即发送FIN包。
    8. SO_LINGER与close,当SO_LINGER选项开启但超时值为0时,调用close直接发送RST(这样可以避免进入TIME_WAIT状态,但破坏了TCP协议的正常工作方式),SO_LINGER对shutdown无影响。
    9. TCP连接上出现RST与随后可能的TIME_WAIT状态没有直接关系,主动发FIN包方必然会进入TIME_WAIT状态,除非不发送FIN而直接以发送RST结束连接。
    //中断套接字连接:通知服务器端或客户端停止接收和发送数据。(服务器端和客户端)
    int shutdown(SOCKET s, int how)
    //s为欲中断连接的套接字。
    //How为描述禁止哪些操作,取值为:SD_RECEIVE、SD_SEND、SD_BOTH。
    #define SD_RECEIVE 0x00
    #define SD_SEND 0x01
    #define SD_BOTH 0x02
    int nResult= shutdown(s,SD_BOTH);
    if(nResult==SOCKET_ERROR)
    {
    //错误处理
    }
    //关闭套接字:释放所占有的资源。(服务器端和客户端)
    int closesocket( SOCKET s )
    //s为欲关闭的套接字。
    int nResult=closesocket(s);
    if(nResult==SOCKET_ERROR)
    {
    //错误处理
    }
  • 相关阅读:
    Pagodas
    Bazinga
    取石子问题
    Sudoku Killer(hdu 1426 数独)
    欧拉函数
    CCPC Ancient Go
    ZZNU 1992: 情人节的尴尬
    fzu Problem 2128 最长子串(KMP + strstr 经典好题)
    POJ
    HDU
  • 原文地址:https://www.cnblogs.com/shmilxu/p/4837134.html
Copyright © 2011-2022 走看看