Socket API

1.Socket()

接口原型

int
lwip_socket(int domain, int type, int protocol)

函数作用:

用于根据指定的地址族、数据类型和协议来分配一个套接口的描述字及其所用的资源的函数

函数入参:

domain地址族AF_INET(IP_V4)、AF_INET6(IP_V6)
type支持三种协议类型Socket protocol types (TCP/UDP/RAW)

#define SOCK_STREAM     1 //流式套接字提供可靠的、面向连接的通信流;它使用TCP 协议,从而保证了数据传输的正确性和顺序性。
#define SOCK_DGRAM      2// 数据报套接字定义了一种无连接的服 ,数据通过相互独立的报文进行传输,是无序的,并且不保证是可靠、无差错的。它使用数据报协议UDP。
#define SOCK_RAW        3// 原始套接字允许对底层协议如IP或ICMP进行直接访问,功能强大但使用较为不便,主要用于一些协议的开发。

protocol
系统使用的协议,其定义如下

#define IPPROTO_IP      0
#define IPPROTO_ICMP    1
#define IPPROTO_TCP     6
#define IPPROTO_UDP     17

可以将 protocol 的值设为 0,系统会自动推演出应该使用什么协议。故一般写0。

返回值

创建错误返回 -1
创建成功返回索引号

2.blind()

接口原型 blind

int
lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)

函数作用:

将sockaddr结构体中描述的一些属性(IP地址、端口号、地址簇)与socket套接字绑定,也叫给套接字命名。

函数入参:

int s :socket()返回文件描述符代表的套接字
const struct sockaddr *name:存放了服务端用于通信的地址和端口。
sockaddr结构体如下所示:

struct sockaddr {
  u8_t sa_len;
  u8_t sa_family;
  char sa_data[14];
};

这个参数的实际结构依赖于网络协议族,然后加上强制转换成sockaddr 类型传入API函数。比如AF_INET就会使用sockaddr_in结构体作为实际结构。
AF_INET6则会使用sockaddr_in6结构体作为实际结构。然后强制转换为const struct sockaddr *name解决编译上的警告报错。

socklen_t namelen
前一参数结构体的长度。

返回值

成功返回0;
出错返回-1;错误原因保存在errno 中。(一般是地址绑定错误、端口已被占用)

3.listen()

接口原型

int
lwip_listen(int s, int backlog)

函数作用:

listen函数使用主动连接套接口变为被连接套接口,使得一个进程可以接受其它进程的请求,从而成为一个服务器进程。

函数入参:

int s :socket()返回文件描述符代表的套接字
backlog:监听队列的长度,当连接数量>这个值,客户端的请求连接会被拒绝

返回值

成功返回0;
出错返回-1;

4.accept()

接口原型

int
lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)

函数作用:

提取出所监听套接字的等待连接队列中第一个连接请求,创建一个新的套接字,并返回指向该套接字的文件描述符。一般用于服务器中阻塞进程,等待客户端连接。

函数入参:

与上方blind()的入参一致这里不再赘述。

返回值

返回指向该套接字的文件描述符。
失败返回:-1;错误原因保存在errno 中。

5.connect()

接口原型

int
lwip_connect(int s, const struct sockaddr *name, socklen_t namelen)

函数作用:

用于建立与指定socket的连接。一般用于客户端,

函数入参:

与上方blind()的入参一致这里不再赘述。

返回值

成功返回:0
失败返回:-1;错误原因保存在errno 中。

6.读 /写read()/write()、recv()/send()

下面是lwip中read()write()函数源码,只是对recvfrom()send()进行了分装
read()函数定义:

int
lwip_read(int s, void *mem, size_t len)
{
  return lwip_recvfrom(s, mem, len, 0, NULL, NULL);
}

write()函数定义:

int
lwip_write(int s, const void *data, size_t size)
{
  return lwip_send(s, data, size, 0);
}

recv()函数定义:

int
lwip_recv(int s, void *mem, size_t len, int flags)
{
  return lwip_recvfrom(s, mem, len, flags, NULL, NULL);
}

send()函数定义:

int
lwip_send(int s, const void *data, size_t size, int flags)

函数入参:

int s:目标连接文件描述符代表的套接字
const void *data:发送数据的指针
void *mem:接收数据的内存地址
int flags:标志位

7.close()

接口原型

int
lwip_close(int s)

函数作用:

关闭socket连接

函数入参:

int s:文件描述符代表的套接字

返回值

成功返回:0
失败返回:-1

先简单介绍一下常见的socket的api函数,还有select()、lwip_shutdown()之后补上。之后还会详细分析一下每个api的源码。加深理解。文中有说错的地方还恳请大佬指出

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐