linux网络编程函数说明

  常用socket函数详解:socket、bind、listen、connect、accept、select、send、sendto、recv、recvfrom、close、shutdown、fcntl、setsockopt、epoll_create、epoll_wait、epoll_ctl

 

 

函数 函数原型 所需头文件 功能 参数说明 返回值及附加说明
socket int socket(int domain,int type, int protocol)

<sys/types.h>        

<sys/socket.h>

 创建一个套接字

domain:

  AF_INET:IPv4协议

  AF_INET6:IPv6协议

  AF_LOCAL:Unix域协议

  AF_ROUTE:路由套接口

  AF_KEY:密钥套接口

type:

  SOCKET_STREAM:双向可靠数据流,对应TCP

  SOCKET_DGRAM:双向不可靠数据报,对应UDP

  SOCKET_RAW:提供传输层以下的协议,可以访问内部网络接口,例如接收和发送ICMP报文

protocol:

  type为SOCKET_RAW时需要设置此值说明协议类型,其他类型设置为0即可

成功:socket文件描述符

失败:-1,失败原因存于error中 

 bind int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)

<sys/types.h>        

<sys/socket.h>

将一个协议地址与socket文件描述符联系起来

sockfd:

  socket文件描述符

addr:

  my_addr指向sockaddr结构,该结构中包含IP地址和端口等信息

addrlen:

  sockaddr结构的大小,可设置为sizeof(struct sockaddr) 

 

成功:0

失败:-1,失败原因存于error中 

 listen int listen(int sockfd, int backlog)  

<sys/types.h>        

<sys/socket.h>

 监听并等待连接

 sockfd:

  监听socket文件描述符

backlog:

  套接字排队的最大连接个数,对于监听socket文件描述符sockfd,内核要维护两个队列,分别为未完成连接队列和已完成连接队列,这两个队列之和不超过backlog

成功:0

失败:-1,失败原因存于error中

 
 connect  

int connect(int sockfd, const struct sockaddr *serv_addr,socklen_t addrlen)

 

<sys/types.h>        

<sys/socket.h>

建立socket连接 

sockfd:

  socket文件描述符

serv_addr:

  连接的网络地址和端口

addrlen: 

  sockaddr结构的大小,可设置为sizeof(struct sockaddr)

成功:0

失败:-1,失败原因存于error中

函数connect激发TCP的三路握手过程,出错返回有以下几种情况:

1、 如果客户没有收到SYN分节的响应(总共75秒,这之间可能重发了若干次SYN),则返回ETIMEDOUT

2、 如果对客户的SYN的响应是RST,则表明该服务器主机在指定的端口上没有进程在等待与之相连,函数返回错误ECONNREFUSED

3、如果客户发出的SYN在中间路由器上引发一个目的地不可达的ICMP错误,内核返回EHOSTUNREACH或ENETUNREACH错误(即ICMP错误)给进程

 
 accept int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)

<sys/types.h>        

<sys/socket.h>

 
接受socket连接,返回一个新的socket文件描述符,原socket文件描述符仍为listen函数所用,而新的socket文件描述符用来处理连接的读写操作 

 

sockfd:

  socket文件描述符

addrlen:

  addr的大小,可设置为sizeof(struct sockaddr)

addr:填入远程主机的地址数据

成功:返回新的sockfd

失败:-1,失败原因存于error中

1、accept函数由TCP服务器调用,为阻塞函数,从已完成连接的队列中返回一个连接;如果该对列为空,则进程进入阻塞等待

2、 函数返回的套接字为已连接套接字,而监听套接字仍为listen函数所用

 
 close int close(int sockfd)  <unistd.h>  关闭连接的socket文件描述符  sockfd:socket文件描述符  

成功:0

失败:-1,失败原因存于error中

1、close函数默认功能是将套接字置为“已关闭”标记,并立即返回给进程,这个套接字不能再为该进程所用

2、 正常情况下,close将引发四个分节终止序列,但在终止前将发送已排队的数据

3、 如果套接字描述符访问计数在调用close后大于0(多个进程共享同一个套接字的情况下),则不会引发TCP终止序列(即不会发送FIN分节)

shutdown int shutdown(int sock, int how) <sys/socket.h>   终止socket通信

sock:

  socket文件描述符

how:

  0(SHUT_RD):关闭socket连接的读这一半,不再接收套接字中的数据且现留在收缓冲区的数据作废

  1(SHUT_WR):关闭socket连接的写这一半(半关闭),但留在套接字发送缓冲区中的数据都会被发送,后跟TCP连接终止序列,不管访问计数是否大于0,此后将不能再执行对套接字的任何写操作

  2(SHUT_RDWR):socket连接的读、写都关闭

 

成功:0

失败:-1,失败原因存于error中

 read ssize_t read(int fd, void *buf ,size_t count) <unistd.h> 从打开的socket文件流中读取数据

fd: socket文件描述符 

count:最大读取字节数

 

buf:读取数据的首地址

成功:实际读取字节数

失败:-1,错误代码存放在error中

调用函数read从socket文件流中读取数据时,有如下几种情况:

1、套接字接收缓冲区接收数据,返回接收到的字节数

2、TCP协议收到FIN数据,返回0

3、 TCP协议收到RST数据,返回-1,同时errno设置为ECONNRESET

4、 进程阻塞过程中接收到信号,返回-1,同时errno设置为EINTR

 write ssize_t write (int fd,const void *buf,size_t count)  <unistd.h> 向socket文件流中写入数据 

fd:

   socket文件描述符 

buf:

  写入数据的首地址  

count:

  最大写入字节数

成功:实际写入的字节数

失败:-1,错误代码存放在error中

调用函数write向socket文件流写数据时,有如下几种情况:

1、套接字发送缓冲区有足够空间,返回发送的字节数

2、 TCP协议接收到RST数据,返回-1,同时errno设置为ECONNRESET

3、 进程阻塞过程中接收到信号,返回-1,同时errno设置为EINTR

 

 

 

 recv

 

ssize_t send(int s, const void *buf, size_t len, int flags)

 

<sys/types.h>        

<sys/socket.h>

通过socket文件描述符发送数据到对方 

 

s:

  socket文件描述符

buf:

  发送数据的首地址

len:

  发送数据的长度

flags:

  0:此时功能同write,flags还可以设为以下标志的组合

  MSG_OOB:发送带外数据

  MSG_DONTROUTE:告诉IP协议,目的主机在本地网络,没有必要查找路由表

  MSG_DONTWAIT:设置为非阻塞操作

  MSG_NOSIGNAL:表示发送动作不愿被SIGPIPE信号中断      

    

  

成功:实际发送的字节数

失败:-1,错误代码存放在error中

 
 recv  ssize_t recv(int s, void *buf, size_t len, int flags)  

<sys/types.h>        

<sys/socket.h>

 通过socket文件描述符从对方接收数据

 

s:

  socket文件描述符

len:

  可接收数据的最大长度

flags:

  0:此时功能同read,flags还可以设为以下标志的组合

  MSG_OOB:接收带外数据

  MSG_PEEK:查看数据标志,返回的数据并不在系统中删除,如果再次调用recv函数会返回相同的数据内容

  MSG_DONTWAIT:设置为非阻塞操作

  MSG_WAITALL:强迫接收到len大小的数据后才返回,除非有错误或有信号产生

buf 接收数据的首地址

成功:实际发送的字节数

失败:-1,失败原因存于error中

getsockopt  

int getsockopt(int s, int level, int optname,void *optval, socklen_t *optlen)

<sys/types.h>        

<sys/socket.h>

 
 获取套接字的属性

s:

  socket文件描述符

level

  SOL_SOCKET:通用套接字选项

  IPPROTO_IP:IP选项

  IPPROTO_TCP:TCP选项

optname:

  访问的选项名,见右侧表格

optlen:

  optval的长度

函数传出值:

  optval,取得的属性值

函数返回值:

  成功:0

  失败:-1,失败原因存于error中

 

level(级别)

optname(选项名

说明

数据类型

SOL_SOCKET

 

SO_BROADCAST

允许发送广播数据

int

SO_DEBUG

允许调试

int

SO_DONTROUTE

不查找路由

int

SO_ERROR

获得套接字错误

int

SO_KEEPALIVE

保持连接

int

SO_LINGER

延迟关闭连接

struct linger

SO_OOBINLINE

带外数据放入正常数据流

int

SO_RCVBUF

接收缓冲区大小

int

SO_SNDBUF

发送缓冲区大小

int

SO_RCVLOWAT

接收缓冲区下限

int

SO_SNDLOWAT

发送缓冲区下限

int

SO_RCVTIMEO

接收超时

struct timeval

SO_SNDTIMEO

发送超时

struct timeval

SO_REUSERADDR

允许重用本地地址和端口

int

SO_TYPE

获得套接字类型

int

SO_BSDCOMPAT

与BSD系统兼容

int

IPPROTO_IP

 

IP_HDRINCL

在数据包中包含IP首部

int

IP_OPTINOS

IP首部选项

int

IP_TOS

服务类型

int

IP_TTL

生存时间

int

IPPRO_TCP

TCP_MAXSEG

TCP最大数据段的大小

int

CP_NODELAY

不使用Nagle算法

int

 
setsockopt  

int setsockopt(int s, int level, int optname,const void *optval, socklen_t optlen)

 

<sys/types.h>        

<sys/socket.h>

 设置套接字的属性

 

s:

  socket文件描述符

level:

  SOL_SOCKET:通用套接字选项

  IPPROTO_IP:IP选项

  IPPROTO_TCP:TCP选项

optname:

  设置的选项名,具体见getsockopt中的表格

optval:

  设置的属性值

optlen:

  optval的长度  

 

成功:0

失败:-1,失败原因存于error中

sendto  

ssize_t sendto(int s, const void *buf, size_t len, int flags,const struct sockaddr *to, socklen_t tolen)

 

<sys/types.h>        

<sys/socket.h>

 通过socket文件描述符发送数据到对方

 

s:

  socket文件描述符

buf:

  发送数据的首地址

len:

  发送数据的长度

flags:

  0:默认方式发送数据,flags还可以设为以下标志的组合

  MSG_OOB:发送带外数据

  MSG_DONTROUTE:告诉IP协议,目的主机在本地网络,没有必要查找路由表

  MSG_DONTWAIT:设置为非阻塞操作

  MSG_NOSIGNAL:表示发送动作不愿被SIGPIPE信号中断

to:

  存放目的主机IP地址和端口信息

tolen:

  to的长度,可设置为sizeof(struct sockaddr)

     

 

 

成功:实际发送的字节数

失败:-1,失败原因存于error中

 recvfrom  

ssize_t recvfrom(int s, void *buf, size_t len, int flags,struct sockaddr *from, socklen_t *fromlen)

<sys/types.h>        

<sys/socket.h>

 
通过socket文件描述符从对方接收数据,用于UDP协议

 

s:

  socket文件描述符

len:

  可接收数据的最大长度

flags:

  0:默认方式接收数据,flags还可以设为以下标志的组合

  MSG_OOB:接收带外数据

  MSG_PEEK:查看数据标志,返回的数据并不在系统中删除,如果再次调用recv函数会返回相同的数据内容

  MSG_DONTWAIT:设置为非阻塞操作

  MSG_WAITALL:强迫接收到len大小的数据后才返回,除非有错误或有信号产生

fromlen:

  from的长度,可设置为sizeof(struct sockaddr)

 

buf 接收数据的首地址

from 存放发送方的IP地址和端口

成功:实际接收的字节数

失败:-1,失败原因存于error中

epoll_create int epoll_create(int size)

 

<sys/epoll.h>

 

 创建一个epoll的句柄

 size:

  监听的数目

 

成功:大于零的句柄

失败:-1,失败原因存于error中

epoll_wait int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout)  

<sys/epoll.h>

 等待事件的产生

epfd:

  epoll_create返回的句柄

events:

  返回的监听到有事件变化的集合

maxevents:

  集合里events的个数

timeout:

  超时时间,毫秒,0会立即返回,-1将不确定,也有说法说是永久阻塞

 

struct epoll_events结构

typedef union epoll_data {

  void *ptr;  //使用的时候使用ptr或者fd其中一个

  int fd;  

  __uint32_t u32; //为了字节对齐  

   __uint64_t u64;//为了字节对齐  

} epoll_data_t;  

 

struct epoll_event {

   __uint32_t events; // Epoll events,对应于下表中的EPOLLIN等参数,可以使用|将多个参数设置进来

   epoll_data_t data; //User data variable

};  

返回触发事件的个数 
epoll_ctl int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)  

<sys/epoll.h>

epoll的事件注册

epfd:

  epoll_create返回的句柄

op:

  对fd的操作

  EPOLL_CTL_ADD:注册新的fd到epfd中

  EPOLL_CTL_MOD:修改已经注册的fd的监听事件

  EPOLL_CTL_DEL:从epfd中删除一个fd

fd:

  要操作的句柄

event:

  需要监听什么事

  EPOLLIN :表示对应的文件描述符可以读(包括对端SOCKET正常关闭);

  EPOLLOUT:表示对应的文件描述符可以写;

  EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);

  EPOLLERR:表示对应的文件描述符发生错误;

  EPOLLHUP:表示对应的文件描述符被挂断;

  EPOLLET: 将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered是默认的)来说的。

  EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里

 

成功返回0

失败返回-1

 

 

 

posted on 2017-06-04 20:54  dbear-E  阅读(1087)  评论(0编辑  收藏  举报

导航