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