持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
本来已经打算不再参加任何日更的活动了,因为日更真的特别消耗创作热情。
但是最近正好在看一本网络编程的入门小册,本就有新将其翻译成中文的想法,甚至发了邮件给作者,也得到了作者的鼓励。
于是心里想着正好趁机参加这个活动吧,为了掘金日更的礼物, 能倒逼自己赶紧完成翻译,不至于半途而废,便有了本系列。
- 英文小册原文地址:beej.us/guide/bgnet…
- 作者:Beej
- 中文翻译地址:www.chanmufeng.com/posts/netwo…
现将目录贴下:
- 什么是socket
- 两种Socket
- 漫谈网络
- IP地址、struct以及地址转换
- IP地址,IPv4和IPv6
- 字节序
- struct结构
- 再谈IP地址
- 从IPv4迁移到IPv6
- IP地址,IPv4和IPv6
- 字节序
- struct结构
- 再谈IP地址
- System call 或 Bust
- getaddrinfo()—准备开始!
- socket()—拿到文件描述符!
- bind()—我在监听哪个端口?
- connect()—嘿,你好啊!
- listen()—会有人联系我吗?
- accept()—感谢呼叫3490端口
- send() and recv()—跟我唠唠吧,宝儿!
- sendto() and recvfrom()—用DGRAM风格跟我说话
- close() and shutdown()—滚犊子!
- getpeername()—你哪位?
- gethostname()—我是谁?
- Client-Server基础
- 一个简单的流服务器
- 一个简单的流客户端
- Datagram Sockets
- 技术进阶
- Blocking—何谓阻塞?
- poll()—同步的I/O多路复用
- select()—老古董的同步I/O多路复用
- 数据只传了一部分怎么办?
- Serialization-如何封装数据?
- 数据封装
- 广播数据包-大声说「Hello,World」
你一直在听别人谈论"sockets
",或许你也想搞明白这到底是个什么东西。
好吧,它们其实就是:「使用标准的Unix file descriptors
(Unix文件描述符)与其他程序进行沟通的一种方式」。
啥玩意儿?
如果接触过Unix,你一定听说过「Unix一切皆文件」的说法。
一定意义上来说,这个说法并没有什么错。因为Unix程序做任何I/O操作,都是通过对file descriptor
(文件描述符)进行读写来实现的。
文件描述符其实就是一个整数罢了,只是这个整数关联了一个打开的文件。这里的文件可以是一个网络连接
、FIFO
、pipe
(管道)、terminal
(终端)、磁盘中的实际文件等等。
我之前写过一篇《什么是文件描述符》的文章,感兴趣的话大家可以看一下
所以「Unix一切皆文件」的说法并非是夸大其词。
不管你信不信,当你想通过网络和另一个程序进行通讯时,你必须通过file descriptor
来实现。
那么怎么获取到和网络通信相关的这个file descriptor
呢?
我们可以使用socket()
函数,这个函数会返回一个socket descriptor
(socket
都是一个文件,socket descriptor
自然就是一个file descriptor
了)。然后你就可以通过这个socket descriptor
,使用send()
和recv()
这两个函数与其他程序进行通信了。
如果你用C语言对文件进行过读写操作,你就知道read()/write()
这一组函数同样可以作用于file descriptor
,为什么不用这一套函数呢?
当然完全可以用!只不过send()/recv()
在数据传输方面比read/write()
提供了更多可选项罢了。
其实sockets
的种类有很多,比如:
- DARPA Internet addresses,简称
Internet Sockets
Internet Sockets是我们接下来讲解的重点,因为它是我们目前进行网络通信时使用最多的一种Socket.
DARPA表示国防部高级研究计划局
- path names on a local node,简称
Unix Sockets
这个英文翻译成中文也不是很直观,所以干脆不翻译了,Unix Sockets
有时候被称为Unix域套接字
。简而言之,Unix Sockets
是用于同一台主机中进程间通讯的一种方式。
使用过MySQL的朋友很可能见过下面这个错误:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
这个错误说明MySQL Client和MySQL Server运行在同一台主机上,并且两个进程通过/var/lib/mysql/mysql.sock
这个文件进行通信,这个文件就是Unix域套接字文件,不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序列号应答等等网络通信细节。
你可能会问,MySQL Client和MySQL Server之间为什么不通过本地网络进行通信呢?
这和你对MySQL的配置有关系。
如果你指定的MySQL主机名为localhost
,或者你指定了--protocl=socket
的启动参数,那么Client和Server之间就会通过Unix域套接字
进行通信了。
相反,如果你指定的MySQL主机名是127.0.0.1
,那么Client和Server之间就会通过Internet Sockets
进行通信了。