• Linux下c++11多线程聊天室


    刚看的c++11多线程,写个聊天室试试
    编译的时候加上 c++11 和 多线程库
    g++ -Wall -std=c++0x -pthread -o server server.cpp
    server 和client 都是 q 退出
    ​1. [代码]server.cpp     

    #include <iostream>
    #include <thread>
    #include <arpa/inet.h>
    #include <cstring>
    #include <vector>
    #include <algorithm>
    #include <unistd.h>
    using namespace std;
        vector<int> cli_vec;
        int listenfd, port;
        const char *ip = "127.0.0.1";
    void SendMsg(char* buf, int connfd){
        //cout<<"now send..."<<endl;
        char *data = buf;
        int len;
        for(auto i=cli_vec.begin(); i!=cli_vec.end(); ++i){
            if(*i == connfd) continue;
            if((len=send(*i, data, strlen(data),0)) == -1){
                //cout<<"send error"<<endl;
            }else{
                //cout<<"Send: "<<data<<endl;
            }
        }
    }
     
    void RecvMsg(int connfd){
        int len;
        char buf[100];
        while(1){
            memset(buf, 0, sizeof(buf));
            //cout<<"now receive..."<<connfd<<endl;
            if((len = recv(connfd, buf,sizeof(buf), 0)) == -1){
                //cout<<"Falid to receive"<<endl;
            }
            if(0 == len){
                cout<<connfd<<" has exit the chatting room"<<endl;
                auto pos = find(cli_vec.begin(), cli_vec.end(), connfd);
                if(pos != cli_vec.end()){
                    cli_vec.erase(pos);
                }
                break;
            }
            SendMsg(buf,connfd);
        }
    }       
     
    void WaitQuit(){
        char buf[100];
        while(1){
            cin>>buf;
            if(0 == strcmp(buf,"q")){
                for(auto i=cli_vec.begin(); i!=cli_vec.end(); i++){
                    close(*i);
                }
                cli_vec.clear();
                close(listenfd);
                break;
            }
        }
        exit(0);
    }
     
    int main()
    {
        if((listenfd=socket(AF_INET,SOCK_STREAM,0)) == -1){
            cout<<"socket error"<<endl;
            return -1;
        }
        cout<<"请输入端口号:";
        cin>>port;
        struct sockaddr_in serv_addr,cli_addr;
        memset(&serv_addr, 0, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port   = htons(port);
        serv_addr.sin_addr.s_addr = inet_addr(ip); 
        if(bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1){
            cout<<"bind error"<<endl;
            return -1;
        }http://www.enterdesk.com/special/dushen/​
        if(listen(listenfd, 10) == -1){
            cout<<"listen error"<<endl;
            return -1;赌神
        }   
        std::thread(WaitQuit).detach();
        cout<<"server is running..."<<endl;
        while(1){
            size_t cli_len = sizeof(cli_addr);
            memset(&cli_addr, 0, cli_len);
     
            int connfd = accept(listenfd, (struct sockaddr*)&cli_addr, &cli_len);
            if(connfd == -1){
                cout<<"accept error"<<endl;
                return -1;
            }
            cout<<connfd<<" has enter the chatting room"<<endl;
            cli_vec.push_back(connfd);
            std::thread(RecvMsg, connfd).detach();
        }
        return 0;
    }
    2. [代码]client.cpp     

    #include <iostream>
    #include <arpa/inet.h> // socket 相关 ...
    #include <unistd.h>    // close()
    #include <thread> 
    #include <string>
    #include <cstring>
    using namespace std;
     
    int sockfd;
    struct sockaddr_in serv_addr;
     
    void SendMsg(const string &msg) {
        if(-1 == send(sockfd, msg.c_str(), msg.size(), 0))
            cout<<"Failed to send"<<endl;
    }
     
    void RMsg(){
        int len;
        char recv_buf[1024];
        while (1) {
            memset(recv_buf, 0, sizeof(recv_buf));
            len = recv(sockfd, recv_buf, sizeof(recv_buf), 0);
            if (-1 == len) {
                cout<<"Failed to recv"<<endl;
            }
            if(0 == len){
                close(sockfd);
                cout<<"与服务器断开链接!"<<endl;
                break;
            }
            cout<<"Receive message: "<<recv_buf<<endl;
        }
    }
     
    int main()
    {
        string ip = "127.0.0.1";
        int port;
        cout<<"please input server port:";
        cin>>port;
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (-1 == sockfd) {
            cout<<"Failed to sockfd"<<endl;
            return -1;
        }
        memset(&serv_addr, 0, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(port);
        serv_addr.sin_addr.s_addr = inet_addr(ip.c_str());
     
        int stat = connect(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr));
        if (-1 == stat) {
            cout<<"Failed to connect"<<endl;
            return -1;
        }
        std::thread(RMsg).detach();
        while(1)
        {
            string send_msg;
             
            cin>>send_msg;
            if (send_msg == "q")
            {
                cout<<"结束客户端!"<<endl;
                break;
            }
            else
                SendMsg(send_msg);
        }
        close(sockfd);
        return 0;
    }

  • 相关阅读:
    使用淘宝Str2varlist与str2numlist 代替 in/exist ,提升性能(Oracle)
    由浅入深理解索引的实现
    你知道数据库索引的工作原理吗?
    深入理解数据库磁盘存储(Disk Storage)
    如何解析oracle执行计划
    Beyond Compare 4 最新中文版 注册码 key
    并发和并行的区别
    代码复用的规则
    Some Java exceptions, messages and errors.
    菜鸟学SSH(十六)——Struts2内部是如何工作的
  • 原文地址:https://www.cnblogs.com/xkzy/p/3969909.html
Copyright © 2020-2023  润新知