生活随笔
收集整理的這篇文章主要介紹了
网络编程套接字(四)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
網(wǎng)絡(luò)編程套接字(四)
文章目錄
- 網(wǎng)絡(luò)編程套接字(四)
- 一、實現(xiàn)tcp服務(wù)器多用戶版本(多進程、多線程、線程池版本)
一、實現(xiàn)tcp服務(wù)器多用戶版本(多進程、多線程、線程池版本)
#pragma once
#include "tcp_socket.hpp"
#include <functional>
#include <signal.h>typedef std
::function
<void (const std
::string
& req
,std
::string
* resp
)> Handler
;class TcpProcessServer
{public:TcpProcessServer(const std
::string
& ip
,uint16_t port
):ip_(ip
),port_(port
){signal(SIGCHLD
,SIG_IGN
);}void ProcessConnect(TcpSocket
& new_sock
,const std
::string
& ip
,uint16_t port
,Handler handler
){int ret
= fork();if(ret
> 0){new_sock
.Close();return;}else if(ret
== 0){while(1){std
::string req
;bool ret
= new_sock
.Recv(&req
);if(!ret
){printf("[client %s : %d] disconnect!\n",ip
.c_str(),port
);exit(0);}std
::string resp
;handler(req
,&resp
);new_sock
.Send(resp
);printf("[client %s : %d ] req : %s, resp : %s\n",ip
.c_str(),port
,req
.c_str(),resp
.c_str());}}else{perror("fork is error");}}bool Start(Handler handler
){CHECK_RET(listen_sock_
.Socket());CHECK_RET(listen_sock_
.Bind(ip_
, port_
));CHECK_RET(listen_sock_
.Listen(5));for (;;) {TcpSocket new_sock
;std
::string ip
;uint16_t port
= 0;if (!listen_sock_
.Accept(&new_sock
, &ip
, &port
)) {continue;}printf("[client %s:%d] connect!\n", ip
.c_str(), port
);ProcessConnect(new_sock
, ip
, port
, handler
);}return true;}private:TcpSocket listen_sock_
;std
::string ip_
;uint16_t port_
;
};
#pragma once
#include <functional>
#include <pthread.h>
#include "tcp_socket.hpp"typedef std
::function
<void (const std
::string
& req
, std
::string
* resp
)> Handler
;struct ThreadArg
{TcpSocket new_sock
;std
::string ip
;uint16_t port
;Handler handler
;
};class TcpThreadServer
{public:TcpThreadServer(const std
::string
& ip
, uint16_t port
) : ip_(ip
), port_(port
) {} bool Start(Handler handler
) {CHECK_RET(listen_sock_
.Socket());CHECK_RET(listen_sock_
.Bind(ip_
, port_
));CHECK_RET(listen_sock_
.Listen(5));for (;;) {ThreadArg
* arg
= new ThreadArg();arg
->handler
= handler
;bool ret
= listen_sock_
.Accept(&arg
->new_sock
, &arg
->ip
, &arg
->port
);if (!ret
) {continue;}printf("[client %s:%d] connect\n", arg
->ip
.c_str(), arg
->port
);pthread_t tid
;pthread_create(&tid
, NULL, ThreadEntry
, arg
);pthread_detach(tid
);}return true;}static void* ThreadEntry(void* arg
) {ThreadArg
* p
= reinterpret_cast<ThreadArg
*>(arg
);PthreadConnect(p
);p
->new_sock
.Close();delete p
;return NULL;}static void PthreadConnect(ThreadArg
* arg
) {for (;;) {std
::string req
;bool ret
= arg
->new_sock
.Recv(&req
);if (!ret
) {printf("[client %s:%d] disconnected!\n", arg
->ip
.c_str(), arg
->port
);break;}std
::string resp
;arg
->handler(req
, &resp
);arg
->new_sock
.Send(resp
);printf("[client %s:%d] req: %s, resp: %s\n", arg
->ip
.c_str(),arg
->port
, req
.c_str(), resp
.c_str());}}private:TcpSocket listen_sock_
;std
::string ip_
;uint16_t port_
;
};
- 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>
#include <functional>typedef std
::function
<void (const std
::string
& req
,std
::string
* resp
)> Handler
;struct Arg
{TcpSocket sock_
;std
::string _ip
;uint16_t _port
;Handler _handler
;
};class MyTask:public Task
{public:MyTask(void* arg
):arg_(arg
){}virtual void Run()override
{Arg
*arg
= (Arg
*)arg_
;TcpSocket newsock_
= arg
->sock_
;std
::string ArgIp
= arg
->_ip
;int ArgPort
= arg
->_port
;Handler ArgHandler
= arg
->_handler
;while(1){std
::string msg
;int n
= newsock_
.Recv(&msg
);if(n
< 0){continue;}else if(n
== 0){printf("[%s:%d]客戶端已經(jīng)關(guān)閉!\n",ArgIp
.c_str(),ArgPort
);break;}printf("[%s:%d]客戶端輸入:%s\n",ArgIp
.c_str(),ArgPort
,msg
.c_str());std
::string resp
;ArgHandler(msg
,&resp
);if(newsock_
.Send(resp
) == false)continue;}newsock_
.Close();delete arg
;}private:void* arg_
;
};class TcpThreadPoolServer
{public:TcpThreadPoolServer(const std
::string ip
,uint16_t port
):pool(10),ip_(ip
),port_(port
){}~TcpThreadPoolServer(){sock_
.Close();}bool Start(Handler handler
){if(sock_
.Socket() == false)return false;cout
<<__LINE__<<endl
;if(sock_
.Bind(ip_
,port_
) == false)return false;cout
<<__LINE__<<endl
;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
.AddTask(new MyTask((void*)NewArg
));}}private:TcpSocket sock_
;ThreadPool pool
;std
::string ip_
;uint16_t port_
;
};
總結(jié)
以上是生活随笔為你收集整理的网络编程套接字(四)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。