libevent多執行緒伺服器
伺服器端程式碼:
完整程式碼地址:https://github.com/Addision/test_libevent_thrd_server#include "lib_net.h" #include "lib_thread.h" #include "lib_public.h" #include<event.h> #include<event2/util.h> #define BACKLOG 10 #define MAX_EVENTS 500 char ip[24]; short port; struct st_listenserv { int sockfd; struct event *ev_listen; struct event_base *base; }; struct st_connserv { int clifd; struct event_base *base; struct event *ev_read; struct event *ev_write; char buf[1024]; }; void initsocket(struct st_listenserv *listenserv); void accept_cb(int fd, short events, void *arg); void read_cb(int fd, short events, void *arg); void send_cb(int fd, short events, void *arg); void start_thrd(int fd); void thrd_readwrite(int sockfd); void release_read(struct st_connserv *connserv); void release_write(struct st_connserv *connserv); int main(int argc, char *argv[]) { if(argc < 1) { perror("input server port"); return -1; } memcpy(ip, argv[1], 24); port = atoi(argv[2]); struct st_listenserv listenserv; initsocket(&listenserv); listenserv.base = event_base_new(); listenserv.ev_listen = event_new(listenserv.base, listenserv.sockfd,EV_READ | EV_PERSIST,accept_cb,NULL); event_add(listenserv.ev_listen, NULL); event_base_dispatch(listenserv.base); } void initsocket(struct st_listenserv *listenserv) { listenserv->sockfd = lib_tcpsrv_init(ip,port); if(listenserv->sockfd < 0) { perror("server create socket error"); return; } if(lib_set_nonblock(listenserv->sockfd) < 0) { perror("set nonblock error"); return; } printf("init socket ok\n"); } void accept_cb(int fd, short events, void *arg) { struct sockaddr_in cin; socklen_t socklen = sizeof(cin); int clifd = lib_tcpsrv_accept(fd, &cin); if(clifd <0) { perror("accept error"); } if(lib_set_nonblock(clifd) < 0) { perror("set nonblock error"); return; } printf("new conneciotn [%s:%d]\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port)); start_thrd(clifd); } void start_thrd(int fd) { pthread_t pid; lib_thread_create(&pid, thrd_readwrite, (void*)fd, 1); } void thrd_readwrite(int sockfd) { struct st_connserv connserv; connserv.clifd = sockfd; connserv.base = event_base_new(); connserv.ev_read = event_new(connserv.base, connserv.clifd, EV_READ|EV_PERSIST, read_cb, &connserv); event_add(connserv.ev_read,NULL); event_base_dispatch(connserv.base); } void read_cb(int fd, short events, void *arg) { struct st_connserv *conn = (struct st_connserv*)arg; int recvlen = lib_tcp_recv(conn->clifd, conn->buf,1024, -1); if(recvlen < 0) { perror("recv error"); close(conn->clifd); release_read(conn); } printf("recv data:%s\n", conn->buf); conn->ev_write = event_new(conn->base, conn->clifd, EV_WRITE, send_cb, conn); event_add(conn->ev_write, NULL); } void send_cb(int fd, short events, void *arg) { struct st_connserv *conn = (struct st_connserv*)arg; int sendlen = lib_tcp_send(conn->clifd, conn->buf, 1024); if(sendlen < 0) { perror("send error"); close(conn->clifd); release_write(conn); } } void release_read(struct st_connserv *connserv) { if(connserv == NULL) { return; } event_del(connserv->ev_read); event_base_loopexit(connserv->base, NULL); if(NULL != connserv->ev_read){ free(connserv->ev_read); } event_base_free(connserv->base); free(connserv); } void release_write(struct st_connserv *connserv) { if(connserv != NULL) { event_del(connserv->ev_write); free(connserv->ev_write); free(connserv); } }
簡單客戶端程式碼:
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #define PORT 9999 #define IPADDR "127.0.0.1" int main(int argc, char *argv[]) { /* 套接字描述符*/ int sockfd, numbytes; char buf[1024]; struct sockaddr_in their_addr; if ((sockfd = socket(AF_INET,SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } their_addr.sin_family = AF_INET; /* 網路位元組順序,短整型*/ their_addr.sin_port = htons(PORT); their_addr.sin_addr.s_addr = inet_addr(IPADDR); /* 將結構剩下的部分清零*/ bzero(&(their_addr.sin_zero),8); if(connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) { perror("connect"); exit(1); } int ret = send(sockfd, "123456", 6,0); if(ret > 0) { printf("send ok\n"); } ret = recv(sockfd, buf, 1024,0); if(ret > 0) { printf("recv data %s\n", buf); } getchar(); return 0; }
相關推薦
libevent多執行緒伺服器
伺服器端程式碼: #include "lib_net.h" #include "lib_thread.h" #include "lib_public.h" #include<event.h> #include<event2/util.h> #
multi-reactor伺服器模型的C++封裝類(libevent+多執行緒實現)
最近在看memcached的原始碼,覺得它那種libevent+多執行緒的伺服器模型(multi-reactor)真的很不錯,我將這個模型封裝成一個C++類,根據我的簡單測試,這個模型的效率真的很不錯,歡迎大家試用。 這個類的使用方法很簡單(缺點是不太靈活),只
使用libevent多執行緒驗證Linux上的伺服器"驚群"現象
什麼是驚群現象? 驚群(thundering herd)是指,只有一個子程序能獲得連線,但所有N個子程序卻都被喚醒了,這種情況將使效能受損。 舉一個很簡單的例子,當你往一群鴿子中間扔一塊食物,雖然最終只有一個鴿子搶到食物,但所有鴿子都會被驚動來爭奪,沒有搶到食物的鴿子只好回
Qt TCP通訊,多執行緒伺服器端
相信許多初學Qt的同學都會和我一樣遇到這樣的問題: 一、Qt TCP通訊在使用nextPendingConnect後,伺服器端就只會與最後接入的客戶端通訊,這個時候就會考慮繼承QThread實現多執行緒,從而實現多個客戶端與伺服器端通訊,每當一個新的客戶端連線時,通過標識碼socke
windows下Libevent +多執行緒(負載均衡分配法) 之檔案傳輸
一、先說一下服務端的流程: 1、主執行緒負責監聽客戶端的連線; 2、當有客戶端連線時,主執行緒通過管道向相應的子執行緒傳送監聽套接字描述符,子執行緒通過負載均衡法選擇出來; 3、當主執行緒傳送監聽描述符時,子執行緒的讀管道回撥函式會被回撥; 4、子執行緒為收到的監聽描述符設定讀取
用 threading 寫多執行緒伺服器
import socket import threading server = socket.socket() server.bind(("127.0.0.1",8899)) server.listen(1000) def func(conn): while T
多執行緒伺服器
#coding=utf-8 from socket import * from threading import Thread from time import sleep # 處理客戶端的請求並執行事情 def dealWithClient(newSocket,destAddr):
Qt 多執行緒伺服器與客戶端
文章目錄 思路 伺服器 myserver.h myserver.cpp mythread.h mythread.cpp mysocket.h mysocket.cpp
C網路程式設計--多執行緒伺服器
伺服器主要用的是socket(雙向的通訊的一端),bind(繫結),listen(切換監聽狀態),accept(與客戶端取得連線) 將accept放入多執行緒,可以多個客戶端連線 #include <stdio.h> //標準輸入輸出 #incl
windows下 Libevent +多執行緒 實現檔案傳輸
1、模式:來一個客戶端連線進來,服務端就開啟一個處理執行緒。 2、缺點:對大量的客戶端情況不適用。大量客戶端的情況需要加入執行緒管理機制。 // LibeventTest.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #incl
TCP/IP網路程式設計 基於Linux程式設計_4 --多執行緒伺服器端的實現
執行緒基本概念 前面我們講過多程序伺服器,但我們知道它開銷很大,因此我們才引入執行緒,我們可以把它看成是一種輕量級程序。它相比程序有如下幾個優點: 執行緒的建立和上下文切換開銷更小且速度更快。 執行緒間交換資料時無需特殊技術。 程序:在作業系統構成
linux tcp多執行緒伺服器與客戶端程式設計例項
伺服器端: #include<iostream> #include<arpa/inet.h> #include<sys/socket.h> #include<cstdlib> #include<cstdio> #i
【muduo】多執行緒伺服器的適用場合與程式設計模型
文章目錄 一、程序與執行緒 1、程序的概念 2、關於程序的一個形象比喻(人) 3、執行緒的概念 二、多程序和多執行緒的適用場景 1、需要頻繁建立銷燬的優先用執行緒 2、
基於非阻塞socket的多執行緒伺服器的實現------一個伺服器如何與多個客戶端進行通訊?
我們首先來看服務端(涉及非阻塞socket和多執行緒): #include <stdio.h> #include <winsock2.h> #include <windows.h> #pragma comment(li
Linux多執行緒伺服器-門禁打卡系統
原始碼地址 系統採用一個伺服器+兩種客戶端(網頁+APP),執行在樹莓派2上 OpenDoorMultiThreadServer OpenDoorMultiThreadServer 實驗室門禁打卡系統 1、mydb是操作資料庫Mysql類,表示每個
多執行緒伺服器模型
本文主要講我個人在多執行緒開發方面的一些粗淺經驗。總結了一兩種常用的執行緒模型,歸納了程序間通訊與執行緒同步的最佳實踐,以期用簡單規範的方式開發多執行緒程式。 文中的“多執行緒伺服器”是指執行在 Linux 作業系統上的獨佔式網路應用程式。硬體平臺為 Int
tcp/ip 多執行緒伺服器端的實現(參考tcp/ip網路程式設計)
執行緒的切換比程序快的多,因為它不需要切換資料區和堆 共享資料區和堆可以用來交換資訊 一、執行緒的建立 pthread_create()函式 #include<pthread.h> int prthread_create(pthread * thread,c
Python TCP 客戶端(配合socket多執行緒伺服器)
''' Python TCP 客戶端(配合socket多執行緒伺服器) by 鄭瑞國 1、建立網路套接字c 2、建立網路連線 3、收發資訊 ''' import socket c = socket.socket() #1、建立網路套接字c c.connect(('127.
Python socket TCP多執行緒伺服器
''' Python socket TCP多執行緒伺服器 by 鄭瑞國 1、建立網路套接字s 2、繫結地址 3、監聽 4、接受客戶端連線 5、多執行緒處理客戶端訊息 ''' import socket import threading s = socket.socket()
java網路程式設計:9、基於TCP的socket程式設計(二)伺服器端迴圈監聽接收多個客戶端_多執行緒伺服器程式
宣告:本教程不收取任何費用,歡迎轉載,尊重作者勞動成果,不得用於商業用途,侵權必究!!! 文章目錄 一、核心程式碼編寫 1、伺服器端程式的編寫 2、客戶端程式的編寫 3、測試列印輸出 二、系列文章(java網路程式設計) 上篇講了基於tcp的程式設計的一些基礎知識