vlambda博客
学习文章列表

第 11 天:我找到了学习 socket 的正确姿势

  这节课程中,我们聊了聊 socket,但是没有写代码,不写代码这不是耍流氓吗!今天把代码补上,以前我一直没找到好的资料,直到某天我找到了一本「神书」,看完后,我我理解了 socket。书中详细介绍了 socket 各个 API 的使用、通过 socket 创建 TCP 与 UDP、TCP 与 UDP 的区别,并通过简单的 demo 来实践,书中有大量的图,这些图比我画的好多了。

操作系统都会提供 socket 接口供应用程序直接进行数据传输。比如 iOS 中 #include <sys/socket.h> 通过 C 的接口描述如何使用 socket 接口。下一节内容我们将使用这些 API 创建 HTTP Server。

我截取了书中部分图,图画的非常精美,如果你想深入学习 socket,建议阅读本书(很薄的一本):

第 11 天:我找到了学习 socket 的正确姿势

第 11 天:我找到了学习 socket 的正确姿势

socket 各个 API 主要有下面这些:

第 11 天:我找到了学习 socket 的正确姿势

1.创建 Socket

int socket(intintint);
a : 返回值可以理解为一个 id,用来标识一个 socket,如果返回 -1,说明有错误;

参数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(intconst 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(intint);

a、返回值为 -1 时错误;

参数1:创建 socket 时的 id;

4. accept

通过这个获取客户端连接的 socket。

int accept(intstruct sockaddr *r, socklen_t *t)

5. connect

客户端通过这个与 server 建立连接

int connect(intconst struct sockaddr *, socklen_t)

6.write

向 socket 发送数据。

ssize_t write(int __fd, const void * __buf, size_t __nbyte)

7.read

从 socket 中读取数据。

ssize_t read(intvoid *, size_t

8.close

关闭 socket 的连接,参数为 socket 的 id。

int close(int)
TCP 和 UDP 的使用如图所示:

第 11 天:我找到了学习 socket 的正确姿势

总结

本文说明了 socket 的接口使用。下节内容我们通过今天介绍的 socket 接口 实现一个 HTTP server。大家加油!!!直接打卡吧!!!



推荐阅读: