这里只放了三个版本的服务器代码,完整代码请前往我的GitHub仓库—>戳我,戳我
tcp_process_server.hpp
#pragma once
#include"tcp_socket.hpp"
#include<signal.h>
typedef void (*Handler)(const string& buf,string& ret);
class TcpProcessServer{
public:
TcpProcessServer()
{}
~TcpProcessServer(){
_sock.Close();
}
bool Start(const string& ip,const int port,Handler handler){
signal(SIGCLD,SIG_IGN);
if(_sock.Bind(ip,port)==false)
return false;
if(_sock.Listen()==false)
return false;
while(1){
TcpSocket NewSock;
string ClientIp;
int ClientPort;
if(_sock.Accept(&NewSock,ClientIp,ClientPort)==false)
continue;
printf("[%s:%d]客户端已连接!~\n",ClientIp.c_str(),ClientPort);
ProcessConnect(NewSock,ClientIp,ClientPort,handler);
}
return true;
}
private:
void ProcessConnect(TcpSocket& NewSock,const string& ip,const int port,Handler handler){
int fid=fork();
if(fid>0){
NewSock.Close();
return;
}
while(1){
string msg;
int n=NewSock.Recv(msg);
if(n<0){
continue;
}
else if(n==0){
printf("[%s:%d]客户端已断开!\n",ip.c_str(),port);
break;
}
printf("[%s:%d]客户端发送了:%s\n",ip.c_str(),port,msg.c_str());
string ret;
handler(msg,ret);
if(NewSock.Send(ret)==false)
continue;
}
NewSock.Close();
exit(0);
}
TcpSocket _sock;
};
tcp_thread_server.hpp
#pragma once
#include"tcp_socket.hpp"
#include<pthread.h>
typedef void (*Handler)(const string& buf,string& ret);
class TcpThreadServer{
public:
TcpThreadServer(){
}
~TcpThreadServer(){
_listen_sock.Close();
}
bool Start(const string& ip,const int port,Handler handler){
int n=_listen_sock.Bind(ip,port);
if(n<0){
return false;
}
n=_listen_sock.Listen();
if(n<0){
return false;
}
while(1){
TcpSocket client_sock;
string peer_ip;
int peer_port;
if(_listen_sock.Accept(&client_sock,peer_ip,peer_port)==false)
continue;
printf("[%s:%d]客户端已连接!\n",peer_ip.c_str(),peer_port);
ProcessClient(client_sock,ip,port,handler);
}
}
private:
TcpSocket _listen_sock;
struct ThreadEntryArg{
TcpSocket client_sock;
string ip;
int port;
Handler handler;
};
void ProcessClient(TcpSocket& client_sock,const string& ip,const int port,Handler handler){
pthread_t tid;
ThreadEntryArg* arg=new ThreadEntryArg;
arg->client_sock=client_sock;
arg->ip=ip;
arg->handler=handler;
arg->port=port;
pthread_create(&tid,NULL,ThreadEntry,(void*)arg);
pthread_detach(tid);
}
static void* ThreadEntry(void* arg){
ThreadEntryArg* argument=(ThreadEntryArg*)arg;
string ip=argument->ip;
int port=argument->port;
Handler handler=argument->handler;
TcpSocket client_sock=argument->client_sock;
while(1){
string req;
int ret=client_sock.Recv(req);
if(ret<0){
continue;
}
else if(ret==0){
printf("[%s:%d]客户端断连接!\n",ip.c_str(),port);
break;
}
printf("[%s:%d]客户端输入:%s\n",ip.c_str(),port,req.c_str());
string resp;
handler(req,resp);
client_sock.Send(resp);
}
client_sock.Close();
delete argument;
return NULL;
}
};
tcp_threadpool_server.hpp
#pragma once
#include"tcp_socket.hpp"
#include<pthread.h>
#include"threadpool.hpp"
#include<sys/syscall.h>
#include<unistd.h>
#include<stdio.h>
typedef void (*Handler)(const string& ip,string& ret);
struct Arg{
TcpSocket _sock;
string _ip;
int _port;
Handler _handler;
};
class MyStack:public Stack{
public:
MyStack(void* arg)
:Stack(arg)
{}
virtual void Entry()override
{
Arg *ret=(Arg*)_arg;
TcpSocket ArgSock=ret->_sock;
string ArgIp=ret->_ip;
int ArgPort=ret->_port;
Handler ArgHandler=ret->_handler;
while(1){
string msg;
int n=ArgSock.Recv(msg);
if(n<0){
continue;
}
else if(n==0){
printf("[%s:%d]客户端已经关闭!\n",ArgIp.c_str(),ArgPort);
break;
}
printf("[%s:%d]客户端输入:%s\n",ArgIp.c_str(),ArgPort,msg.c_str());
string ret;
ArgHandler(msg,ret);
if(ArgSock.Send(ret)==false)
continue;
}
ArgSock.Close();
delete ret;
}
};
class TcpThreadServer{
public:
TcpThreadServer()
:pool(10)
{}
~TcpThreadServer(){
_sock.Close();
}
bool Start(const string& ip,const int port,Handler handler){
if(_sock.Bind(ip,port)==false)
return false;
if(_sock.Listen()==false)
return false;
while(1){
Arg *NewArg=new Arg;
NewArg->_handler=handler;
if(_sock.Accept(&(NewArg->_sock),NewArg->_ip,NewArg->_port)==false)
continue;
printf("[%s:%d]客户端已连接!\n",NewArg->_ip.c_str(),NewArg->_port);
pool.AddStack(new MyStack((void*)NewArg));
}
}
private:
TcpSocket _sock;
ThreadPool pool;
};