Linux c/c++实现简单网络库

Linux c/c++实现简单网络库

client和server类的声明

// file:network.h
// Created by ppd on 21-3-8.
// 主要实现:创建client和server类的
//
#include <iostream>
#include<sys/socket.h>
#include <sys/epoll.h>
#include<arpa/inet.h>
#include <string>
using namespace std;

class Client{
private:
    struct sockaddr_in server_addr;
    int server_port;
    const char* server_ip;
    int protocol;
    int cfd;

public:
    pthread_t pid;
    void* receivebuff;
    Client();
    Client(const char* ip,int &port,int pro);
    void SetServerIp(const char* ip);
    const char* getServerIp() { return  server_ip;}
    void SetServerPort(int &port);
    int& getServerPort() { return  server_port;}
    void ClientInit();
    int ClientConnect();
    bool ClientSendBuff(const void *sendbuff,const size_t len);
    void ClientReceiver();
    static void* ClientReceiverImpl(void *args);
    bool ClientReceiverRun();
    ~Client();

};

class Server{
private:
    struct sockaddr_in server_addr;
    struct epoll_event server_event;
    struct epoll_event client[20];
    int server_port;
    const char* server_ip;
    int protocol;
    int listenfd;
    int epollfd;

public:
    Server(const char* ip ="127.0.0.1" , int port = 8888,int pro = 0) {
        this->server_ip = ip;
        this->server_port = port;
        this->protocol = pro;
    }
    void ServerInit();
    int ServerListener();



};

client和server类的实现

基于epoll实现server的监听

// file:network.cpp
// Created by ppd on 21-3-8.
// 主要实现:实现client和server类的成员方法,实现消息收发
//
#include <pthread.h>
#include <sys/fcntl.h>
#include <sys/epoll.h>
#include "network.h"
#include <unistd.h>
#include <string.h>

typedef struct {
    int message_id;
    char  buff[30];
}receiver;
Client::Client():server_ip("127.0.0.1"),server_port(8888),protocol(0) {

}
Client::Client(const char* ip, int &port,int pro) {
    this->server_ip = ip;
    this->server_port = port;
    this->protocol = pro;
}

void Client::SetServerIp(const char* ip) {
    this->server_ip = ip;
}
void Client::SetServerPort(int &port) {
    this->server_port = port;
}
void Client::ClientInit() {
    this->server_addr.sin_port = htons(server_port);
    if(protocol == 0) {
        this->server_addr.sin_family = AF_INET;
        inet_pton(AF_INET,server_ip, &server_addr.sin_addr.s_addr);
    }
    else {
        this->server_addr.sin_family = AF_INET6;
        inet_pton(AF_INET6, server_ip, &server_addr.sin_addr.s_addr);
    }

}
int Client::ClientConnect() {
    int cfd;
    if(protocol == 0)
        cfd = socket(AF_INET,SOCK_STREAM,0);
    else
        cfd = socket(AF_INET6,SOCK_STREAM,0);
    int ret = connect(cfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
    if(ret == -1)
    {
        cout<<"CLIENT: connect error"<<endl;
        return 1;
    }
    cout<<"CLIENT: connect server IP:"<<this->server_ip<<" PORT:"<<this->server_port<<" success"<<endl;
    this->cfd = cfd;
    return 0;


}

bool Client::ClientSendBuff(const void *sendbuff,const size_t len) {
    int ret = send(this->cfd,sendbuff,len,0);
    if(ret <= 0)
    {
        cout<<"CLIENT: send error"<<endl;
        return false;
    }else {
        cout << "CLIENT: send " << ret << "bytes success" << endl;
        return true;
    }

}

void Client::ClientReceiver() {

    this->receivebuff = (void*)new(receiver);
    int ret;

    while(1)
    {
        ret = recv(this->cfd,this->receivebuff,sizeof(receiver),0);
        sleep(1);
        cout<<"CLIENT: message id:"<<((receiver*)receivebuff)->message_id<<"message buff:"<<((receiver*)receivebuff)->buff<<endl;
        *(receiver*)(this->receivebuff)={0};
        if(ret <= 0) {
            cout<<"CLIENT: server is disconnect"<<endl;
            close(cfd);
            return;

        }

    }

}
void* Client::ClientReceiverImpl(void *args) {
    Client *ptr = (Client*)args;
    ptr->ClientReceiver();
}

bool Client::ClientReceiverRun() {
    pthread_t pid;
    int ret = pthread_create(&pid,NULL,ClientReceiverImpl,(void*)this);
    this->pid = pid;
    if(ret != 0)
    {
        cout<<"CLIENT: create thread error"<<endl;
        return false;
    }else{
        cout<<"CLIENT: create thread success"<<endl;
        return true;
    }
}
Client::~Client() {
    if(this->receivebuff != nullptr)
    {
        delete this->receivebuff;
        this->receivebuff = nullptr;
    }
}

void Server::ServerInit() {
    this->server_addr.sin_port = htons(server_port);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    this->listenfd = socket(AF_INET,SOCK_STREAM,0);
    int ret;
    if(protocol == 0) {
        this->server_addr.sin_family = AF_INET;
        ret = bind(listenfd,(struct sockaddr*)&server_addr,sizeof(server_addr));
        if(ret == -1) {
            cout<<"SERVER: bind error"<<endl;
            return;
        }else {
            cout<<"SERVER: bind success"<<endl;
        }
    }
    else {
        this->server_addr.sin_family = AF_INET6;
        ret = bind(listenfd,(struct sockaddr*)&server_addr,sizeof(server_addr));
        if(ret == -1) {
            cout<<"SERVER: bind error"<<endl;
            return;
        }else {
            cout<<"SERVER: bind success"<<endl;
        }
    }
    ret = listen(listenfd,128);
    if(ret == -1) {
        cout<<"SERVER: listen error"<<endl;
    }
    cout<<"SERVER: listen success"<<endl;
    this->epollfd = epoll_create(20);
    if(epollfd == -1) {
        cout<<"SERVER: epoll create success"<<endl;
    }
    this->server_event.events = EPOLLIN | EPOLLET;
    this->server_event.data.fd = listenfd;
    ret = epoll_ctl(epollfd,EPOLL_CTL_ADD,listenfd,&server_event);
    if(ret == -1) {
        cout<<"SERVER: epoll_ctl error"<<endl;
    }
    cout<<"SERVER: will listen in PORT "<<server_port<<endl;



}
int Server::ServerListener() {
    int eventnum;
    struct sockaddr_in client_addr;
    int flag;
    socklen_t size = sizeof(client_addr);
    char str[INET_ADDRSTRLEN];
    while(1) {
        eventnum = epoll_wait(epollfd, client, 20, -1);
        for (int i = 0; i < eventnum; i++) {
            if (client[i].data.fd == listenfd) {
                int connfd = accept(listenfd, (struct sockaddr *) &client_addr, &size);
                printf("SERVER: received from %s at port %d\n",
                       inet_ntop(AF_INET, &client_addr.sin_addr, str, sizeof(str)),
                       ntohs(client_addr.sin_port));

                flag = fcntl(connfd, F_GETFL);
                flag |= O_NONBLOCK;
                fcntl(connfd, F_SETFL, flag);
                server_event.events = EPOLLIN;
                server_event.data.fd = connfd;
                eventnum = epoll_ctl(epollfd, EPOLL_CTL_ADD, connfd, &server_event);

            } else {
                char buf[1024] = {0};
                int n = read(client[i].data.fd, buf, sizeof(buf));
                if (n == 0) {
                    close(client[i].data.fd);
                    epoll_ctl(epollfd, EPOLL_CTL_DEL, client[i].data.fd, NULL);
                    printf("SERVER: one client is closed\n");
                } else if (n > 0) {
                    write(STDOUT_FILENO, buf, n);
                    cout<<endl;
                    receiver send;
                    send.message_id = 1;
                    strcpy(send.buff, "hello world\r\n");
                    write(client[i].data.fd, &send, sizeof(send));
                }
            }
        }
    }

}

sever类的使用

//
// Created by ppd on 21-3-9.
//
#include "network.h"
#include <iostream>
using namespace std;
int main()
{
    Server server = Server();
    server.ServerInit();
    server.ServerListener();

}

运行结果

SERVER: bind success
SERVER: listen success
SERVER: will listen in PORT 8888
SERVER: received from 127.0.0.1 at port 49616
hello world
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值