16. 使用Socket接口编程

您所在的位置:网站首页 lwip应用需要调整堆大小吗 16. 使用Socket接口编程

16. 使用Socket接口编程

2024-05-02 11:17| 来源: 网络整理| 查看: 265

16.3. Socket API¶ 16.3.1. socket()¶

这个函数的功能是向内核申请一个套接字,在本质上该函数其实就是对netconn_new()函数进行了封装,虽然说不是直接调用它,但是主体完成的工作就做了 netconn_new()函数的事情,而且该函数本质是一个宏定义,具体见 代码清单16_2。

代码清单 16‑2 socket()

#define socket(domain,type,protocol) \ lwip_socket(domain,type,protocol) int lwip_socket(int domain, int type, int protocol); #define AF_INET 2 /* Socket服务类型 (TCP/UDP/RAW) */ #define SOCK_STREAM 1 #define SOCK_DGRAM 2 #define SOCK_RAW 3

参数domain表示该套接字使用的协议簇,对于TCP/IP协议来说,该值始终为AF_INET。

参数type指定了套接字使用的服务类型,可能的类型有3种:

SOCK_STREAM:提供可靠的(即能保证数据正确传送到对方)面向连接的Socket服务,多用于资料(如文件)传输,如TCP协议。

SOCK_DGRAM:是提供无保障的面向消息的Socket 服务,主要用于在网络上发广播信息,如UDP协议,提供无连接不可靠的数据报交付服务。

SOCK_RAW:表示原始套接字,它允许应用程序访问网络层的原始数据包,这个套接字用得比较少,暂时不用理会它。

参数protocol指定了套接字使用的协议,在IPv4中,只有TCP协议提供SOCK_STREAM这种可靠的服务,只有UDP协议提供SOCK_DGRAM服务,对于这两种协议,protocol的值均为0。

当申请套接字成功的时候,该函数返回一个int类型的值,也是Socket描述符,用户通过这个值可以索引到一个Socket连接结构——lwip_sock,当申请套接字失败时,该函数返回-1。

16.3.2. bind()¶

该函数的功能与netconn_bind()函数是一样的,用于服务器端绑定套接字与网卡信息, 实际上就是对netconn_bind()函数进行了封装,可以将一个申请成功的套接字与网卡信息进行绑定, 其函数原型具体见 代码清单16_3

代码清单 16‑3 bind()

#define bind(s,name,namelen) \ lwip_bind(s,name,namelen) int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen);

参数s是表示要绑定的Socket套接字,注意了,这个套机字必须是从socket()函数中返回的索引,否则将无法完成绑定操作。

参数name是一个指向sockaddr结构体的指针,其中包含了网卡的IP地址、端口号等重要的信息,LwIP为了更好描述这些信息,使用了sockaddr结构体来定义了必要的信息的字段,它常被用于Socket API的很多函数中,我们在使用bind()的时候,只需要直接填写相关字段即可,sockaddr结构体具体见 代码清单16_4。

参数namelen指定了name结构体的长度。

代码清单 16‑4sockaddr结构体

struct sockaddr { u8_t sa_len; /* 长度 */ sa_family_t sa_family; /* 协议簇 */ char sa_data[14]; /* 连续的14字节信息 */ };

咋一看这个结构体,好像没啥信息要我们填写的,确实也是这样子,我们需要填写的IP地址与端口号等信息,都在sa_data连续的14字节信息里面,但是这个数据对我们不友好,因此LwIP还定义了另一个对开发者更加友好的结构体——sockaddr_in,我们一般也是用这个结构体,具体见 代码清单16_5

代码清单 16‑5sockaddr_in结构体

struct sockaddr_in { u8_t sin_len; sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; #define SIN_ZERO_LEN 8 char sin_zero[SIN_ZERO_LEN]; };

这个结构体的前两个字段是与sockaddr结构体的前两个字段一致,而剩下的字段就是sa_data连续的14字节信息里面的内容,只不过从新定义了成员变量而已,sin_port字段是我们需要填写的端口号信息,sin_addr字段是我们需要填写的IP地址信息,剩下sin_zero 区域的8字节保留未用。

那么这个函数应该怎么使用呢?具体见 代码清单16_6,

代码清单 16‑6 bind()函数的使用方法

sock = socket(AF_INET, SOCK_STREAM, 0); if (sock


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3