C++ selec聊天室

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

C++ selec聊天室

ufgnix0802   2022-06-03 我要评论

TIPS:以下使用CMake项目进行开发。关于何为CMake,链接:https:

简单聊天室效果展示

简单聊天室服务端源码(使用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;
}

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们