C++ select模型简单聊天室的实现示例

TIPS:以下使用CMake项目进行开发。关于何为CMake,链接:https://www.jb51.net/article/247089.htm

简单聊天室效果展示

简单聊天室服务端源码(使用select模型)

// Server0327.cpp: 定义应用程序的入口点。
//

#include "Server0327.h"
#include <WinSock2.h>
#include <vector>

#pragma comment(lib,"ws2_32.lib")

using namespace std;
class TcpServer
{
public:
    bool Listen(const char* ip, int port)
    {
        //创建socket
        _serverSock = socket(AF_INET, SOCK_STREAM, 0);
        if (INVALID_SOCKET == _serverSock)
            goto Exit;
        //绑定IP和端口号
        SOCKADDR_IN addr;
        addr.sin_addr.s_addr = inet_addr(ip);
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        if (INVALID_SOCKET == bind(_serverSock, (sockaddr*)&addr, sizeof(SOCKADDR_IN)))
            goto Exit;

        //监听端口
        if (INVALID_SOCKET == listen(_serverSock, 255))
            goto Exit;

        return true;
    Exit:
        closesocket(_serverSock);
        _serverSock = INVALID_SOCKET;
        return false;
    }

    void Update()
    {
        FD_SET reads;
        FD_ZERO(&reads);
        FD_SET(_serverSock, &reads);

        for (auto&& clientSock : _clientSocks)
            FD_SET(clientSock, &reads);

        int nRet = select(0, &reads, nullptr, nullptr, nullptr);
        if (nRet > 0)
        {
            if (FD_ISSET(_serverSock, &reads))
                Accept();
            else
            {
                for (int i = 0; i < _clientSocks.size(); i++)
                {
                    if (FD_ISSET(_clientSocks[i], &reads))
                    {
                        char buf[1024]{ 0 };
                        int nRecv = recv(_clientSocks[i], buf, 1024, 0);
                        if (nRecv > 0)
                            OnNetMsg(_clientSocks[i], buf, sizeof(buf));
                        if (nRecv <= 0)
                        {
                            closesocket(_clientSocks[i]);
                            OnDisConnect(_clientSocks[i]);
                            _clientSocks.erase(_clientSocks.begin() + i);
                            continue;
                        }
                    }
                }
            }
        }
    }

    void Accept()
    {
        SOCKADDR_IN clientAddr;
        int clientAddrLen = sizeof(clientAddr);
        SOCKET clientSock = accept(_serverSock, (sockaddr*)&clientAddr, &clientAddrLen);
        if (INVALID_SOCKET != clientSock)
        {
            _clientSocks.push_back(clientSock);
            OnConnect(clientSock);
        }

    }

    void OnConnect(SOCKET clientSock)
    {
        printf("%d 客户端连接\n", clientSock);
    }

    int OnNetMsg(SOCKET clientSock, const char* buff, int len)
    {
        printf("%d == %s\n", clientSock, buff);
        for (auto&& clientSock : _clientSocks)
            send(clientSock, buff, len, 0);
        return len;
    }

    void OnDisConnect(SOCKET sock)
    {
        printf("%d==客户端断开连接\n", sock);
    }

private:
    SOCKET _serverSock;
    vector<SOCKET> _clientSocks;
};

int main()
{
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2), &wsa);

    TcpServer server;
    server.Listen("0.0.0.0", 7890);
    while (true)
        server.Update();

    WSACleanup();
    return 0;
}

简单聊天室客户端源码(使用多线程)

// CMakeClient0331.cpp: 定义应用程序的入口点。
//

#include "CMakeClient0331.h"
#include<iostream>
#include<WinSock2.h>
#include<thread>

#pragma comment(lib,"ws2_32.lib")

int main()
{
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    SOCKET clientSock = socket(AF_INET, SOCK_STREAM, 0);
    if (INVALID_SOCKET == clientSock)
    {
        closesocket(clientSock);
        WSACleanup();
        return 0;
    }

    SOCKADDR_IN serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    serverAddr.sin_port = htons(7890);
    if (INVALID_SOCKET == connect(clientSock, (sockaddr*)&serverAddr, sizeof(SOCKADDR_IN)))
    {
        closesocket(clientSock);
        WSACleanup();
        return 0;
    }
    std::cout << "已连接服务端" << std::endl;

    std::thread t([&clientSock] {
        while (true)
        {
            char buf[1024]{ 0 };
            int nRecvLen = recv(clientSock, buf, 1024, 0);
            if (nRecvLen <= 0)
                break;
            std::cout << "接收数据长度:" << nRecvLen << " 接受数据:" << buf << std::endl;
        }
        });
    t.detach();

    while (true)
    {
        char buf[1024]{ 0 };
        std::cin >> buf;
        if (buf[0] == 'q')break;
        int nSendLen = send(clientSock, buf, sizeof(buf), 0);
    }

    closesocket(clientSock);
    WSACleanup();
    return 0;
}

到此这篇关于C++ select模型简单聊天室的文章就介绍到这了,更多相关C++ select模型简单聊天室内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++基于socket编程实现聊天室功能

    本文实例为大家分享了C++基于socket编程实现聊天室的具体代码,供大家参考,具体内容如下 服务端 // server.cpp : 此文件包含 "main" 函数.程序执行将在此处开始并结束. // #include "pch.h" #include <iostream> #include "winsock2.h" #include "stdlib.h" #include "stdio.h"

  • 基于C++实现TCP聊天室功能

    本文实例为大家分享了C++实现TCP聊天室功能的具体代码,供大家参考,具体内容如下 TCPServer.cpp: // TCPServer.cpp : Defines the entry point for the console application. #include "stdafx.h" #include<iostream> #include<stdio.h> #include<WinSock2.h> using namespace std;

  • C++实现简易UDP网络聊天室

    本文实例为大家分享了C++实现简易UDP网络聊天室的具体代码,供大家参考,具体内容如下 工程名:NetSrv NetSrv.cpp //服务器端 #include<Winsock2.h> #include<stdio.h> void main() { //加载套接字库 WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(1,1); err = WSAStartup(wVersi

  • C++基于socket多线程实现网络聊天室

    本文实例为大家分享了C++基于socket多线程实现网络聊天室的具体代码,供大家参考,具体内容如下 1. 实现图解 2. 聊天室服务端:TCP_Server_Chat.cpp #include <winsock2.h> // winsock2的头文件 #include <iostream> #pragma comment(lib, "ws2_32.lib") using namespace std; // stdcall的线程处理函数 DWORD WINAPI

  • C++实现Window环境聊天室功能

    C++ Window环境聊天室,供大家参考,具体内容如下 最近闲来无事,想学习一下C++的并发编程和Socket信息传输,故以聊天室为载体进行学习.话不多说,代码开干. 聊天室分为多个客户端和一个服务器.服务器负责接收各个客户端传来的信息,然后转发给各个客户端,起到"中介"的作用:而客户端可以发送消息,并接收消息. 1.服务端 根据上述所说,一个服务器需要做的事: ① 接受新的客户端连接请求 ② 聆听各个已连接的客户端的新消息 ③ 将收到的信息逐个传送给各个已连接的服务器 所以,我设置

  • C++基于socket UDP网络编程实现简单聊天室功能

    本文实例为大家分享了C++基于socket UDP实现简单聊天室功能的具体代码,供大家参考,具体内容如下 0.通信步骤流程图 (左:服务器:右:客户端:) 1.服务器代码 1.1服务器类头文件(CServer_UDP.h) #pragma once #include <winsock2.h> class CServer_UDP { public: CServer_UDP(); void SendMsg(const char sendBuf[]); void RecMsg(); ~CServer

  • C++实现多人聊天室

    本文实例为大家分享了C++实现多人聊天室的具体代码,供大家参考,具体内容如下 UDP 服务端代码: // Test_Console.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #include <WinSock2.h> #include <WS2tcpip.h> #include <Windows.h> #include <thread> #i

  • C++ select模型简单聊天室的实现示例

    TIPS:以下使用CMake项目进行开发.关于何为CMake,链接:https://www.jb51.net/article/247089.htm 简单聊天室效果展示 简单聊天室服务端源码(使用select模型) // Server0327.cpp: 定义应用程序的入口点. // #include "Server0327.h" #include <WinSock2.h> #include <vector> #pragma comment(lib,"ws

  • Python socket实现简单聊天室

    本文实例为大家分享了Python socket实现简单聊天室的具体代码,供大家参考,具体内容如下 服务端使用了select模块,实现了对多个socket的监控.客户端由于select在Windows下只能对socket使用,所以使用了多线程来实现对客户端输入和socket连接的同时监控.注意这里的socket设置为了非阻塞.这样就实现了在一个线程中同时进行socket的接收和发送. 服务器代码: # -*- coding: utf-8 -*- import socket,select conne

  • Python基于Socket实现简单聊天室

    本文实例为大家分享了Python基于Socket实现简单聊天室,供大家参考,具体内容如下 服务端 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2017/7/27 15:34 # @File : Server.py """ 聊天室服务端 """ import socket,select host='' port=7799 addr=(host,port) inputs=[] mem

  • java基于netty NIO的简单聊天室的实现

    一.为何要使用netty开发 由于之前已经用Java中的socket写过一版简单的聊天室,这里就不再对聊天室的具体架构进行细致的介绍了,主要关注于使用netty框架重构后带来的改变.对聊天室不了解的同学可以先看下我的博客(<JAVA简单聊天室的实现>) 本篇博客所使用的netty版本为4.1.36,完整工程已上传到Github(https://github.com/Alexlingl/Chatroom),其中lib文件夹下有相应的netty jar包和source包,自行导入即可. 1.为何要

  • JAVA NIO实现简单聊天室功能

    本文实例为大家分享了JAVA NIO实现简单聊天室功能的具体代码,供大家参考,具体内容如下 服务端 初始化一个ServerSocketChannel,绑定端口,然后使用Selector监听accept事件. 当有accept发生时,表示有客户端连接进来了,获取客户端的SocketChannel,然后注册其read事件:用来接收客户端发送的消息. package chatroom; import java.io.IOException; import java.net.InetSocketAddr

  • Java continue break制作简单聊天室程序

    Java continue break 制作简单聊天室程序,屏蔽不文明语言,显示每句话聊天时间 package com.swift; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Scanner; public class ChatWithBreakContinue { public static void main(String[] args) { Scanner scan = new Sc

  • 使用socket.io实现简单聊天室案例

    本文实例为大家分享了socket.io实现简单聊天室的具体代码,供大家参考,具体内容如下 1.客户端[index.html]代码: <body> <h3>socket简例</h3> <hr> <div id = 'app'> <div> <div> <ul> <li v-for = 'item in msgs'> {{item.name}}说:{{item.content}} </li>

  • python实现简单聊天室功能 可以私聊

    本文实例为大家分享了python实现简单聊天室功能的具体代码,供大家参考,具体内容如下 公共模块 首先写一个公共类,用字典的形式对数据的收发,并且进行封装,导入struct解决了TCP的粘包问题,并在公共类中进行了异常处理 import socket,struct,json def send_dic(c,dic): dic_json=json.dumps(dic) dic_json_length=len(dic_json.encode('utf-8')) struct_dic_json_leng

  • java实现简单聊天室单人版

    本文实例为大家分享了java实现简单聊天室的具体代码,供大家参考,具体内容如下 先整理下思路: 1.创建一个通信服务端,传入端口号和相关的流后等待客户端连接,并初始化图形界面. 2.创建一个JFrame,用于写出聊天的界面,这里界面名称由其他类传入. 3.把客户端创建的方法写进JFrame(当然这里很粗糙的方法) 4.设置按钮的监听事件,发送消息和离线功能 首先创建一个服务端的类 import java.io.IOException; import java.net.ServerSocket;

  • java web实现简单聊天室

    目标 servlet.jsp实现简单聊天室,用户通过浏览器登录后进入聊天室,可发送消息进行群聊,点击聊天信息框中的用户名可实现拍一拍功能. 基础知识 数据的存取 setAttribute / getAttribute request请求对象 :有效时间短 ServletContext上下文对象:一直存在于服务器,存储公有. 共享数据 Session会话对象:独立 网站默认页面一般是index.jsp 实现思路 1.登录页面 login.jsp 输入昵称 2.编写一个LoginSevlet,处理登

随机推荐