在 第 5 天:以农村故事说说我对 socket 的理解 这节课程中,我们聊了聊 socket,但是没有写代码,不写代码这不是耍流氓吗!今天把代码补上,以前我一直没找到好的资料,直到某天我找到了一本「神书」,看完后,我我理解了 socket。书中详细介绍了 socket 各个 API 的使用、通过 socket 创建 TCP 与 UDP、TCP 与 UDP 的区别,并通过简单的 demo 来实践,书中有大量的图,这些图比我画的好多了。
操作系统都会提供 socket 接口供应用程序直接进行数据传输。比如 iOS 中 #include <sys/socket.h> 通过 C 的接口描述如何使用 socket 接口。下一节内容我们将使用这些 API 创建 HTTP Server。
我截取了书中部分图,图画的非常精美,如果你想深入学习 socket,建议阅读本书(很薄的一本):
你可以在公众号对话框输入「socket」可以获取本书 pdf。
socket 各个 API 主要有下面这些:
1.创建 Socket
int socket(int, int, int);
a: 返回值可以理解为一个 id,用来标识一个 socket,如果返回 -1,说明有错误;
参数1:AF_INET:网络通信,UDP、TCP等网络协议,AF_UNIX:本地通信,比如文件地址;
参数2:socket 类型,有以下几个值:SOCK_STREAM,流式的 socket,比如 TCP;SOCK_DGRAM,datagram socket 数据报 socket,比如 UDP;SOCK_RAW,原始套接字;
参数3:采用的协议,IPPROTO_TCP,TCP协议;IPPROTO_UDP,UDP协议;
2. bind
给 socket 绑定一个地址和端口。
int bind(int, const struct sockaddr *, socklen_t);
a、返回值为 -1 时错误;
参数1:创建 socket 时的 id;
参数2:socket 地址;
struct sockaddr_in { __uint8_t sin_len; sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; char sin_zero[8];}
struct in_addr { in_addr_t s_addr;};
参数3:地址的 size;
bind 使用的例子:
int sockid;struct sockaddr_in addrport;sockid = socket(PF_INET, SOCK_STREAM, 0);addrport.sin_family = AF_INET;addrport.sin_port = htons(5100);addrport.sin_addr.s_addr = htonl(INADDR_ANY);if(bind(sockid, (struct sockaddr *) &addrport, sizeof(addrport))!= -1) { ...}
3. listen
绑定地址后,需要进行监听。
int listen(int, int);
a、返回值为 -1 时错误;
参数1:创建 socket 时的 id;
参数2:socket 地址;
4. accept
通过这个获取客户端连接的 socket。
int accept(int, struct sockaddr *r, socklen_t *t)
5. connect
客户端通过这个与 server 建立连接。
int connect(int, const struct sockaddr *, socklen_t)
6.write
向 socket 发送数据。
ssize_t write(int __fd, const void * __buf, size_t __nbyte)
7.read
从 socket 中读取数据。
ssize_t read(int, void *, size_t)
8.close
关闭 socket 的连接,参数为 socket 的 id。
int close(int)
TCP 和 UDP 的使用如图所示:
总结
本文说明了 socket 的接口使用。下节内容我们通过今天介绍的 socket 接口 实现一个 HTTP server。大家加油!!!直接打卡吧!!!
推荐阅读: