C/C++ 套接字编程

2025年3月17日 | 阅读 8 分钟

当今世界,计算机网络在数据传输领域发挥着重要作用。这是每个程序员都应该了解的学科。在计算机网络中,套接字编程是编程世界中最重要的主题之一。在本主题中,我们将讨论套接字编程以及在 C++ 中实现的套接字编程的不同方法。

在 C++ 中,套接字编程是一种将两个或多个节点连接在一起的方法,以便节点能够共享数据而不会丢失数据。在此连接中,一个节点监听一个连接到特定 IP 地址的端口。当客户端到达服务器时,服务器会创建套接字侦听器。

什么是套接字?

让我们通过现实生活中的例子来理解套接字。套接字是一种提供两个设备之间连接的媒介。套接字可以是手机充电器,它提供套接字和手机之间的连接,或者手机和笔记本电脑之间的连接。借助套接字,不同的应用程序通过不同的端口连接到本地网络。每次创建套接字时,服务器都会指定程序,该程序会指定套接字和域地址。

套接字是一种用于在不同进程之间交换数据的机制。这里的进程要么存在于不同设备上,要么存在于同一设备上,并且它们通过网络连接。一旦套接字连接建立,数据就可以双向发送,并一直持续到其中一个端点关闭连接。

Socket Programming in C/C++

客户端-服务器通信过程

建立客户端-服务器通信需要遵循一些过程。它们如下。

  1. 套接字 (Socket): 借助套接字,我们可以创建新的通信。
  2. 绑定 (Bind): 借助此功能,我们可以将本地地址绑定到套接字。
  3. 监听 (Listen): 借助此功能,我们可以接受连接。
  4. 接受 (Accept): 借助此功能,我们可以阻止传入连接,直到请求到达。
  5. 连接 (Connect): 借助此功能,我们可以尝试建立连接。
  6. 发送 (Send): 借助此功能,我们可以通过网络发送数据。
  7. 接收 (Receive): 借助此功能,我们可以通过网络接收数据。
  8. 关闭 (Close): 借助此功能,我们可以从网络释放连接。

服务器套接字创建阶段

有一些阶段可以帮助我们为服务器创建套接字。它们如下。

  1. int socketcr: Socket(domain, type, protocol)
  2. Socketcr: 它是一个整数类型,类似于文件句柄。
  3. Domain (域): 它是通信域,是整数类型。
  4. Type (类型): 它是通信类型。
  5. SOCK_DGRAM: 它是 UDP 的一种类型,不可靠且无连接。
  6. Protocol (协议): 它用于为 IP 地址分配协议值,通常为 0。协议值类似于 IP 报头协议字段中出现的值。

什么是连接?

连接是一种两个机器之间的关系,其中两个软件相互了解。这两个软件知道如何建立连接;换句话说,我们可以说这两个软件知道如何在网络上传输比特。套接字连接意味着两台机器应该知道彼此的所有信息,例如电话号码、IP 地址和 TCP 端口。

套接字是一种类似于文件的对象,它允许程序接受传入连接并允许它们发送或接收传入连接。此外,它是一种分配给服务器进程的资源。

服务器可以通过 socket() 创建套接字。此套接字不能与其他任何处理器共享。

  • Setsockopt: 借助 Setsockopt,我们可以操作由套接字文件描述符引用的各种套接字选项。此过程是完全可选的。借助 Setsockopt,我们可以重用客户端和服务器的端口和地址。当服务器出现“地址已在使用中”错误时,我们可以借助 Setsockopt 来防止它。
  • Bind: 我们可以借助 bind 函数将套接字与地址和端口绑定。此操作在创建套接字之后完成。例如,如果我们尝试将服务器绑定到本地主机,则使用 INADDR_ANY 来定义服务器的 IP 地址。
  • Listen: 我们可以使用 listening () 函数创建一个连接模式套接字。连接模式套接字的示例是 SOCK_STREAM。这可以通过套接字参数定义。它用于接受传入连接,为传入连接执行队列操作,并执行传入连接的队列。当传入连接请求服务器进行确认时,套接字将被置于被动模式。服务器的 backlog 参数是指它一次不允许超过一个连接到服务器。如果出现某些传入连接且队列已满,服务器将指示“ECONNREFUSED”错误。借助 listen(),传入连接将保持挂起状态,当队列为空时,它将调用所有传入连接到服务器。
  • Accept: 借助 accept() 系统调用,我们可以创建基于连接的套接字。一些基于连接的套接字是 SOCK_STREAM 和 SOCK_SEQPACKET。它提取所有首先到达的传入连接,并允许它们的请求到达服务器。新连接的列表无法使用另一个参数进行监听以创建新套接字。

客户端阶段

  1. 套接字连接 (Socket connection): 它与服务器的创建方法完全相同。
  2. Connect: 我们可以使用 connect() 系统调用发起与套接字的连接。如果套接字的参数是 SOCK_DGRAM 类型,则我们可以使用 connect() 将数据报定义为永久的。如果套接字是 SOCK_STREAM 类型,那么我们可以尝试为服务器建立另一个连接。借助 connect() 函数,我们还可以为外部关联创建连接。如果套接字未绑定,则系统会分配一个唯一的本地关联值。当系统成功调用完成后,套接字就可以发送或接收任何类型的数据。
  3. Send/Receive (发送/接收): send() 和 recv() 函数可以执行以下操作。
  • 数据可以在其上进行通信的套接字。
  • 存储缓冲区可以存储有关地址的数据,例如 addr_of_data 和 addr_of_buffer。
  • 它处理缓冲区的大小,例如 len_of_data 和 len_of_buffer。
  • 它处理标志,该标志指示数据如何发送。

在套接字中建立连接的步骤

它建立了不同客户端和服务器之间的连接。但客户端和服务器都可以处理套接字连接。每个进程都必须为其自己的套接字建立连接。

在客户端建立套接字涉及的步骤如下

  • 它使用 socket() 系统调用创建一个套接字。
  • 然后我们必须使用 system() 调用连接到服务器的套接字地址。
  • 然后我们必须发送和接收数据。我们可以通过多种方式进行。我们可以使用 read() 和 write() 函数。

在服务器端建立套接字涉及的步骤如下

  • 它首先使用 socket() 系统调用创建一个套接字。
  • 然后它使用 bind() 系统调用将套接字绑定到一个地址。地址包括服务器套接字在主机上的端口号。
  • 然后它使用 listening () 系统调用监听连接。
  • 然后服务器使用 accept() 系统调用接受传入连接。它还会阻止所有传入命令,直到客户端连接到服务器。
  • 然后开始发送和接收数据的过程。

在不使用多线程的情况下连接多个客户端

有很多例子说明单个用户如何与服务器连接。在当今的编程世界中,多个用户通过不同的套接字连接到服务器。

有多种方法可以实现这一点。其中一种是多线程。借助多线程,我们可以实现这一点。我们可以通过 select() 函数实现多线程进程。

示例

客户端代码

编译

Socket Programming in C/C++

输出

Socket Programming in C/C++

套接字编程的用途

套接字程序用于在各种进程之间进行通信,通常运行在不同的系统上。它主要用于创建客户端-服务器环境。本文介绍了用于创建服务器和客户端程序的各种函数以及一个示例程序。

在示例中,客户端程序将文件名发送给服务器,服务器将文件的内容发送回客户端。套接字编程通常涉及 TCP/UDP 等基本通信协议以及 ICMP 等原始套接字。与 HTTP/DHCP/SMTP 等底层协议相比,这些协议的通信开销很小。

客户端和服务器之间的一些基本数据通信是

  • 文件传输:发送文件名并获取文件。
  • 网页:发送 URL 并获取页面。
  • 回显:发送消息并将其收回。

缺点

  • C++ 只能与请求的机器建立通信,而不能与网络上的任何其他机器建立通信。
  • 套接字只允许发送原始数据。这意味着客户端和服务器需要解释数据的机制。

下一个主题C++ 多线程及示例