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日

相关文章

  • java8新特性之stream的collect实战教程

    Java8新特性之Stream的Collect实战教程 前言 在 Java 8 的新特性中,有一个非常强大的用于流式操作的 API,那便是 Stream。在 Stream 中提供了非常好用且灵活的方法,对于集合中数据的操作具备了强大的支持。而其中 collect() 方法在实际的应用中尤为常见,在这篇文章中,我们将介绍 Stream 中的 collect()…

    C 2023年5月23日
    00
  • C语言执行时,程序控制台输出窗口 一闪而过问题及解决

    在使用C语言编写程序并在控制台中运行时,有时会遇到程序执行后控制台窗口一闪而过的情况,使得无法看到程序的输出结果。这种情况通常是由于程序执行完毕后,系统自动关闭控制台窗口所导致的。解决这个问题,可以采用以下两种方法。 方法一:调用“暂停”命令 使用该方法需要在程序执行完毕后,调用系统命令行窗口的“暂停”命令,从而保证程序执行结果能够停留在窗口中,直到用户手动…

    C 2023年5月23日
    00
  • 用纯C语言实现贪吃蛇游戏

    用C语言实现贪吃蛇游戏 1. 设计思路 贪吃蛇游戏是一个老少皆宜的经典游戏,其基本原理是通过操纵方向键控制一条蛇在一个固定大小的游戏窗口中移动,蛇的长度不断增长,直至最后碰到游戏窗口边缘或者自身。游戏的难度在于蛇不可以穿墙而且一碰到边缘或自身就死亡。下面我们讲一下用C语言实现贪吃蛇游戏的完整攻略。 1.1 思路概述 程序主要分为两个部分:逻辑实现和界面实现。…

    C 2023年5月23日
    00
  • C语言单链表实现学生管理系统

    C语言单链表实现学生管理系统 简介 单链表是一种线性结构,由多个节点组成。每个节点包含两个域,一个是数据域,用于存储数据,另一个是指针域,用于指向下一个节点。 学生管理系统是一个常见的应用程序,可以用于记录和管理学生信息。C语言单链表可以用来实现学生管理系统,通过链表数据结构的操作,实现学生信息的增删改查等功能。 程序框架 定义学生结构体 typedef s…

    C 2023年5月23日
    00
  • C++中的常对象与常对象成员详解

    C++中的常对象与常对象成员详解 在C++中存在常对象和常对象成员,它们都有一个共同点:都不允许在对象的生命周期内被修改。下面我们详细讲解常对象和常对象成员的定义、声明、初始化及其特点。 常对象 定义 常对象是指一个对象在它被创建后就无法被修改。在C++中,我们可以通过在对象类型前面加上const关键字来定义常对象。例如: const int a = 10;…

    C 2023年5月22日
    00
  • C语言实现词法分析器

    C语言实现词法分析器主要涉及以下步骤: 建立词法规则集合 读取输入源代码文件 对源代码进行字符的预处理和错误检查 生成Token序列 下面我们来对这些步骤进行详细说明。 建立词法规则集合 在词法分析器中,我们需要使用正则表达式或者其他方式建立词法规则集合。规则集合里包含了程序中的关键字、符号等信息,可以通过与源代码进行匹配,找出其中的单词(Token)。 例…

    C 2023年5月23日
    00
  • win11错误代码0xC004F074无法激活修复的解决办法

    Win11错误代码0xC004F074无法激活修复的解决办法 如果在Win11安装或更新后出现错误代码0xC004F074无法激活的情况,你可以按照以下的步骤来解决。 步骤一:使用管理员权限打开命令提示符 在“开始”菜单中右键单击“命令提示符”(或“快速访问菜单”中的“命令提示符”),然后选择“以管理员身份运行”。 如果你看到一个用户控制弹窗,请选择“是”来…

    C 2023年5月24日
    00
  • JavaScript中的连续赋值问题实例分析

    当我们在 JavaScript 语言中使用连续赋值时,需要注意一些问题。本文将介绍这些问题,并通过实例进行详细分析,帮助开发者更好地理解。 什么是连续赋值? 在 JavaScript 语言中,变量可以连续被赋值。连续赋值是指将多个值赋给多个变量的过程。例如: let a = 1, b = 2, c = 3; a = b = c = 4; console.lo…

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