第 11 天:我找到了学习 socket 的正确姿势
在 这节课程中,我们聊了聊 socket,但是没有写代码,不写代码这不是耍流氓吗!今天把代码补上,以前我一直没找到好的资料,直到某天我找到了一本「神书」,看完后,我我理解了 socket。书中详细介绍了 socket 各个 API 的使用、通过 socket 创建 TCP 与 UDP、TCP 与 UDP 的区别,并通过简单的 demo 来实践,书中有大量的图,这些图比我画的好多了。
操作系统都会提供 socket 接口供应用程序直接进行数据传输。比如 iOS 中 #include <sys/socket.h> 通过 C 的接口描述如何使用 socket 接口。下一节内容我们将使用这些 API 创建 HTTP Server。
我截取了书中部分图,图画的非常精美,如果你想深入学习 socket,建议阅读本书(很薄的一本):
socket 各个 API 主要有下面这些:
1.创建 Socket
int socket(int, int, int);
参数2:socket 类型,有以下几个值:SOCK_STREAM,流式的 socket,比如 TCP;SOCK_DGRAM,datagram socket 数据报 socket,比如 UDP;SOCK_RAW,原始套接字;
参数3:采用的协议,IPPROTO_TCP,TCP协议;IPPROTO_UDP,UDP协议;
2. bind
int bind(int, const struct sockaddr *, socklen_t);
a、返回值为 -1 时错误;
参数1:创建 socket 时的 id;
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;
};
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;
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)
本文说明了 socket 的接口使用。下节内容我们通过今天介绍的 socket 接口 实现一个 HTTP server。大家加油!!!直接打卡吧!!!