pthreadPool.hpp
#pragma once
#include<pthread.h>
#include<queue>
#include<iostream>
#include<string>
#include<cstring>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#define NUM 5
class Task{
private:
int _sock;
public:
Task(int sock)
:_sock(sock)
{
}
void run()
{
std::cout<<"run()"<<std::endl;
char buffer[128];
buffer[0] = 0;
int ret = recv( _sock, buffer , sizeof(buffer)-1 , 0);
if( ret < 0 )
{
std::cerr <<" recv error"<<std::endl;
exit(4);
}
else if(ret == 0)/*对端关闭了*/
{
std::cerr<<" Client quit" <<std::endl;
}
else{
buffer[ ret ] = 0;
std::cout << buffer <<std::endl;
std::string msg = "echo: ";
msg += buffer;
send(_sock , msg.c_str() , (int)msg.size(), 0);
}
}
~Task()
{
close(_sock);
}
};
class pthreadPool{
private:
std::queue<Task*> _que;
int _max_num;
pthread_mutex_t lock;
pthread_cond_t cond;
void LockQueue()
{
pthread_mutex_lock(&lock);
}
void UnlockQueue()
{
pthread_mutex_unlock(&lock);
}
bool IsEmpty()
{
return _que.size()==0;
}
void ThreadWait()
{
pthread_cond_wait(&cond,&lock);
}
void ThreadWakeUp()
{
pthread_cond_signal(&cond);
}
public:
pthreadPool(int max_num = NUM)
:_max_num(max_num)
{}
~pthreadPool()
{
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&cond);
}
static void* Routine(void* arg)
{
pthreadPool *this_p = (pthreadPool*) arg;
while(1)
{
this_p->LockQueue();
while(this_p->IsEmpty())
{
this_p->ThreadWait();
}
Task* t;
this_p->Get(t);
this_p->UnlockQueue();
t->run();
std::cout<<"task has run"<<std::endl;
delete t;
}
}
void pthreadPoolInit()
{
pthread_mutex_init(&lock,NULL);
pthread_cond_init(&cond,NULL);
std::cout<<"_max_num="<<_max_num<<std::endl;
pthread_t t;
for(int i =0 ; i < _max_num ; i++)
{
pthread_create(&t,NULL,Routine,(void*)this);
pthread_detach(t);
}
}
void Put(Task* in)
{
LockQueue();
_que.push(in);
UnlockQueue();
ThreadWakeUp();
std::cout<<"task has put "<<std::endl;
}
void Get(Task* &out)
{
Task* t = _que.front();
_que.pop();
out = t;
}
};
tcpClient.hpp
#ifndef _TCP_CLIENT_H
#define _TCP_CLIENT_H
#include<iostream>
#include<string>
#include<cstring>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#endif
class tcpClient{
private:
std::string _Ip;
int _port;
int _sock;
public:
tcpClient(std::string Ip="127.0.0.1",int port=8080)
:_Ip(Ip)
,_port(port)
{
}
void tcpClientInit()
{
_sock = socket(AF_INET, SOCK_STREAM, 0);
if(_sock < 0)
{
std::cerr << "socket error "<<std::endl;
exit(1);
}
struct sockaddr_in s;
s.sin_family = AF_INET;
s.sin_port = htons(_port);
s.sin_addr.s_addr = inet_addr(_Ip.c_str());
if( connect(_sock , (struct sockaddr*)&s ,sizeof(s) ) != 0 )
{
std::cerr<<" connect error "<<std::endl;
exit(2);
}
}
void start()
{
char buffer[128];
buffer[0] = 0;
int res = read( 0 , buffer, sizeof(buffer)-1 );
if( res < 0 )
{
std::cerr << "read error"<<std::endl;
exit(3);
}
res--;//处理read的换行符
buffer[res]= 0;
send(_sock , buffer, res,0 );
std::cout<<"##############"<<std::endl;
buffer[0] = 0;
res = recv(_sock, buffer , sizeof(buffer) -1 ,0);
buffer[res] = '\0';
std::cout<<buffer<<std::endl;
}
~tcpClient()
{
close(_sock);
}
};
tcpServer.hpp
#ifndef _TCP_SERVER_H
#define _TCP_SERVER_H
#include<iostream>
#include<string>
#include<cstring>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<pthread.h>
#include"pthreadPool.hpp"
#define BACKLOG 5
#endif
class tcpServer{
private:
int _port;
int _lsock;
pthreadPool* pool;
public:
tcpServer(int port)
:_port(port)
{
}
void tcpServerInit()
{
_lsock = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in s;
s.sin_family = AF_INET;
s.sin_port = htons(_port);
s.sin_addr.s_addr = (INADDR_ANY);
if( bind(_lsock,(struct sockaddr*)&s,sizeof(s)) < 0)
{
std::cerr<< "bind error" <<std::endl;
exit(1);
}
if( listen(_lsock,BACKLOG) < 0 )
{
std::cerr<< "listen error" <<std::endl;
exit(2);
}
pool = new pthreadPool(5);
pool ->pthreadPoolInit();
}
private:
void service(int sock)
{
char buffer[128];
while(true)
{
buffer[0] = 0;
int ret = recv( sock, buffer , sizeof(buffer)-1 , 0);
if( ret < 0 )
{
std::cerr <<" recv error"<<std::endl;
exit(4);
}
else if(ret == 0)/*对端关闭了*/
{
std::cerr<<" Client quit" <<std::endl;
break;
}
else{
buffer[ ret ] = 0;
std::cout << buffer <<std::endl;
std::string msg = "echo: ";
msg += buffer;
send(sock , msg.c_str() , (int)msg.size(), 0);
}
}
}
public:
void start()
{
while(true)
{
struct sockaddr_in end_point;
socklen_t len = sizeof(end_point);
int sock = accept(_lsock , (struct sockaddr*)&end_point,&len);
if(sock < 0)
{
std::cerr<<"sock error"<<std::endl;
continue;
}
std::cout<<"get a link..."<<std::endl;
Task* task = new Task(sock);
pool->Put(task);
}
}
~tcpServer()
{
close(_lsock);
}
};
tcpServer.cc
#include"tcpServer.hpp"
void Usage(std::string arg)
{
std::cout<<arg<<" Usage: port "<<std::endl;
}
int main(int argc ,char* argv[])
{
if( argc != 2 )
{
Usage(argv[0]);
exit(1);
}
tcpServer* tp = new tcpServer(atoi(argv[1]));
tp->tcpServerInit();
tp->start();
return 0;
}
tcpClient.cc
#include"tcpClient.hpp"
void Usage(std::string arg)
{
std::cout<<arg<<" Usage : Ip port "<<std::endl;
}
int main(int argc , char* argv[])
{
if( argc != 3 )
{
Usage(argv[0]);
exit(5);
}
tcpClient* tcpc = new tcpClient(argv[1],atoi(argv[2]));
tcpc->tcpClientInit();
tcpc->start();
return 0;
}