c++的tcp服务类可以连接多个客户端

前言

把tcp连接封装成类,建立面向对象的编程思维,利用多线程可以让tcp服务与多个tcp客户建立连接并通信

重点

  1. accept()会堵塞进程,直到检测到新连接,所以需要把accpet放到循环中
  2. 在线程中传递参数时,把建立好连接的对象传递过去
  3. 注意关闭连接

完整代码脚本

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <iostream>
#include <thread>
#include <vector>

using namespace std;


class SocketTcpServer
{
private:
	int sk;
	string ip;
	int port;
	bool status;
    struct sockaddr_in s_addr;
public:
    SocketTcpServer()
    {
        ip = "0.0.0.0";
        port = 8080;
        sk = 0;
        status = false;
        s_addr.sin_family = AF_INET;	 // 协议族,在socket编程中只能是AF_INET
        s_addr.sin_addr.s_addr = inet_addr(ip.c_str());
        s_addr.sin_port = htons(port); // 绑定通讯端口

    }

    SocketTcpServer(string ip_, int port_)
    {
        ip = ip_;
        port = port_;
        sk = 0;
        status = false;
        s_addr.sin_family = AF_INET;	 // 协议族,在socket编程中只能是AF_INET
        s_addr.sin_addr.s_addr = inet_addr(ip.c_str());
        s_addr.sin_port = htons(port); // 绑定通讯端口
    }

    void tcpTalk(int cl)
    {
        char buf[1024] = {0};
        while(1) {
            int rd = read(cl, buf, sizeof(buf));
            if (rd == -1) {
                perror("read");
                exit(-1);
            } else if(rd > 0) {
                for (int i=0; i< rd; i++) {
                    printf("%d ", buf[i]);
                }
                printf("\n");
            } else if (rd == 0) {
                cout << "client close" << endl;
                close(cl);
                break;
            }
            char const *data= "hello, iam server";
            write(cl, data, strlen(data));
        }

    }

    void openTcp()
    {
        sk = socket(AF_INET, SOCK_STREAM, 0);
        if (sk == -1) {
            perror("socket");
            exit(-1);
        }
        int opt = 1;
        setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt));
        int res = bind(sk, (struct sockaddr *)&s_addr, sizeof(s_addr));
        if (res == -1) {
            perror("bind");
            exit(-1);
        } else {
            cout << "bind success!" << endl;
        }

        res = listen(sk, 5);
        if(res == -1) {
            perror("listen");
            exit(-1);
        } else {
            cout << "listening ..." << endl;
        }

        struct sockaddr_in c_addr;
        socklen_t c_addr_len = sizeof(c_addr);
        while (true)
        {
            int sk_client = accept(sk, (struct sockaddr *)&c_addr, &c_addr_len);
            if (sk_client == -1) {
                perror("accept");
                exit(-1);
            }
            printf("connect : %s %d\n", inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port));
            thread(&SocketTcpServer::tcpTalk, this, sk_client).detach();
        }
        close(sk);
    }

};


int main()
{
    SocketTcpServer s("192.168.1.103", 10000);
    s.openTcp();
    while (true)
    {
        this_thread::sleep_for(chrono::milliseconds(200));
    }
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值