단일 프로 세 스 지원 높 은 병행
linux 서버 에서:
clients:20001 established:20000
데모 코드 는 다음 과 같 습 니 다.
#include<sys/types.h>
#include<sys/socket.h>
#include<errno.h>
#include<string.h>
#include<sys/ioctl.h>
#include<netinet/in.h>
#include<sys/epoll.h>
#include<iostream>
using namespace std;
int main(int argc, char** argv)
{
if(argc <= 2){
cout << "Usage: " << argv[0] << " <port> <max_clients>" << endl
<< " port: the listening port." << endl
<< " max_clients: the max accept clients." << endl;
return -1;
}
int port = atoi(argv[1]);
int max_clients = atoi(argv[2]);
cout << "port:" << port << " max_clients:" << max_clients << " pid:" << getpid() << endl;
int server_socket = socket(PF_INET, SOCK_STREAM, 0);
if(server_socket == -1){
cout << "init socket error: " << strerror(errno) << endl;
exit(-1);
}
cout << "init socket success: fd=" << server_socket << "!" << endl;
int flag;
if(ioctl(server_socket, FIONBIO, &flag) == -1){
cout << "set socket to un-blocked error: " << strerror(errno) << endl;
exit(-1);
}
cout << "set socket to non-block mode success!" << endl;
sockaddr_in addr;
memset(&addr, 0, sizeof(sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
// bind
if(bind(server_socket, (const sockaddr*)&addr, sizeof(sockaddr)) == -1){
cout << "socket bind error: " << strerror(errno) << endl;
exit(-1);
}
cout << "bind socket success!" << endl;
if(listen(server_socket, 10) == -1){
cout << "socket listen error: " << strerror(errno) << endl;
exit(-1);
}
cout << "listen socket success!" << endl;
int epoll = epoll_create(max_clients);
if(epoll == -1){
cout << "create event poll error: " << strerror(errno) << endl;
exit(-1);
}
cout << "create event poll success: fd=" << epoll << "!" << endl;
if(true){
epoll_event ev;
memset(&ev, 0, sizeof(epoll_event));
ev.events = EPOLLIN | EPOLLOUT; // focus on read|write event.
ev.data.fd = server_socket;
if(epoll_ctl(epoll, EPOLL_CTL_ADD, server_socket, &ev) == -1){
cout << "event poll ctl error: " << strerror(errno) << endl;
exit(-1);
}
cout << "event poll ctl success!" << endl;
}
epoll_event* ee = new epoll_event[max_clients];
for(;;){
int active_fds = epoll_wait(epoll, ee, max_clients, 100);
if(active_fds == -1){
cout << "event poll wait error: " << strerror(errno) << endl;
exit(-1);
}
cout << "event poll wait success: active_fds=" << active_fds << "!" << endl;
for(int i = 0; i < active_fds; i++){
// if client is coming.
if(ee[i].data.fd == server_socket){
int client = accept(server_socket, (sockaddr*)NULL, NULL);
if(client == -1){
cout << "accept client error: " << strerror(errno) << endl;
exit(-1);
}
cout << "accept client success: client=" << client << "!" << endl;
epoll_event ev;
memset(&ev, 0, sizeof(epoll_event));
ev.events = EPOLLIN;
ev.data.fd = client;
if(epoll_ctl(epoll, EPOLL_CTL_ADD, client, &ev) == -1){
cout << "client event poll ctl error: " << strerror(errno) << endl;
exit(-1);
}
cout << "client event poll ctl success!" << endl;
}
// do read-write
else{
int client = ee[i].data.fd;
// read
char buffer[1024];
int len;
if((len = read(client, buffer, sizeof(buffer))) <= 0){
cout << "read from client error: " << strerror(errno) << endl;
exit(-1);
}
cout << "read from client success: " << len << "bytes received!" << endl;
// write
char msg[] = "server is ok!";
if(send(client, msg, sizeof(msg), 0) <= 0){
cout << "write to client error: " << strerror(errno) << endl;
exit(-1);
}
cout << "write to client success!" << endl;
}
}
}
cout << "server cleanup and exit." << endl;
close(epoll);
close(server_socket);
return 0;
}
아 날로 그 클 라 이언 트, 시간 에 맞 춰 HTTP 요청 보 내기:
#include<signal.h>
#include<errno.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
void on_signal_active(int sno)
{
cout << "get a signal: " << sno
<< ", SIGINT=" << SIGINT << ", SIGTERM=" << SIGTERM << endl;
if(sno == SIGINT || sno == SIGTERM){
cout << "get a exit signal, exit" << endl;
exit(0);
}
}
class Client
{
private:
int client;
public:
Client(){
client = 0;
}
~Client(){
if(client > 0){
close(client);
}
}
bool initialize(int id, char* host, int port){
cout << "#" << id << ":" << "client start..." << endl;
cout << "#" << id << ":" << "register the signal function" << endl;
signal(SIGINT, on_signal_active);
signal(SIGTERM, on_signal_active);
client = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(client < 0){
cout << "#" << id << ":" << "init socket error!" << "msg: " << strerror(errno) << endl;
return false;
}
cout << "#" << id << ":" << "socket init success" << endl;
sockaddr_in server_address;
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr(host);
server_address.sin_port = htons(port);
if(connect(client, (sockaddr*)&server_address, sizeof(sockaddr_in)) < 0){
cout << "#" << id << ":" << "connect to server error." << "msg: " << strerror(errno) << endl;
return false;
}
cout << "#" << id << ":" << "socket connect success" << endl;
return true;
}
bool run(int id, char* host){
// HTTP request
if(true){
stringstream ss(stringstream::in | stringstream::out);
string s0x20 = string(1, (char)0x20);
string sCRLF = string(1, (char)0x0D) + string(1, (char)0x0A);
ss << string("GET") << s0x20 // Command: GET 47 45 54 20
<< string("/index.html") << s0x20 // URI: / 2F 20
<< string("HTTP/1.1") << sCRLF // ProtocolVersion: HTTP/1.1 48 54 54 50 2F 31 2E 31 0D 0A
<< string("Host:") << s0x20 << string(host) << sCRLF // Host:www.baidu.com.. 48 6F 73 74 3A 20 77 77 77 2E 62 61 69 64 75 2E 63 6F 6D 0D 0A
<< string("Connection:") << s0x20 << string("keep-alive") << sCRLF // Connection: keep-alive.. 43 6F 6E 6E 65 63 74 69 6F 6E 3A 20 6B 65 65 70 2D 61 6C 69 76 65 0D 0A
<< string("User-Agent:") << s0x20 << string("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.162 Safari/535.19") << sCRLF // UserAgent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.162 Safari/535.19
<< string("Accept:") << s0x20 << string("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") << sCRLF//Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
<< string("Accept-Encoding:") << s0x20 << string("gzip,deflate,sdch") << sCRLF//Accept-Encoding: gzip,deflate,sdch
<< string("Accept-Language:") << s0x20 << string("zh-CN,zh;q=0.8") << sCRLF//Accept-Language: zh-CN,zh;q=0.8
<< string("Accept-Charset:") << s0x20 << string("GBK,utf-8;q=0.7,*;q=0.3") << sCRLF//Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3
<< string("Cookie:") << s0x20 << string("BAIDUID=3BABFCA8602431FA83A9AFBE4FBD6F85:FG=1;") << s0x20 << string("MCITY=-158%3A") << sCRLF//Cookie: BAIDUID=3BABFCA8602431FA83A9AFBE4FBD6F85:FG=1; MCITY=-158%3A
// << string("Key:") << s0x20 << string("Value") << sCRLF //Key: Value
<< sCRLF; //HeaderEnd: CRLF
ss.seekg(0, ios::end);
int len = ss.tellg();
ss.seekg(0, ios::beg);
char* buffer = new char[len];
ss.read(buffer, len);
int ret = send(client, buffer, len, 0);
delete buffer;
if(ret <= 0){
cout << "send HTTP request error" << endl;
return false;
}
cout << "send HTTP request success" << endl;
}
// HTTP response
if(true){
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
if(read(client, buffer, sizeof(buffer)) <= 0){
cout << "receive HTTP response error" << "msg: " << strerror(errno) << endl;
return false;
}
cout << "receive HTTP reponse success" << "msg: " << strerror(errno) << endl;
}
return true;
}
};
int main(int argc, char** argv)
{
int i = 0;
int id = 0;
if(argc <= 3){
cout << "Usage: " << argv[0] << " <client_count> <host> <port>" << endl
<< " client_count: the client count to run." << endl
<< " host: the host to connect to." << endl
<< " port: the port to connect to." << endl;
return -1;
}
int client_count = atoi(argv[1]);
char* host = argv[2];
int port = atoi(argv[3]);
while(true){
Client clients[client_count];
for(int j = 0; j < client_count; j++){
Client& client = clients[j];
if(!client.initialize(++i, host, port)){
goto error;
}
}
while(true){
for(int j = 0; j < client_count; j++){
Client& client = clients[j];
if(!client.run(++id, host)){
goto error;
}
}
}
error:
cout << "server error, reinitialize all " << client_count << " clients" << endl;
usleep(10 * 1000 * 1000);
}
return 0;
}
통계 연결 스 크 립 트:
#!/bin/bash
#vi /bin/status
#################################################################################################
#
if [ $# -lt 2 ]; then
echo "Usage: $0 <sleep_time> <port>";
echo " <sleep_time> the sleep time in seconds.";
echo " <port> to display the program which listening at the specified port.";
echo " e.g. $0 3 80";
exit -1;
fi
sleep_time=$1
port=$2
echo "sleep_time:${sleep_time}s"
for((i=0;;i++))
do
program_listening=`netstat -ntlp|grep ${port}|awk -F "LISTEN" '{print $2}'|awk '{print $1}'`
if [ -z "${program_listening}" ]; then
program_listening="None";
fi
nginx_master_pid=`ps aux|grep nginx|grep master|awk '{print $2}'`
if [ -z "${nginx_master_pid}" ]; then
nginx_master_pid="0";
fi
nginx_origin_pid=`ps aux|grep nginx|grep bin|awk '{print $2}'`
if [ -z "${nginx_origin_pid}" ]; then
nginx_origin_pid=`ps aux|grep nginx|grep winlin|awk '{print $2}'`
if [ -z "${nginx_origin_pid}" ]; then
nginx_origin_pid="0";
fi
fi
if [ ${nginx_origin_pid} == ${nginx_master_pid} ]; then
# if origin equals to master, the origin is master actually.
nginx_origin_pid="0";
fi
nginx_worker_pid=`ps aux|grep nginx|grep worker|awk '{print $2}'`
if [ -z "${nginx_worker_pid}" ]; then
nginx_worker_pid="0";
fi
local_ip_address=`/sbin/ifconfig|grep "inet\ "|awk 'NR==1 {print $2}'|awk -F ':' '{print $2}'`
established_clients=`netstat -nt|grep ESTABLISHED|grep "0\ ${local_ip_address}:${port}\ "|wc -l`
all_clients=`netstat -nat|grep "0\ ${local_ip_address}:${port}\ "|wc -l`
echo "nginx-origin:${nginx_origin_pid} master:${nginx_master_pid} worker:${nginx_worker_pid} listen-${port}:(${program_listening}) all:${all_clients} established:${established_clients}"
sleep ${sleep_time}
done
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.