服务器端:
#include <iostream>
#include <thread>
#include <vector>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace std;
class ThreadPool {
public:
ThreadPool(int threadNum):m_threadNum(threadNum) {
m_isRunning = true;
for (int i=0; i<threadNum; i++) {
m_threads.emplace_back(bind(&ThreadPool::runInThread, this));
}
}
~ThreadPool() {
if(m_isRunning) {
stop();
}
}
void stop() { {
lock_guard<mutex> locker(m_mutex);
m_isRunning = false;
}
m_cond.notify_all();
for (auto& thread : m_threads) {
thread.join();
}
}
void addTask(function<void()> task) { {
lock_guard<mutex> locker(m_mutex);
m_tasks.emplace(task);
}
m_cond.notify_one();
}
private: void runInThread() {
while(m_isRunning) {
function<void()> task; {
unique_lock<mutex> locker(m_mutex);
m_cond.wait(locker, [this] {
return !m_isRunning || !m_tasks.empty();
}
);
if(!m_tasks.empty()) {
task = m_tasks.front();
m_tasks.pop();
}
}
if(task) {
task();
}
}
}
private: int m_threadNum;
vector<thread> m_threads;
queue<function<void()>> m_tasks;
mutex m_mutex;
condition_variable m_cond;
bool m_isRunning;
}
;
class TcpServer {
public: TcpServer(int port):m_port(port) {
m_listenfd = socket(AF_INET, SOCK_STREAM, 0);
if(m_listenfd < 0) {
cerr << "socket error" << endl;
exit(1);
}
struct sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port = htons(m_port);
if(bind(m_listenfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
cerr << "bind error" << endl;
exit(1);
}
if(listen(m_listenfd, 5) < 0) {
cerr << "listen error" << endl;
exit(1);
}
m_threadPool = new ThreadPool(4);
}
~TcpServer() {
delete m_threadPool;
}
void start() {
struct sockaddr_in clientAddr;
socklen_t len = sizeof(clientAddr);
while(1) {
int connfd = accept(m_listenfd, (struct sockaddr*)&clientAddr, &len);
if(connfd < 0) {
cerr << "accept error" << endl;
continue;
}
cout << "client ip: " << inet_ntoa(clientAddr.sin_addr) << " port: " << ntohs(clientAddr.sin_port) << endl;
m_threadPool->addTask(bind(&TcpServer::doTask, this, connfd));
}
}
private: void doTask(int connfd) {
char buf[1024];
while(1) {
int ret = read(connfd, buf, sizeof(buf));
if(ret == 0) {
cout << "client close" << endl;
break;
} else if(ret == -1) {
cerr << "read error" << endl;
break;
}
cout << "recv msg: " << buf << endl;
write(connfd, buf, ret);
}
close(connfd);
}
private: int m_port;
int m_listenfd;
ThreadPool* m_threadPool;
}
;
int main() {
TcpServer server(8080);
server.start();
return 0;
}
客户端:#include <iostream>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>using namespace std;
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0) {
cerr << "socket error" << endl;
return 1;
}
struct sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
serverAddr.sin_port = htons(8080);
if(connect(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
cerr << "connect error" << endl;
return 1;
}
while(1) {
char buf[1024];
cout << "send msg: ";
cin >> buf;
write(sockfd, buf, sizeof(buf));
int ret = read(sockfd, buf, sizeof(buf));
if(ret == 0) {
cout << "server close" << endl;
break;
} else if(ret == -1) {
cerr << "read error" << endl;
break;
}
cout << "recv msg: " << buf << endl;
}
close(sockfd);
return 0;
}
本文暂时没有评论,来添加一个吧(●'◡'●)