C++实现聊天程序

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日

相关文章

  • 在ASP.NET 2.0中操作数据之三十八:处理BLL和DAL的异常

    在ASP.NET 2.0中操作数据之三十八:处理BLL和DAL的异常是一个重要的主题,对于开发者很有帮助。在开发应用程序时,处理异常是一个必要的过程,可以帮助我们检测和修复代码中的错误,提高程序的健壮性和可靠性。 异常处理的重要性 在应用程序开发中,异常处理非常重要。当应用程序发生异常,如果没有进行任何处理,程序将会停止运行,给用户带来极不好的使用体验。此时…

    C 2023年5月23日
    00
  • 详解JS变量存储深拷贝和浅拷贝

    详解JS变量存储深拷贝和浅拷贝 什么是拷贝? 拷贝是将原来的变量复制一份新的变量,使得新的变量与原变量相互独立,对新的变量的修改不会对原变量产生任何影响。 浅拷贝 在 JS 中,浅拷贝指的是将原始对象的引用复制给新的对象,如果原始对象发生变化,则新对象也会随之发生变化。示例如下: const originalObj = { a: { b: 1 }, c: 2…

    C 2023年5月23日
    00
  • C语言实现循环队列

    C语言实现循环队列的完整攻略 前言 循环队列是一种常用的数据结构,用于解决队列数据访问时线性存储空间限制的问题。本文将讲解如何使用C语言实现循环队列。 队列的定义 队列是一种特殊的线性表,具有先进先出(FIFO)的特点,即最先进入队列的元素最先被取出。 循环队列的特殊之处在于,队列空间是使用连续的线性存储空间而形成的一个环。 循环队列的实现 代码实现 在C语…

    C 2023年5月23日
    00
  • 使命召唤手游怎么赚c币 C币获取方法一览

    使命召唤手游怎么赚C币:C币获取方法一览 什么是C币? C币是使命召唤手游中的虚拟货币,可以用来购买游戏内道具和装备。 C币获取方法 1. 完成任务 游戏中会有一些每日和成就任务,每完成一项可获得一定数量的C币作为奖励。在任务界面查看任务并完成就可以领取奖励。 2. 参加活动 游戏官方会举办一些活动,参加活动并完成指定要求可以获取C币奖励。活动类型包括临时活…

    C 2023年5月23日
    00
  • asp生成不需要数据库的中奖码

    对于“asp生成不需要数据库的中奖码”的问题,我将提供完整的攻略。 首先,我们需要定义一个用来生成中奖码的函数。这个函数需要满足以下要求: 需要生成固定长度的中奖码。 每个中奖码由字母和数字组成。 中奖码不能重复。 下面是一个示例代码,用于生成6位长度的中奖码: Function GenerateCode() Dim code Dim i Randomize…

    C 2023年5月23日
    00
  • 毕业答辩的ppt怎么写? 毕业答辩的ppt的制作技巧

    下面是毕业答辩PPT的制作攻略,分为以下几个步骤: 1.明确PPT的目的和主题 在制作PPT之前,我们需要先想清楚PPT的主题和目的,展示内容和要讲解的重点,对于毕业答辩PPT来说,最好能够简洁明了地介绍自己的研究方向、主要研究内容和研究成果。 2.制作PPT的结构 PPT的结构要清晰且合理,通过分章节、剖析问题、展示数据等多种方式为听众呈现自己的研究成果。…

    C 2023年5月22日
    00
  • C# JSON格式化转换辅助类 ConvertJson

    C#是一种广泛使用的面向对象编程语言,而JSON格式化转换是现代程序中广泛使用的数据交换方式,将一个对象或一组对象序列化为JSON格式数据非常常见。ConvertJson是一个C# JSON格式化转换辅助类,在处理JSON格式数据时非常实用。接下来,我将为您提供关于如何使用ConvertJson的完整攻略。 安装 ConvertJson可以从NuGet包中获…

    C 2023年5月23日
    00
  • C++编译/编辑器对OIer的必要功能(推荐)

    C++编译/编辑器对OIer的必要功能(推荐) C++编译/编辑器是开发者进行编程时必要的工具,对于OIer而言,这些工具是必不可少的辅助设备。以下是编译/编辑器应该具备的必要功能以及一些推荐的C++编译/编辑器。 必要功能 代码高亮 —— 代码高亮可以使得代码更加美观易读,同时也方便调试。有些编辑器支持自定义语法高亮。 代码补全 —— 代码补全可以自动完成…

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