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日

相关文章

  • C语言对于volatile与gcc优化的探究

    C语言对于volatile与gcc优化的探究 什么是volatile关键字 在C语言中,volatile是一个关键字,可以用来修饰一个变量,告诉编译器这个变量没有被优化,需要实时读取。 volatile的作用是防止编译器进行一些优化,例如在一个循环中,变量的值在循环中被修改,而且这个变量还被其他模块所使用,那么为了保证其他模块使用的变量是最新的,我们就需要用…

    C 2023年5月23日
    00
  • C语言入门篇–初识C语言及数据类型

    C语言入门篇–初识C语言及数据类型 一、C语言概述 C语言是一种高级编程语言,它可以编写底层的系统软件和高级的应用程序。它在计算机领域中的优势在于它快速、高效、稳定,且是一种跨平台的语言。 二、数据类型 在C语言中,数据类型用于定义不同类型的变量。C语言提供了许多内置的数据类型,例如int、float、char等等。 1.整数型(int) 整数型是最基本的…

    C 2023年5月23日
    00
  • C/C++ Qt 运用JSON解析库的实例代码

    下面将为您详细讲解在C/C++ Qt中运用JSON解析库的实例代码的完整攻略。 一、JSON简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。JSON建立在两种结构上:一个用来表示值的简单原始类型(数字、字符串、布尔值、空值)以及一种集合值的有序列表(数组)和一个包含…

    C 2023年5月23日
    00
  • C++11如何引入的尾置返回类型

    C++11 引入了尾置返回类型(trailing return type)来增强类型推导的能力。尾置返回类型是一种特殊的语法形式,可用于在函数定义中指定函数返回类型。尾置返回类型的语法形式是在函数形参列表之后使用箭头(->),后跟将函数返回类型所需的任何内容。 尾置返回类型是在编译时确定的,因此使用尾置返回类型可以提高代码的可读性和可维护性,例如可以维…

    C 2023年5月23日
    00
  • iOS底层探索之自动释放池原理解析

    iOS底层探索之自动释放池原理解析 什么是自动释放池 自动释放池是一种机制,用于在Objective-C中管理内存。具体来说,自动释放池是一个用于暂时存储不需要的Objective-C对象的容器,当自动释放池被销毁时,它所包含的所有对象都被发送一条autorelease消息。autorelease消息会将这些对象的引用计数减一,如果引用计数变为0,对象会立即…

    C 2023年5月23日
    00
  • 详解C++内存的代码区,全局区,栈区和堆区

    首先我们来了解一下 C++ 内存分区的四个部分:代码区、全局区、栈区和堆区。 代码区 代码区是用于存放程序的可执行代码,是只读的,它的大小在程序编译时就已经确定了。在代码区中,每个函数都有一个入口地址,这些入口地址按照函数声明的顺序保存在函数表中。 全局区 全局区用于全局变量和静态变量的存储,它在程序运行前就已经分配好了固定的内存空间,程序结束时才会被释放。…

    C 2023年5月24日
    00
  • C语言各类操作符全面讲解

    C语言各类操作符全面讲解 C语言中操作符是完成各种操作的重要基础,操作符可分为以下几类: 算术操作符 关系操作符 逻辑操作符 赋值操作符 条件操作符 位操作符 下面我们一一来进行详细讲解。 算术操作符 操作符 功能 + 两数相加 – 两数相减 * 两数相乘 / 两数相除 % 取余数 ++ 自增操作 — 自减操作 示例: int a = 10; int b …

    C 2023年5月23日
    00
  • C++控制台绘图头文件实例代码

    下面是对“C++控制台绘图头文件实例代码”的完整攻略: 1. 简介 在C++的控制台程序中,通过使用图形化绘图头文件,可以在控制台中绘制出各种图形。 2. 下载 在使用绘图头文件前,需要下载对应的库文件。 目前比较流行的库包括: graphics.h:Borland C++ 5.02自带的,不建议使用。 conio.h:Turbo C自带的,也不建议使用。 …

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