52.TcpSocket

lesson40 聊天室改成多线程

线程池内部处理任务时候已经解锁了,所以函数中成员集不属于临界资源,多线程访问会出现问题

可以把route新增,转发,删除在udpserver拆开,这样的话锁的力度就变细了。

看网络第二个课件的补充参考部分 改一下Inetaddr.hpp 主机转网络封装好了之后,sockaddr_in就不需要初始化各种值,肢解创建InetAddr,直接就初始化好了。

inet_ntoa有可能存在线程安全问题 ip以后用inet_ntop inet_pton 端口用ntohs htons

windows linux能联动

看tcpechoserver代码

服务器禁止拷贝

继承之后如果想拷贝,必须拷贝父类,父类禁止拷贝所以就禁止拷贝

telnet 可以远程连接tcp服务器 telnet ip 端口号

cpp 复制代码
#pragma once

// 注意:基于截图内容,省略了外部头文件(如 <iostream>, <unistd.h>, "Log.hpp", "InetAddr.hpp" 等)
// 假设 backlog 和 CONV 宏已在 Common.hpp 等文件中定义
// const static int backlog = 16;
// #define CONV(addr) (struct sockaddr *)&(addr)

// 服务器往往是禁止拷贝的
using namespace LogModule;

const static int defaultsockfd = -1;

class TcpServer : public NoCopy
{
public:
    TcpServer(uint16_t port) : _port(port), _listensockfd(defaultsockfd), _isrunning(false)
    {}

    void Init()
    {
        // 1. 创建套接字文件
        _listensockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (_listensockfd < 0)
        {
            LOG(LogLevel::FATAL) << "socket error";
            exit(SOCKET_ERR);
        }
        LOG(LogLevel::INFO) << "socket success: " << _listensockfd; // 3

        // 2. bind众所周知的端口号
        InetAddr local(_port);
        int n = bind(_listensockfd, local.NetAddrPtr(), local.NetAddrLen());
        if (n < 0)
        {
            LOG(LogLevel::FATAL) << "bind error";
            exit(BIND_ERR);
        }
        LOG(LogLevel::INFO) << "bind success: " << _listensockfd; // 3

        // 3. 设置socket状态为listen
        n = listen(_listensockfd, backlog);
        if (n < 0)
        {
            LOG(LogLevel::FATAL) << "listen error";
            exit(LISTEN_ERR);
        }
        LOG(LogLevel::INFO) << "listen success: " << _listensockfd; // 3
    }

    void Service(int sockfd, InetAddr &peer)
    {
        char buffer[1024];
        while (true)
        {
            // 1. 先读取数据
            // a. n>0: 读取成功
            // b. n<0: 读取失败
            // c. n==0: 对端把链接关闭了,读到了文件的结尾 --- pipe
            ssize_t n = read(sockfd, buffer, sizeof(buffer) - 1);
            if (n > 0)
            {
                buffer[n] = 0; // 设置为C风格字符串,n<= sizeof(buffer)-1
                LOG(LogLevel::DEBUG) << peer.StringAddr() << " say# " << buffer;
                
                // 2. 写回数据
                std::string echo_string = "echo# ";
                echo_string += buffer;

                write(sockfd, echo_string.c_str(), echo_string.size());
            }
            else if (n == 0)
            {
                LOG(LogLevel::DEBUG) << peer.StringAddr() << " 退出了...";
                close(sockfd);
                break;
            }
            else
            {
                LOG(LogLevel::DEBUG) << peer.StringAddr() << " 退出了...";
                close(sockfd);
                break;
            }
        }
    }

    void Run()
    {
        _isrunning = true;
        while (_isrunning)
        {
            // a. 获取链接
            struct sockaddr_in peer;
            socklen_t len = sizeof(sockaddr_in);
            // 如果没有连接,accept就会阻塞
            int sockfd = accept(_listensockfd, CONV(peer), &len);
            if (sockfd < 0)
            {
                LOG(LogLevel::WARNING) << "accept error";
                continue;
            }
            InetAddr addr(peer);
            LOG(LogLevel::INFO) << "accept success, peer addr : " << addr.StringAddr();

            // version0 -- test version --- 单进程程序 --- 不会存在的!
            Service(sockfd, addr);
        }
        _isrunning = false;
    }

    ~TcpServer()
    {
    }

private:
    uint16_t _port;
    int _listensockfd; // 监听socket
    bool _isrunning;
};

相关推荐
hey you~11 小时前
400电话选型技术测评:一个开发视角的线路质量评估方案
运维·网络·数据库·400电话·企业通信
筱羽_筱羽11 小时前
跟着“Ubuntu18.04/20.04编译Linux5.10.76+Xenomai-3.2.1+IgH”教程遇到的问题
linux·运维·ubuntu
法外狂徒111 小时前
将 Pi Agent 接入 HagiCode 的实践之路
服务器·前端·人工智能
曾令胜12 小时前
HTTP协议基础总结
网络·网络协议·http
ShineWinsu12 小时前
对于Linux:基于UDP实现简单聊天室功能
linux·c++·面试·udp·笔试·进程·简单聊天室
Dovis(誓平步青云)12 小时前
《精讲Spring Boot后端跑另一个端口:如何解决暴露服务器问题》
服务器·人工智能·spring boot·后端·生成对抗网络
hj28625112 小时前
Docker 核心知识点整理(网络 + Dockerfile + 原理 + 命令)
网络·docker·容器
so~what12 小时前
NTN全局控制器集中管理的优势
网络·ntn
流量猎手12 小时前
Vscode登陆服务器
服务器·ide·vscode
zoipuus12 小时前
上传repo仓库到自己的gitlab
linux·gitlab·shell·全志·tina