C++实现聊天程序

yizhihongxing

C++实现聊天程序攻略

1. 确定通信协议

在实现聊天程序之前,需要确定通信协议。常见的通信协议包括TCP、UDP等,这里我们选择TCP协议。

TCP协议是一种面向连接的协议,它提供可靠的数据传输,适用于需要确保数据完整性的场景,如聊天程序。

2. 编写服务器端和客户端程序

2.1 服务器端程序

服务器端程序需要完成以下任务:

  1. 创建一个socket对象,指定协议为TCP;
  2. 绑定端口号;
  3. 监听连接请求;
  4. 接受连接请求,创建一个新的socket对象与客户端进行通信;
  5. 接收客户端发送的消息;
  6. 将消息发送给其他客户端。

以下是一个简单的服务器端程序示例:

#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
using namespace std;

const int PORT = 8888;   // 服务器端口号
const int MAXCONN = 10;  // 最大连接数

void* handle_client(void* arg) {
    int client_sock = *(int*)arg;
    char buffer[1024] = {0};
    while (true) {
        int len = read(client_sock, buffer, sizeof(buffer));
        if (len == 0) break;
        cout << "收到客户端消息: " << buffer << endl;
        memset(buffer, 0, sizeof(buffer));
    }
    close(client_sock);
    return NULL;
}

int main() {
    int server_sock, client_sock;
    struct sockaddr_in server_addr, client_addr;
    pthread_t thread_id;

    // 创建socket对象
    if ((server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
        cout << "创建socket对象失败" << endl;
        return -1;
    }
    // 绑定端口号
    memset(&server_addr, 0, sizeof(server_addr));  
    server_addr.sin_family = AF_INET;  
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);  
    server_addr.sin_port = htons(PORT);  
    if (bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        cout << "绑定端口号失败" << endl;
        return -1;
    }
    // 监听连接请求
    if (listen(server_sock, MAXCONN) < 0) {
        cout << "监听连接请求失败" << endl;
        return -1;
    }
    while (true) {
        socklen_t client_len = sizeof(client_addr);
        // 接受连接请求,创建新的socket对象
        if ((client_sock = accept(server_sock, (struct sockaddr*)&client_addr, &client_len)) < 0) {
            cout << "接受连接请求失败" << endl;
            continue;
        }
        cout << "客户端连接成功,IP地址为:" << inet_ntoa(client_addr.sin_addr) << endl;
        // 创建新线程处理客户端消息
        if (pthread_create(&thread_id, NULL, handle_client, (void*)&client_sock) < 0) {
            cout << "创建线程失败" << endl;
            return -1;
        }
    }
    close(server_sock);
    return 0;
}

2.2 客户端程序

客户端程序需要完成以下任务:

  1. 创建一个socket对象,指定协议为TCP;
  2. 连接服务器端;
  3. 发送消息给服务器端;
  4. 接收服务器端发送的消息。

以下是一个简单的客户端程序示例:

#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;

const char* SERVER_IP = "127.0.0.1";  // 服务器IP地址
const int PORT = 8888;               // 服务器端口号

int main() {
    int client_sock;
    struct sockaddr_in server_addr;

    // 创建socket对象
    if ((client_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
        cout << "创建socket对象失败" << endl;
        return -1;
    }
    // 连接服务器端
    memset(&server_addr, 0, sizeof(server_addr));  
    server_addr.sin_family = AF_INET;  
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);  
    server_addr.sin_port = htons(PORT);  
    if (connect(client_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        cout << "连接服务器端失败" << endl;
        return -1;
    }
    // 发送消息给服务器端
    string message;
    while (getline(cin, message)) {
        send(client_sock, message.c_str(), message.size(), 0);
        if (message == "quit") break;
    }
    close(client_sock);
    return 0;
}

3. 示例说明

3.1 示例1

此示例展示了如何在服务器端接收客户端发来的消息,并将消息打印到终端上。

启动服务器端程序后,在终端输入以下命令:

$ nc 127.0.0.1 8888

此时,nc命令会连接服务器端。在终端输入消息,服务器端会接收到并在终端上打印该消息。

3.2 示例2

此示例展示了如何在客户端向服务器端发送消息,并在服务器端接收到该消息后,将消息发送给其他客户端。

启动服务器端程序后,在终端输入以下命令:

$ nc 127.0.0.1 8888

此时,nc命令会连接服务器端。分别打开两个终端,分别输入以下命令:

$ ./client.out

这时,在一个终端中输入消息,消息会被发送给服务器端,服务器端会将该消息发送给其他客户端,并在每个客户端上打印该消息。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++实现聊天程序 - Python技术站

(1)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C语言实现单元测试的示例详解

    首先,在文章标题处应添加一级标题C语言实现单元测试的示例详解。 接下来,对于这篇文章,需要进行以下内容的详细讲解: 1. 单元测试的概念及其意义 在这一部分,应该阐述什么是单元测试,以及它的意义和重要性。可以从以下几个方面进行讲解: 1.1 什么是单元测试 单元测试是指对软件中的最小可测试单元进行检查和验证。在C语言中,最小的可测试单元是函数,因此单元测试需…

    C 2023年5月23日
    00
  • C++两个cpp文件间如何进行各自函数的调用方式

    当我们在一个项目中有多个 C++ 源文件时,我们需要知道如何在不同的文件中调用其它文件的函数。 下面是两个cpp文件间如何进行各自函数的调用方式的攻略: 声明和定义 要在一个文件中使用另一个文件中定义的函数,我们必须将该函数的定义标记为 “extern”,并在需要使用它的文件中进行声明。 例如,如果我们有两个文件,一个叫做 main.cpp 和另一个叫做 h…

    C 2023年5月23日
    00
  • 避免elif和ELSE IF的阶梯和阶梯问题

    避免使用过多的elif和elseif语句是一个组织代码的好习惯,因为它们会导致代码不易维护,出现错误的可能性也更大。以下是一些关于如何避免elif和elseif语句阶梯和阶梯问题的建议: 使用字典代替elif语句 如果有一系列的if…elif语句,每个分支中的代码差别较小,这可以使用字典代替。 例如,我们想根据性别来获取某人的称呼: def get_ti…

    C 2023年5月9日
    00
  • 详解C++中的inline用法

    关于C++中的inline用法,我将给您详细讲解一下。本攻略包含以下内容: 什么是inline inline的使用方法 inline的使用场景 两个示例说明 1. 什么是inline inline 是C++中的一个关键字,表示内联函数。它是一种可以提高程序运行时性能的优化手段。 简而言之,在C++中,编译器一般会将函数调用转换为栈帧的操作,而使用 inlin…

    C 2023年5月23日
    00
  • VSCode launch.json配置详细教程

    首先,我们需要了解什么是VSCode的launch.json文件。launch.json是配置VSCode调试器的文件,在这个文件中,我们可以设置如何运行我们的代码、哪些文件需要调试、以及如何传递命令行参数等等。 接下来,让我们通过以下步骤创建一个新的launch.json文件: 在VSCode中打开你的项目文件夹。 打开调试器工具栏。(快捷键F5) 在工具…

    C 2023年5月23日
    00
  • MongoDB导出查询结果到文件例子

    MongoDB导出查询结果到文件主要有两种方式:使用mongoexport命令和使用db.collection.find().forEach()方法,下面分别进行讲解: 使用mongoexport命令导出查询结果到文件 语法: mongoexport -d <database_name> -c <collection_name> -q…

    C 2023年5月23日
    00
  • C++11 学习笔记之std::function和bind绑定器

    C++11 学习笔记之std::function和bind绑定器 概述 C++11引入了新的STL库,其中包含<functional>头文件,提供了一些与函数相关的新功能:std::function和std::bind。这两个功能的使用可以使得C++中的函数更加灵活,便于使用。 std::function是一个通用的函数封装,可以存储、复制及调用…

    C 2023年5月22日
    00
  • C语言实现运动会管理系统

    C语言实现运动会管理系统攻略 运动会管理系统是一个基于C语言编写的管理软件。本文将详细讲解如何使用C语言实现运动会管理系统。 一、系统功能 运动会管理系统主要包括以下功能: 注册和登录:新用户可以注册账号,已有账号可以登录系统。 学生信息管理:包括添加、修改、查询和删除学生信息。 运动员报名和成绩管理:运动员可以报名参加比赛,并记录比赛成绩。 赛程安排管理:…

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