您现在的位置: 365建站网 > 365学习 > C语言中accept()函数和shutdown()函数的使用

C语言中accept()函数和shutdown()函数的使用

文章来源:365jz.com     点击数:460    更新时间:2018-05-30 11:55   参与评论

C语言setsockopt()函数:设置socket状态

头文件:

#include <sys/types.h>  #include <sys/socket.h>

定义函数:

int setsockopt(int s, int level, int optname, const void * optval, ,socklen_toptlen);

函数说明:setsockopt()用来设置参数s 所指定的socket 状态. 参数level 代表欲设置的网络层, 一般设成SOL_SOCKET 以存取socket 层. 参数optname 代表欲设置的选项, 有下列几种数值:
   SO_DEBUG 打开或关闭排错模式
   SO_REUSEADDR 允许在bind ()过程中本地地址可重复使用
   SO_TYPE 返回socket 形态.
   SO_ERROR 返回socket 已发生的错误原因
   SO_DONTROUTE 送出的数据包不要利用路由设备来传输.
   SO_BROADCAST 使用广播方式传送
   SO_SNDBUF 设置送出的暂存区大小
   SO_RCVBUF 设置接收的暂存区大小
   SO_KEEPALIVE 定期确定连线是否已终止.
   SO_OOBINLINE 当接收到OOB 数据时会马上送至标准输入设备
   SO_LINGER 确保数据安全且可靠的传送出去.

参数 optval 代表欲设置的值, 参数optlen 则为optval 的长度.

返回值:成功则返回0, 若有错误则返回-1, 错误原因存于errno.

附加说明:
1、EBADF 参数s 并非合法的socket 处理代码
2、ENOTSOCK 参数s 为一文件描述词, 非socket
3、ENOPROTOOPT 参数optname 指定的选项不正确.
4、EFAULT 参数optval 指针指向无法存取的内存空间.


C语言accept()函数:接受socket连线

头文件:

#include <sys/types.h>  #include <sys/socket.h>

定义函数:

int accept(int s, struct sockaddr * addr, int * addrlen);

函数说明:accept()用来接受参数s 的socket 连线. 参数s 的socket 必需先经bind()、listen()函数处理过, 当有连线进来时accept()会返回一个新的socket 处理代码, 往后的数据传送与读取就是经由新的socket处理, 而原来参数s 的socket 能继续使用accept()来接受新的连线要求. 连线成功时, 参数addr 所指的结构会被系统填入远程主机的地址数据, 参数addrlen 为scokaddr 的结构长度. 关于机构sockaddr 的定义请参考bind().accept()系统调用主要用在基于连接的套接字类型,比如SOCK_STREAM和SOCK_SEQPACKET。它提取出所监听套接字的等待连接队列中第一个连接请求,创建一个新的套接字,并返回指向该套接字的文件描述符。新建立的套接字不在监听状态,原来所监听的套接字也不受该系统调用的影响。

备注:新建立的套接字准备发送send()和接收数据recv()。

参数:

sockfd,    利用系统调用socket()建立的套接字描述符,通过bind()绑定到一个本地地址(一般为服务器的套接字),并且通过listen()一直在监听连接;

addr,    指向struct sockaddr的指针,该结构用通讯层服务器对等套接字的地址(一般为客户端地址)填写,返回地址addr的确切格式由套接字的地址类别(比如TCP或UDP)决定;若addr为NULL,没有有效地址填写,这种情况下,addrlen也不使用,应该置为NULL;

备注:addr是个指向局部数据结构sockaddr_in的指针,这就是要求接入的信息本地的套接字(地址和指针)。

addrlen,    一个值结果参数,调用函数必须初始化为包含addr所指向结构大小的数值,函数返回时包含对等地址(一般为服务器地址)的实际数值;

备注:addrlen是个局部整形变量,设置为sizeof(struct   sockaddr_in)。

返回值:成功则返回新的socket 处理代码, 失败返回-1, 错误原因存于errno 中.

错误代码:
1、EBADF 参数s 非合法socket 处理代码.
2、EFAULT 参数addr 指针指向无法存取的内存空间.
3、ENOTSOCK 参数s 为一文件描述词, 非socket.
4、EOPNOTSUPP 指定的socket 并非SOCK_STREAM.
5、EPERM 防火墙拒绝此连线.
6、ENOBUFS 系统的缓冲内存不足.
7、ENOMEM 核心内存不足.
 

为了在套接字中有到来的连接时得到通知,可以使用select()或poll()。当尝试建立新连接时,系统发送一个可读事件,然后调用accept()为该连接获取套接字。另一种方法是,当套接字中有连接到来时设定套接字发送SIGIO信号。

返回值

成功时,返回非负整数,该整数是接收到套接字的描述符;出错时,返回-1,相应地设定全局变量errno。

错误处理

Linux下,accept()把已等待的网络错误传给新建立的连接,当作是accept()返回的错误。这于其他的BSD实现是不同的。为了可靠运行,应该在accept()之后检测协议已定义的一些网络错误,并把这些错误当作EAGAIN并重试。对于TCP/IP协议来说,主要有错误:ENETDOWN,EPROTO,ENOPROTOOPT,EHOSTDOWN,ENONET,EHOSTUNREACH,EOPNOTSUPPENETUNREACH

C语言shutdown()函数:终止socket通信
头文件:

#include <sys/socket.h>

定义函数:

int shutdown(int s, int how);

函数说明:shutdown()用来终止参数s 所指定的socket 连线. 参数s 是连线中的socket 处理代码, 参数how有下列几种情况:

  •    how=0 终止读取操作.
  •    how=1 终止传送操作
  •    how=2 终止读取及传送操作

返回值:成功则返回0, 失败返回-1, 错误原因存于errno.

错误代码:
1、EBADF 参数s 不是有效的socket 处理代码
2、ENOTSOCK 参数s 为一文件描述词, 非socket
3、ENOTCONN 参数s 指定的socket 并未连线

注意:
    1>. 如果有多个进程共享一个套接字,close每被调用一次,计数减1,直到计数为0时,也就是所用进程都调用了close,套

接字将被释放。
    2>. 在多进程中如果一个进程中shutdown(sfd, SHUT_RDWR)后其它的进程将无法进行通信. 如果一个进程close(sfd)将不会

影响到其它进程. 得自己理解引用计数的用法了. 有Kernel编程知识的更好理解了.

============================================================
如果有五个进程使用该 socket id 则这个socket 描述符参考数则有五个,当所有进程都close()了这样参考数就等于0,该socket 就真的关闭释放了。


如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛


发表评论 (460人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码: 点击我更换图片
最新评论
------分隔线----------------------------