TCPSOCKET用法小结v1.1.doc_第1页
TCPSOCKET用法小结v1.1.doc_第2页
TCPSOCKET用法小结v1.1.doc_第3页
TCPSOCKET用法小结v1.1.doc_第4页
TCPSOCKET用法小结v1.1.doc_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

TCP SOCKET用法总结v1.0一、 理解socket1、 什么是socketsocket接口是TCP/IP网络的API,socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。要学Internet上的TCP/IP网络编程,必须理解socket接口。socket接口设计者最先是将接口放在Unix操作系统里面的。如果了解Unix系统的输入和输出的话,就很容易了解socket了。网络的 socket数据传输是一种特殊的I/O,socket也是一种文件描述符。socket也具有一个类似于打开文件的函数调用socket(),该函数返 回一个整型的socket描述符,随后的连接建立、数据传输等操作都是通过该socket实现的。常用的socket类型有两种:流式socket (SOCK_STREAM)和数据报式socket(SOCK_DGRAM)。流式是一种面向连接的socket,针对于面向连接的TCP服务应用;数据报式socket是一种无连接的socket,对应于无连接的UDP服务应用。2、 socket的建立为了建立Socket,程序可以调用socket函数,该函数返回一个类似于文件描述符的句柄。socket函数原型为:int socket(int domain, int type, int protocol);domain指明所使用的协议族,通常为PF_INET/AF_INET,表示互联网协议族(TCP/IP IPV4协议族);type参数指定socket的类型: SOCK_STREAM 或SOCK_DGRAM,Socket接口还定义了原始Socket(SOCK_RAW),允许程序使用底层协议;protocol通常赋值0。 socket()调用返回一个整型socket描述符,你可以在后面的调用使用它。socket描述符是一个指向内部数据结构的指针,它指向描述符表入口。调用socket函数时,将为一个socket数据结构分配存储空间,返回的是代表该结构空间的int型值,称作描述符。两个网络程序之间的一个网络连接包括五种信息:通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。socket数据结构中包含这五种信息。3、 socket的配置通过socket调用返回一个socket描述符后,在使用socket进行网络传输以前,必须配置该socket。面向连接的socket客户端通过 调用connect函数在socket数据结构中保存本地和远端信息。无连接socket的客户端和服务端以及面向连接socket的服务端通过调用 bind函数来配置本地信息。二、 TCP SOCKET(以下简称socket)有阻塞和非阻塞2种模式1、 Linux操作系统默认socket是阻塞的。2、 socket没有单独设置接收阻塞或发送阻塞的接口。因此,设置阻塞或非阻塞是对于接收和发送同时生效的。3、 有时一个socket可以先设成阻塞来用,再设成非阻塞来用,或相反。主要是根据功能需求确定使用方法。4、 fcntl( sockfd, F_SETFL, O_NONBLOCK);/ sockfd 是要改变状态的文件描述符./ F_SETFL 表明要改变文件描述符的状态/ O_NONBLOCK 表示将文件描述符变为非阻塞的.三、 setsockopt()函数函数原型int setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen);参数:sock:将要被设置或者获取选项的套接字。level:选项所在的协议层。 1)SOL_SOCKET:通用套接字选项.(选择)2)IPPROTO_IP:IP选项.3)IPPROTO_TCP:TCP选项.optname:需要访问的选项名,如下:leveloptname说明数据类型SOL_SOCKETSO_BROADCAST允许发送广播数据intSO_DEBUG允许调试intSO_DONTROUTE不查找路由intSO_ERROR获得套接字错误intSO_KEEPALIVE保持连接intSO_LINGER延迟关闭连接intSO_OOBINLINE带外数据放入正常数据流intSO_RCVBUF接收缓冲区大小intSO_SNDBUF发送缓冲区大小intSO_RCVLOWAT接收缓冲区下限intSO_SNDLOWAT发送缓冲区下限intSO_RCVTIMEO接收超时struct timevalSO_SNDTIMEO发送超时struct timevalSO_REUSERADDR允许重用本地地址和端口intSO_TYPE获得套接字类型intSO_BSDCOMPAT与BSD系统兼容intIPPROTO_IPIP_HDRINCL在数据包中包含IP首部intIP_OPTINOSIP首部选项intIP_TOS服务类型intIP_TTL生存时间intIPPRO_TCPTCP_MAXSEGTCP最大数据段的大小intTCP_NODELAY不使用Nagle算法intoptval:指向包含新选项值的缓冲。optlen:现选项(optval实际内容)的长度。返回值:成功执行时,返回0。失败返回-1,errno被设为以下的某个值EBADF:sock不是有效的文件描述词EFAULT:optval指向的内存并非有效的进程空间EINVAL:在调用setsockopt()时,optlen无效ENOPROTOOPT:指定的协议层不能识别选项ENOTSOCK:sock描述的不是套接字 四、 Socket()函数函数原型int socket(int domain, int type, int protocol);参数:Domain:指定用何种地址类型,完整的定义在/usr/include/bits/socket.h内PFUNIX/PF_LOCAL/AF_ UINIX进程通讯协议UNIX/AF_LOCAL PF_INET/AF_INET IPV4网络协议PF_INET6/AF_INET6 IPV6网络协议PF_IPX/AF_IPX IPX-Novell协议PF_NETLINK/AF_NETLINK 核心用户接口装置PF_X25/AF_X25 ITU-TX.25/ISO-8208协议PF_AX25/AF_AX25 业余无线AX.25协议PF_ATMPVC/AF_ATMPVC 存取原始ATM PVCsPF_APPLETALK/AF_APPLETALK Appletalk(DDP)协议PF_PACKET/AF_PACKET 初始封包接口Type:SOCK_STREAM提供双向连续且可信赖的数据流,即TCP。支持OOB(out-of-band)机制。在所有数据传输前必须使用connect()来建立连线状态。SOCK_DGRAM使用不连续不可信连的数据包连接SOCK_SEQPACKET 提供连续可信赖的数据包连接SOCK_RAW提供原始网络协议存取SOCK_RDM 提供可信赖的数据包连接SOCK_PACKET 提供网络驱动程序直接通信Protocol用来指定socket所使用的传输协议编号,通常此参考不用管它,设为0即可。返回值:成功执行时,返回0。失败返回-1,errno被设为以下的某个值 EPROTONOSUPPORT 参数domain指定的类型不支持参数type或protocol指定的协议 ENFILE 核心内存不足,无法建立新的socket结构 EACCESS 权限不足,无法建立参数type或protocol指定的协议 ENOBUFS/ENOMEM 内存不足 EINVAL 参数domain/type/protocol不合法执行流程:当我们在应用程序调用API函数socket(AF_INET, SOCK_STREAM,IPPROTO_TCP)时就会调用socket的系统调用进入统一的入口函数sys_socketcall,如果是创建套接字,就会调用sys_socket,sys_socket然后就调用sock_create,这个才是真正执行socket创建的函数。Sock_create函数调用socket_alloc创建socket,主要分配两个主要数据,一个是套接字socket,另一个是socket对应的inode。Socket的结构为:struct socketsocket_statestate;unsigned longflags;struct proto_ops*ops;/文件系统相关的接口file,inodestruct inode*inode;struct fasync_struct*fasync_list;/* Asynchronous wake up list*/struct file*file;/* File back pointer for gc*/网络关联的数据接口在sock中struct sock*sk;wait_queue_head_twait;shorttype;unsigned charpasscred; 因此,socket只是网络和文件系统关联的接口抽象,没有网络的相关信息,从socket的数据结构容易看出,还有另一个网络抽象的重要的数据结构sock。 接下来,调用inet_create(对于ip网络协议)创建sock(注意,sock和socket不同)。至此数据初始化完成了,然后就调用具体传输层协议的初始化函数。整个创建过程主要函数调用层次关系如下:sock_create() /创建socketalloc_sock() /创建初始的socketget_empty_inode() /获取一个Inode-socket_look_up() /填充具体inode的socket并初始化inet_create() /完善socket结构体内容,如添加sock结构alloc_sk() /创建sock结构五、 Bind()函数原型:int bind(int sockfd, struct sockaddr *my_addr, int addrlen);参数:sockfd: 是调用socket函数返回的socket描述符;my_addr:是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针;对于AF_INET类型的domain,sockaddr的结构定义为:struct socketaddr_in unsigned short int sin_family; uint16_t sin_port; struct in_addr sin_addr; unsigned char sin_zero8;struct in_adrr unit32_t s_addr;sin_family 即为sa_familySin_port 为使用的Port编号sin_addr.s_addr 为IP地址sin_zero 未使用addrlen: sockaddr的结构长度,常被设置为sizeof(struct sockaddr);返回值:成功则返回0,失败返回-1,错误原因存于errno中。错误代码:EBADF 参数sockfd非合法的socket处理代码EACCESS 权限不足ENOTSOCK参数sockfd为一文件描述词,非socket执行流程:对于AF_INET类型socket,调用inet_bind (),inet_bind ()中处理如下:1、 取得绑定地址.以及相关的socket和inet_sock.2、 得到地址类型,比如广播地址之类的.3、 判断地址是不是本地地址等一些相应的类型,如果不是,返回EADDRNOTAVAIL(Cannot assign requested address)4、 判断端口号小于prot_sock(1024)必须得有root权限.如果没有则返回EACCES.5、 判断TCP状态是否为close,如果close则返回EINVAL(Invalid argument);6、 检查绑定的端口是否可用,不可用则返回-EADDRINUSE(Address already in use);7、 设置源地址,源端口,目的地址和端口都设为0。可见,Bind ()函数无阻塞与非阻塞之分。六、 Listen()函数原型:int listen(int sockfd, int backlog);功能:Move a socket into listening state.参数:Sockfd 为调用socket函数获得的套接字的文件描述符信息。backlog 为提出连接请求后,在服务器接收该连接请求时的等待队列中的连接数。默认情况,该值为20,(就是在accep之前等待队列中最大保存的连接数)。如果等待队列中的连接数超过这个值,client端将收到ECONNEREFUSED的错误。系统调用listen只用于套接字类型为SOCK_STREAM或SOCK_SEQPACKET的场合。返回值:成功则返回0,失败返回-1,错误原因存于errno中。错误代码:EBADF 参数sockfd非合法socketEACCESS 权限不足EOPNOTSUPP 指定的socket并未支援listen模式执行流程:首先对传入的参数进行合法性的基本判断,如果参数非法则立即退出;对于AF_INET类型socket,调用inet_listen(),inet_listen()中处理如下:1、 如果socket已连接,或者socket类型不是SOCK_STREAM,则直接退出;2、 如果socket已关闭,或者socket已被侦听,则直接退出;3、 调用inet_csk_listen_start(),inet_csk_listen_start()返回成功或失败。 3.1)inet_csk_listen_start()首先调用reqsk_queue_allocnet/core/request_sock.c申请一块内存, 存放侦听 队列 for accept;如果申请不到,返回ENOMEM错误信息;3.2)接着检查绑定的端口是否可用,不可用则返回-EADDRINUSE(Address already in use);3.3)最后设置侦听状态,并把该struct sock *sk放入tcp_hashinfo.ehash中。 可见,listen ()函数无阻塞与非阻塞之分。七、 accept ()函数原型:int accept(int s, struct sockaddr *addr, socklen_t *addrlen);参数:s 是以 socket() 创建,用 bind() 绑定到一个本地地址,并且调用了listen()之后正在侦听一个连接的套接字;addr是回传指针。存入的是接受的连接对端的地址信息。addrlen addr的结构长度,常被设置为sizeof(struct sockaddr);accept返回一个新的套接字描述符fd。返回值:成功则返回新的socket描述符,失败返回-1,错误原因存于errno中。错误代码:EBADF 参数s 非合法socket处理代码。EFAULT 参数addr指针指向无法存取的内存空间。ENOTSOCK 参数s为一文件描述词,非socket。EOPNOTSUPP 指定的socket并非SOCK_STREAM。EPERM 防火墙拒绝此连线。ENOBUFS 系统的缓冲内存不足。ENOMEM 核心内存不足。执行流程:1) 阻塞方式在内核函数中,首先创建一个新的struct socket,并复制原来的套接字描述符s中的部分信息(主要是协议类型,协议操作等)。s就是正在listen的那个socket的fd,该socket中有已被接受的请求socket的队列。接下来,先确认侦听socket的状态是TCP_LISTEN后,检查请求队列是否为空(struct inet_connection_sock-isck_accept_queue-rskq_accept_head为NULL就表示请求队列为空)。如果为空,则进行睡眠等待(我们假设以阻塞方式进行accept),当协议栈接受了新的连接请求,填充了队列后,进程被唤醒,然后从队列头rskq_accept_head中取走一个request_sock,取其成员sk,这是我们需要的网络层的socket。侦听socket的成员sk_ack_backlog减1(从这儿看,sk_ack_backlog应该是侦听socket中未被accept的socket的数量),删除取出来的request_sock。 把获得的网络层socket与sys_accept中创建的struct socket建立关联。socket状态进入SS_CONNECTED,然后,如果accept系统调用传入了一个addr指针,则要为其赋值,这些信息从socket中都可以直接得到。accept一个连接请求即告完成。需要注意的是:新创建的描述符不再处于侦听状态.原套接字 s 也不受此调用的影响。还有,任意一个文件描述符标志 (任何可以被 fcntl以参数 F_SETFL 设置的值,比如非阻塞式或者异步状态)不会被 accept新创建的描述符所继承.2) 非阻塞方式当侦听socket的请求连接队列为空时,accept 将直接返回EAGAIN。八、 connect()函数原型:int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);功能:用来将参数sockfd的socket连至参数serv_addr指定的网络地址。参数: sockfd 为调用socket函数获得的套接字的文件描述符信息。 serv_addr 服务端的地址 addrlen serv_addr的结构长度,常被设置为sizeof(struct sockaddr);返回值:成功则返回新的socket描述符,失败返回-1,错误原因存于errno中。错误代码:EBADF 参数sockfd非合法socketEFAULT 参数serv_addr指针指向无法存取的内存空间ENOTSOCK 参数sockfd为一文件描述词,非socketEISCONN 参数sockfd的socket已是连线状态ECONNREFUSED 连线要求被server端拒绝ETIMEDOUT 企图连线的操作超过限定时间仍未有响应ENETUNREACH 无法传送数据包至指定的主机EAFNOSUPPORT sockaddr结构的sa_family不正确EALREADY socket为非阻塞且先前的连线操作还未完成执行流程:sys_connect():1、由fd得到socket,并且将地址复制到内核空间 2、调用inet_stream_connect进行主要的处理.inet_stream_connect():1、判断socket的状态。只有SS_UNCONNECTED也就是非连接状态时才调用tcp_v4_connect来进行连接处理。2、 判断tcp的状态sk_state只能为TCPF_SYN_SENT或者TCPF_SYN_RECV,才进入相关处理。3、 如果2的状态合适并且socket为阻塞模式则调用inet_wait_for_connect进入休眠等待三次握手完成,如果三次握手完成则继续执行4,握手失败则设置错误字EINPROGRESS并返回;非阻塞模式则直接返回,并设置错误号为EINPROGRESS。4、阻塞模式下,如果tcp的状态sk_state是TCP_CLOSE,则返回,错误字是inet_wait_for_connect设置的;否则置sk_state为连接状态SS_CONNECTED,返回成功。5、阻塞模式下,等待的超时时间为sk-sk_sndtimeo。网上有文章说这个时间不可设,固定为189秒,也有说是75秒的。经过测试发现,在我们10.45.11.156服务器上,这个时间只有3秒,而且,这个时间也是可设的。通过设置SO_SNDTIMO可以设置这个超时时间,但是只有设置在3秒之内时有用,大于3秒则按默认3秒处理了。需要进一步跟踪内核。阻塞方式和非阻塞方式的用法:1、 如上所述,阻塞方式下的情况比较简单。但有人觉得在连接不上的情况下,阻塞的时间太长且不受控,希望用非阻塞方式。但是,非阻塞方式下,connect返回不能说明连接的结果。因此,若使用非阻塞模式的connect,需要有其它办法辅助。2、 非阻塞connect使用方法1)、首先将标志位设为Non-blocking模式,准备在非阻塞模式下调用connect函数2)、调用connect,正常情况下,因为TCP三次握手需要一些时间;而非阻塞调用只要不能立即完成就会返回错误,所以这里会返回EINPROGRESS,表示在建立连接但还没有完成。3)、在读套接口描述符集(fd_set rset)和写套接口描述符集(fd_set wset)中将当前套接口置位(用FD_ZERO()、FD_SET()宏),并设置好超时时间(struct timeval *timeout)4)、调用select( socket, &rset, &wset, NULL, timeout ) 返回0表示connect超时如果你设置的超时时间大于75秒就没有必要这样做了,因为内核中对connect有超时限制就是75秒。九、 Send()函数原型:int send(int s, const void *msg, int len, unsigned int flags);参数:该函数的第一个参数指定发送端套接字描述符; 第二个参数指明一个存放应用程序要发送数据的缓冲区; 第三个参数指明实际要发送的数据的字节数; 第四个参数一般置0,其它的数值定义如下: MSG_OOB 传送的数据以out-of-band送出 MSG_DONTROUTE 取消路由表(routing-table)查询 MSG_DONTWAIT 设置为不可阻断运作 MSG_NOSIGNAL 此动作不愿被SIGPIPE信号中断返回值:成功则返回新的socket描述符,失败返回-1,错误原因存于errno中。错误代码:EBADF 参数s非合法的socketEFAULT 参数中有一指针指向无法存取的内存空间ENOTSOCK 参数s为一文件描述词,非socketEINTR 被信号所中断EAGAIN 此动作会令进程阻断但参数s的socket为不可阻断ENOBUFS 系统的核心内存不足ENOMEM 核心内存不足EINVAL 传给系统调用的参数不正确执行流程:1) 阻塞Socket的send函数(1)send先比较待发送数据的长度len和套接字s的 发送缓冲的长度 , 如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR; (2)如果len小于或者等于s的发送缓冲区的长度,那么send先检查协议是否正在发送s的发送缓冲中的数据,如果是就等待协议把数据发送完,如果协议还没有开始发送s的发送缓冲中的数据或者s的发送缓冲中没有数据,那么send就比较s的发送缓冲区的剩余空间和len ; (3)如果len大于剩余空间大小,send就一直等待协议把s的发送缓冲中的数据发送完 ; (4)如果len小于剩余 空间大小,send就仅仅把buf中的数据copy到剩余空间里(注意并不是send把s的发送缓冲中的数据传到连接的另一端的,而是协议传的,send仅仅是把buf中的数据copy到s的发送缓冲区的剩余空间里)。 如果send函数copy数据成功,就返回实际copy的字节数,如果send在copy数据时出现错误,那么send就返回SOCKET_ERROR;如果send在等待协议传送数据时网络断开的话,那么send函数也返回SOCKET_ERROR; 要注意send函数把buf中的数据成功copy到s的发送缓冲的剩余空间里后它就返回了,但是此时这些数据并不一定马上被传到连接的另一端 。 如果协议在后续的传送过程中出现网络错误的话,那么下一个Socket函数就会返回SOCKET_ERROR。(每一个除send外的Socket函数在执行的最开始总要先等待套接字的发送缓冲中的数据被协议传送完毕才能继续,如果在等待时出现网络错误,那么该Socket函数就返回 SOCKET_ERROR) 2) 非阻塞Socket的send函数的执行通过测试发现,异步socket的send函数在网络刚刚断开时还能发送返回相应的字节数,同时使用select检测也是可写的,但是过几秒钟之后,再send就会出错了,返回-1。select也不能检测出可写了。ssnd 十、 recv()函数功能原型:i nt recv( SOCKET s, char FAR *buf, int len, int flags);参数: 第一个参数指定接收端套接字描述符;第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据; 第三个参数指明buf的长度; 第四个参数一般置0。 返回值:执行流程:1) 阻塞Socket 的recv函数(1)recv先等待s的发送缓冲中的数据被协议传送完毕,如果协议在传送s的发送缓冲中的数据时出现网络错误,那么recv函数返回SOCKET_ERROR;(2)如果s的发送缓冲中没有数据或者数据被协议成功发送完毕后,recv先检查套接字s的接收缓冲区,如果s接收缓冲区中没有数据或者协议正在接收数据,那么recv就一直等待,直到协议把数据接收完毕或超时。当协议把数据接收完毕,recv函数就把s的接收缓冲中的数据copy到buf中( 注意协议接收到的数据可能大于buf的长度,所以在这种情况下要调用几次recv函数才能把s的接收缓冲中的数据copy完。recv函数仅仅是copy数据,真正的接收数据是协议来完成的 );recv函数返回其实际copy的字节数。如果recv在copy时出错,那么它返回SOCKET_ERROR;如果recv函数在等待协议接收数据时网络中断了,那么它返回0。2) 非阻塞Socket 的recv函数上述(2)的过程,无等待,直接返回当前收到的长度或错误。十一、 数据结构1、struct socketstruct socket socket_statestate;shorttype;unsigned longflags;/* * Please keep fasync_list & wait fields in the same cache line */struct fasync_struct*fasync_list;wait_queue_head_twait;struct file*file;struct sock*sk;const struct proto_ops*ops;2、struct sockaddrstruct sockaddr sa_family_tsa_family;/* address family, AF_xxx*/charsa_data14;/* 14 bytes of protocol address*/;3、struct sockaddr_instruct sockaddr_in sa_family_tsin_family;/* Address family*/ _be16 sin_port; /* Port number*/ struct in_addrsin_addr; /* Internet address*/ /* Pad to size of struct sockaddr. */ unsigned char_pad_SOCK_SIZE_ - sizeof(short int) -sizeof(unsigned short int) - sizeof(struct in_addr);4、struct sockstruct sock /* * Now struct inet_timewait_sock also uses sock_common, so please just * dont add nothing before this first member (_sk_common) -acme */struct sock_common_sk_common;#define sk_family_sk_common.skc_family#define sk_state_sk_common.skc_state#define sk_reuse_sk_common.skc_reuse#define sk_bound_dev_if_sk_common.skc_bound_dev_if#define sk_node_sk_common.skc_node#define sk_nulls_node_sk_common.skc_nulls_node#define sk_bind_node_sk_common.skc_bind_node#define sk_refcnt _sk_common.skc_refcnt#define sk_hash_sk_common.skc_hash#define sk_prot_sk_common.skc_prot#define sk_net _sk_common.skc_netunsigned char sk_shutdown : 2, sk_no_check : 2, sk_userlocks : 4;unsigned charsk_protocol;unsigned shortsk_type;int sk_rcvbuf;socket_lock_tsk_lock;/* * The backlog queue is special, it is always used with * the per-socket spinlock held and requires low latency * access. Therefore we special case its implementation. */struct struct sk_buff *head;struct sk_buff *tail; sk_backlog;wait_queue_head_t*sk_sleep;struct dst_entry*sk_dst_cache;#ifdef CONFIG_XFRMstruct xfrm_policy*sk_policy2;#endifrwlock_tsk_dst_lock;atomic_tsk_rmem_alloc;atomic_tsk_wmem_alloc;atomic_tsk_omem_alloc;intsk_sndbuf;struct sk_buff_headsk_receive_queue;struct sk_buff_headsk_write_queue;#ifdef CONFIG_NET_DMAstruct sk_buff_headsk_async_wait_queue;#endifintsk_wmem_queued;intsk_forward_alloc;gfp_tsk_allocation;intsk_route_caps;intsk_gso_type;unsigned intsk_gso_max_size;intsk_rcvlowat;unsigned long sk_flags;unsigned long sk_lingertime;struct sk_buff_headsk_error_queue;struct proto*sk_prot_creator;rwlock_tsk_callback_lock;intsk_err,sk_err_soft;atomic_tsk_drops;unsigned shortsk_ack_backlog;unsigned shortsk_max_ack_backlog;_u32sk_priority;struct ucredsk_peercred;longsk_rcvtimeo;longsk_sndtimeo;struct sk_filter *sk_filter;void*sk_protinfo;struct timer_listsk_timer;ktime_tsk_stamp;struct socket*sk_socket;void*sk_user_data;struct page*sk_sndmsg_page;struct sk_buff*sk_send_head;_u32sk_sndmsg_off;intsk_write_pending;#ifdef CONFIG_SECURITYvoid*sk_security;#endif_u32sk_mark;/* XXX 4 bytes hole on 64 bit */void(*sk_state_change)(struct sock *sk);void(*sk_data_ready)(struct sock *sk, int bytes);void(*sk_write_space)(struct sock *sk);void(*sk_error_report)(struct sock *sk); int(*sk_backlog_rcv)(struct sock *sk, struct sk_buff *skb); void (*sk_destruct)(struct sock *sk);附录1:linux系统的全局errno号#ifndef _ASM_GENERIC_ERRNO_H#define _ASM_GENERIC_ERRNO_H#define EPERM 1 #define ENOENT 2 #define ESRCH 3 #define EINTR 4 #define EIO 5 #define ENXIO 6 #define E2BIG 7 #define ENOEXEC 8 #define EBADF 9 #define ECHILD 10 #define EAGAIN 11 #define ENOMEM 12 #define EACCES 13 #define EFAULT 14 #define ENOTBLK 15 #define EBUSY 16 #define EEXIST 17 #define EXDEV 18 #define ENODEV 19 #define ENOTDIR 20 #define EISDIR 21 #define EINVAL 22 #define ENFILE 23 #define EMFILE 24 #define ENOTTY 25 #define ETXTBSY 26 #define EFBIG 27 #define ENOSPC 28 #define ESPIPE 29 #define EROFS 30 #define EMLINK 31 #define EPIPE 32 #define EDOM 33 #define ERANGE 34 #define EDEADLK 35 #define ENAMETOOLONG 36 #define ENOLCK 37 #define ENOSYS 38 #define ENOTEMPTY 39 #define ELOOP 40 #define EWOULDBLOCK EAGAIN #define ENOMSG 42 #define EIDRM 43 #define ECHRNG 44 #define EL2NSYNC 45 #define EL3HLT 46 #define EL3RST 47 #define ELNRNG 48 #define EUNATCH 4

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论