当我们需要理解并实现两台计算机之间的通信时,首先得明白socket技术的作用。简单来说,socket是实现两台计算机通信的基石。
1、socket诞生的原因
为了使两台装有操作系统的机器能够进行通信,它们需要遵循一定的规则。这些规则以协议的形式存在,例如我们常见的http协议。但当我们要在传输层处理这些协议数据时,就需要一个接口,这就是socket的由来。传输层通过socket对外提供服务。毫不夸张地说,socket是计算机通信的基石。
2、服务端和客户端的代码实现
在Linux系统上,我们通常通过特定的代码实现服务端和客户端的通信过程。这部分代码稍显复杂,但提供了具体的网络编程实现方式。先给出代码框架,后续再对每部分功能进行详细解释。
服务端代码(略)
客户端代码(略)
以上代码是基础框架,其中可能存在一些小缺点,我们将在后续的讨论中指出并解决。
3、socket的基本操作
3.1、socket()函数
socket函数用于创建一个socket描述符,它唯一标识一个socket。这个描述符在后续的操作中作为参数出现,通过它来进行一些读写操作。
协议族(family)决定了socket的地址类型。例如,AF_INET决定了使用ipv4地址与端口号的组合。
type指定了socket类型,如SOCK_STREAM用于TCP传输,SOCK_DGRAM用于UDP传输等。
调用socket创建时,返回的socket描述字存在于协议族空间中,但还没有具体的地址。要给它复制一个地址,就需要调用bind()函数。
3.2、bind()函数
bind()函数将一个地址赋给socket。这个地址是根据创建socket时的协议族来确定的,如AF_INET对应的是ipv4或ipv6地址和端口号的组合。
在服务器启动时,通常会绑定一个众所周知的地址和端口号以提供服务;而客户端则由系统自动分配一个端口号和自身的ip地址组合。
3.3、其他函数
其他如listen()、connect()、accept()函数分别用于服务器、客户端连接和接受客户端连接。
read()、write()等函数则用于网络I/O操作,实现不同进程之间的数据通信。
close()函数用于关闭socket描述字,结束网络连接。
注意:close操作只是使相应socket描述字的引用计数减一,只有当引用计数为0时,才会触发TCP客户端向服务器发送终止连接请求。
4、代码的缺陷及改进
上述服务端和客户端的代码是实现socket通信的基础,但若要实现长连接,仅运行一次后就会退出显然不符合实际需求。为了持续发送数据,我们需要对代码进行改进。具体如何改进,需要大家思考并尝试。
通过socket的实现和操作,我们能够理解两台计算机之间通信的基本原理和过程。在实际应用中,还需要根据具体需求进行代码的调整和优化。