linux c++ tcp demo 极简版(最好理解)

tcp client

int fd = socket(AF_INET, SOCK_STREAM, 0);

sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(DEFAULT_SERVER_IP);
server_addr.sin_port = htons(DEFAULT_SERVER_PORT);

connect(fd, (sockaddr*)&server_addr, sizeof(sockaddr_in));

int num = 0;
while (true) {
	char buf[DEFAULT_BUF_LEN] = {0};
	sprintf(buf, "hello, server.....%d\n", num++);
	send(fd, buf, sizeof(buf), 0);
	printf("client send: %s\n", buf);
	sleep(1);
}

tcp server

int connection_fd = socket(AF_INET, SOCK_STREAM, 0);

sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(DEFAULT_SERVER_PORT);

bind(connection_fd, (sockaddr*)&server_addr, sizeof(sockaddr_in));
listen(connection_fd, 20);

socklen_t len = sizeof(sockaddr_in);
sockaddr_in client_addr;
int fd = accept(connection_fd, (sockaddr*)&client_addr, &len);

while (true) {
    char buf[DEFAULT_BUF_LEN] = {0};
    recv(fd, buf, sizeof(buf), 0);
    printf("server receive: %s\n", buf);
}

select server

class SelectServer {
   public:
    SelectServer() = default;
    void init();
    void run();
   private:
    int connection_fd_;
    fd_set read_fd_set_;
};

void SelectServer::init() {
    connection_fd_ = socket(AF_INET, SOCK_STREAM, 0);

    int opt = 1;
    unsigned int len = sizeof(opt);
    setsockopt(connection_fd_, SOL_SOCKET, SO_REUSEADDR, &opt, len);
    setsockopt(connection_fd_, SOL_SOCKET, SO_KEEPALIVE, &opt, len);

    sockaddr_in servaddr;
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(DEFAULT_SERVER_PORT);

    bind(connection_fd_, (sockaddr*)&servaddr, sizeof(servaddr));
    listen(connection_fd_, 20);

    FD_ZERO(&read_fd_set_);
    FD_SET(connection_fd_, &read_fd_set_);
}

void SelectServer::run() {
    while (true) {
        fd_set tmpfdset = read_fd_set_;
        int infds = select(MAXEVENTS + 1, &tmpfdset, NULL, NULL, NULL);
        if (infds < 0) break;
        if (infds == 0) continue;

        for (int i = 0; i <= MAXEVENTS; i++) {
            if (FD_ISSET(i, &tmpfdset) <= 0)
                continue;
            if (i == connection_fd_) { // [connection_fd_ event]
                sockaddr_in client;
                socklen_t len = sizeof(client);
                int data_fd = accept(connection_fd_, (sockaddr*)&client, &len);
                printf("add data_fd %d\n", data_fd);
                FD_SET(data_fd, &read_fd_set_); // add data_fd
            } else { // [data_fd event]
                char buf[DEFAULT_BUF_LEN] = {0};
                ssize_t isize = read(i, buf, sizeof(buf));
                if (isize <= 0) {
                    close(i);
                    FD_CLR(i, &read_fd_set_); // del data_fd
                    printf("del data_fd %d\n", i);
                } else {
                    printf("fd: %d, recv: %s\n", i, buf); // read data
                }
            }
        }
    }
}

epoll server

class EpollServer {
   public:
    EpollServer() = default;
    void init();
    void run();
   private:
    void update_epollfd(const int sock, int epoll_ctl_arg);
    int connection_fd_;
    int epollfd_;
};

void EpollServer::init() {
    connection_fd_ = socket(AF_INET, SOCK_STREAM, 0);

    int opt = 1;
    unsigned int len = sizeof(opt);
    setsockopt(connection_fd_, SOL_SOCKET, SO_REUSEADDR, &opt, len);
    setsockopt(connection_fd_, SOL_SOCKET, SO_KEEPALIVE, &opt, len);

    sockaddr_in servaddr;
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(DEFAULT_SERVER_PORT);

    bind(connection_fd_, (sockaddr*)&servaddr, sizeof(servaddr));
    listen(connection_fd_, 20);

    epollfd_ = epoll_create(1);
    update_epollfd(connection_fd_, EPOLL_CTL_ADD);
}

void EpollServer::run() {
    while (true) {
        epoll_event events[MAXEVENTS];
        int infds = epoll_wait(epollfd_, events, MAXEVENTS, -1);
        if (infds < 0) break;
        if (infds == 0) continue;

        for (int i = 0; i < infds; i++) {
            if (!(events[i].events & EPOLLIN))
                continue;
            if (events[i].data.fd == connection_fd_) { // [connection_fd_ event]
                sockaddr_in client;
                socklen_t len = sizeof(client);
                int data_fd = accept(connection_fd_, (sockaddr*)&client, &len);
                printf("add data_fd %d\n", data_fd);
                update_epollfd(data_fd, EPOLL_CTL_ADD); // add data_fd
            } else {  // [data_fd event]
                char buf[DEFAULT_BUF_LEN] = {0};
                ssize_t sz = read(events[i].data.fd, buf, sizeof(buf));
                if (sz <= 0) {
                    printf("del data_fd %d\n", events[i].data.fd);
                    update_epollfd(events[i].data.fd, EPOLL_CTL_DEL); // del data_fd
                    close(events[i].data.fd);
                } else {
                    printf("fd: %d, recv: %s\n", events[i].data.fd, buf); // read data
                }
            }
        }
    }
}

void EpollServer::update_epollfd(const int fd, int operation) {
    epoll_event ev;
    memset(&ev, 0, sizeof(epoll_event));
    ev.events = EPOLLIN;
    ev.data.fd = fd;
    epoll_ctl(epollfd_, operation, fd, &ev);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值