C++ TCP网络编程详细讲解

C++ TCP网络编程详细讲解

简介

TCP网络编程是指基于传输控制协议(TCP)实现的网络通信,其主要特点是数据传输稳定可靠,适用于对数据传输要求较高的应用场景。在C++中,我们可以使用一些网络编程库(如Boost.Asio、Winsock等)来实现TCP网络编程。

步骤

1. 创建socket

在进行TCP网络编程时,我们需要先创建一个socket,通过该socket来进行数据传输。在C++中,我们可以使用以下代码来创建一个socket:

SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sock == INVALID_SOCKET) {
    // 创建socket失败
    return;
}

其中,AF_INET表示使用IPv4协议,SOCK_STREAM表示创建流式socket(即TCP),IPPROTO_TCP表示使用TCP协议。

2. 绑定IP地址和端口号

在进行TCP网络编程时,我们需要将socket与一个本地IP地址和端口号进行绑定。如果是服务端程序,通常我们可以指定监听IP地址为0.0.0.0,表示监听所有可用的网络接口;如果是客户端程序,则可以将IP地址置为空字符串。

sockaddr_in addr = {0};
addr.sin_family = AF_INET;  // 使用IPv4协议
addr.sin_port = htons(8080);  // 绑定的端口号
addr.sin_addr.s_addr = INADDR_ANY;  // 使用任意可用的IP地址
bind(sock, (sockaddr*)&addr, sizeof(addr));

3. 连接远程服务器

在进行TCP网络编程时,客户端需要先与服务器进行连接,才能发送和接收数据。我们可以使用以下代码使客户端与远程服务器进行连接:

sockaddr_in addr = {0};
addr.sin_family = AF_INET;  // 使用IPv4协议
addr.sin_port = htons(8080);  // 远程服务器端口号
inet_pton(AF_INET, "192.168.0.1", &addr.sin_addr);  // 远程服务器IP地址
connect(sock, (sockaddr*)&addr, sizeof(addr));

4. 监听连接

在进行TCP网络编程时,服务端需要监听客户端的连接请求,我们可以使用以下代码使服务端开始监听:

listen(sock, SOMAXCONN);  // 最大连接数

SOMAXCONN表示同时连接到服务端的最大客户端数量。

5. 接受连接

在进行TCP网络编程时,服务端需要接受客户端的连接请求,并创建一个新的socket与该客户端通信。我们可以使用以下代码接受连接请求:

sockaddr_in client_addr = {0};
int client_addr_len = sizeof(client_addr);
SOCKET client_sock = accept(sock, (sockaddr*)&client_addr, &client_addr_len);

6. 发送和接收数据

在进行TCP网络编程时,我们可以使用send函数向对端发送数据,使用recv函数从对端接收数据。以下代码展示了如何从服务端接收客户端发送的数据:

int recv_len = recv(client_sock, buf, buf_len, 0);
if(recv_len == SOCKET_ERROR) {
    // 接收数据失败
    return;
}

以下代码展示了如何向客户端发送数据:

// 假设待发送的数据存储在buf中
int send_len = send(client_sock, buf, buf_len, 0);
if(send_len == SOCKET_ERROR) {
    // 发送数据失败
    return;
}

示例

示例一:服务端

以下代码展示了如何创建一个服务端程序,该程序监听8080端口,等待客户端连接并接收客户端发送的数据:

#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;

int main() {
    WSADATA wsaData;
    if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        cout << "WSAStartup failed." << endl;
        return 0;
    }

    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sock == INVALID_SOCKET) {
        cout << "socket failed." << endl;
        return 0;
    }

    sockaddr_in addr = { 0 };
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    addr.sin_addr.s_addr = INADDR_ANY;
    if(bind(sock, (sockaddr*)&addr, sizeof(addr)) != 0) {
        cout << "bind failed." << endl;
        return 0;
    }

    listen(sock, SOMAXCONN);

    sockaddr_in client_addr = { 0 };
    int client_addr_len = sizeof(client_addr);
    SOCKET client_sock = accept(sock, (sockaddr*)&client_addr, &client_addr_len);
    if(client_sock == INVALID_SOCKET) {
        cout << "accept failed." << endl;
        return 0;
    }

    char buf[1024] = { 0 };
    int recv_len = recv(client_sock, buf, sizeof(buf), 0);
    if(recv_len == SOCKET_ERROR) {
        cout << "recv failed." << endl;
        return 0;
    }
    cout << "Received data: " << buf << endl;

    closesocket(client_sock);
    closesocket(sock);

    WSACleanup();

    return 0;
}

示例二:客户端

以下代码展示了如何创建一个客户端程序,该程序连接到服务端IP为192.168.0.1,端口号为8080,并向服务端发送数据"Hello, World!":

#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;

int main() {
    WSADATA wsaData;
    if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        cout << "WSAStartup failed." << endl;
        return 0;
    }

    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sock == INVALID_SOCKET) {
        cout << "socket failed." << endl;
        return 0;
    }

    sockaddr_in addr = { 0 };
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    inet_pton(AF_INET, "192.168.0.1", &addr.sin_addr);
    if(connect(sock, (sockaddr*)&addr, sizeof(addr)) != 0) {
        cout << "connect failed." << endl;
        return 0;
    }

    const char* buf = "Hello, World!";
    int buf_len = strlen(buf);
    int send_len = send(sock, buf, buf_len, 0);
    if(send_len == SOCKET_ERROR) {
        cout << "send failed." << endl;
        return 0;
    }

    closesocket(sock);

    WSACleanup();

    return 0;
}

总结

本文介绍了C++ TCP网络编程的基本步骤,包括创建socket、绑定IP地址和端口号、连接远程服务器、监听连接、接受连接、发送和接收数据等。同时,本文提供了两条示例,帮助读者更好地理解TCP网络编程的实现细节。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++ TCP网络编程详细讲解 - Python技术站

(0)
上一篇 2023年5月24日
下一篇 2023年5月24日

相关文章

  • C++类成员初始化的三种方式

    C++类成员初始化是一种在创建对象时给类成员变量赋值的方式,它通常发生在构造函数中。在C++中,类成员初始化方式有三种:默认构造函数初始化、成员初始化列表和构造函数初始化。下面我们将分别详细介绍这三种方式。 默认构造函数初始化 对于没有定义构造函数的类,C++编译器会为其自动生成默认构造函数,在这种情况下,编译器会使用默认值为成员变量赋初值。例如,下面的代码…

    C 2023年5月22日
    00
  • C++分析讲解类的静态成员函数如何使用

    当我们需要为一个类定义一个在全局范围内使用的函数时,我们可以使用类的静态成员函数。静态成员函数只能访问静态成员变量,它们没有this指针,所以无法访问非静态成员变量、函数和成员变量的this指针。在C++中,静态成员函数前面加上static关键字即可将其设置为静态成员函数。 如何声明定义静态成员函数 我们可以将静态成员函数声明为public、protecte…

    C 2023年5月23日
    00
  • C++实现strcpy函数实例

    C++实现strcpy函数实例 什么是strcpy函数 strcpy是C/C++中非常常用的字符串复制函数,用于将一个字符串复制到另一个字符串中。其函数原型如下: char* strcpy(char* dest, const char* src); 其中,dest是目标字符串指针,src是源字符串指针。 实现strcpy函数的步骤 计算源字符串的长度n 申请…

    C 2023年5月23日
    00
  • C语言中程序环境和预处理的详细图文讲解

    针对“C语言中程序环境和预处理的详细图文讲解”这一主题,我会为你提供一份完整攻略。本攻略主要分两部分:程序环境和预处理。下面就分别进行详细讲解。 程序环境 什么是程序环境? 程序环境指的是程序执行的环境,包括操作系统、硬件设备等因素。C语言的程序需要在特定的环境下才能执行。 程序的执行过程 当程序运行时,它需要在内存中占用一定的空间。程序在执行过程中分为以下…

    C 2023年5月23日
    00
  • 详解ubuntu安装CMake的几种方式

    下面我将详细讲解一下“详解Ubuntu安装CMake的几种方式”完整攻略,过程中还会有两条示例说明。 简介 CMake是一个跨平台的开源构建系统,用于生成跨平台的软件。在Ubuntu操作系统中使用CMake的话,需要安装CMake。下面将详细讲解Ubuntu安装CMake的几种方式。 方式一:通过apt-get命令安装 sudo apt-get update…

    C 2023年5月23日
    00
  • JSP学习之Java Web中的安全控制实例详解

    JSP学习之Java Web中的安全控制实例详解,是一篇讲解Java Web项目中应用安全控制的文章。在Web项目中,安全控制是非常重要的一环。本文将详细介绍实现Java Web应用中的安全控制的过程。 什么是安全控制 首先,我们需要了解什么是安全控制。在Web应用中,安全控制是指对应用程序进行访问限制以保证应用的安全性。安全控制可以是身份验证、授权、审计等…

    C 2023年5月23日
    00
  • 使用JSONObject生成和解析json的方法

    使用JSONObject生成和解析json的方法,是在Java开发中经常需要用到的一种技术。下面是一份关于该技术的攻略: 生成Json 在Java开发中,我们可以通过使用JSONObject类来生成JSON对象。 首先需要导入以下依赖: <dependency> <groupId>org.json</groupId> &l…

    C 2023年5月23日
    00
  • oracle 数据库隔离级别学习

    Oracle 数据库隔离级别学习 简介 数据库隔离级别是指在多个并发事务之间的数据隔离程度。Oracle 数据库中提供了四种不同隔离级别(未提交读取、已提交读取、可重复读取、串行化),每种级别各自具有不同的数据隔离程度和并发性能。这篇文章将为您详细介绍这四种隔离级别以及如何选择适合您的数据库场景的级别。 隔离级别 未提交读取 未提交读取是最低级别的隔离级别,…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部