日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[c语言 ] 用libev 写个echo服务器

發(fā)布時(shí)間:2025/3/21 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [c语言 ] 用libev 写个echo服务器 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
放假了.同學(xué)都回家了,我是更情愿留久點(diǎn)在學(xué)校,一來學(xué)校安靜,二來免得火車太擠.? 這臨走前的幾天,放下了erlang,寫了一下c. 其實(shí)只是對比下erlang 寫socket服務(wù)器,和c寫socket服務(wù)器的異同.


說一下libev:? 點(diǎn)擊打開鏈接
Libev是一個(gè)event loop:向libev注冊感興趣的events,比如Socket可讀事件,libev會對所注冊的事件的源進(jìn)行管理,并在事件發(fā)生時(shí)觸發(fā)相應(yīng)的程序。 ? 對比另外一個(gè)更加出名的libevent,這個(gè)更加先進(jìn). 小巧輕量.? 源碼解讀就不獻(xiàn)丑了,一堆堆宏.我功力不夠去深層切入libev.官網(wǎng)有文檔,弄成pdf了,可以下載: http://d.yun.io/Y9ziuo


說一下環(huán)境: ubuntu 11.10 ,gcc4.4.6 ,libev 4.11,? code:block(vim,emacs黨...莫要黑,我用CB好久了,莫要離間!!!)

官方文檔是有個(gè)鍵盤輸入的demo,網(wǎng)上也有幾個(gè)用libev寫echo sever的,感覺都寫得很不錯,很全面.? 我還是參考他們寫個(gè)簡單,簡陋的試一下吧.

main.c 只有一個(gè)文件..呵呵

[cpp] view plain copy
  • #include?<stdio.h>??
  • #include?<netinet/in.h>??
  • #include?<ev.h>??
  • ??
  • #define?PORT?9999??
  • #define?BUFFER_SIZE?1024??
  • ??
  • ??
  • void?accept_cb(struct?ev_loop?*loop,?struct?ev_io?*watcher,?int?revents);??
  • ??
  • ??
  • void?read_cb(struct?ev_loop?*loop,?struct?ev_io?*watcher,?int?revents);??
  • ??
  • int?main()??
  • {??
  • struct?ev_loop?*loop?=?ev_default_loop(0);??
  • int?sd;??
  • struct?sockaddr_in?addr;??
  • int?addr_len?=?sizeof(addr);??
  • struct?ev_io?socket_accept;??
  • ??
  • //?創(chuàng)建socket的寫法,這里簡單處理,用INADDR_ANY?,匹配任何客戶端請求.這里寫法都一樣,沒什么特別的,直接copy都可以用??
  • if(?(sd?=?socket(PF_INET,?SOCK_STREAM,?0))?<?0?)??
  • {??
  • ??printf("socket?error");??
  • ??return?-1;??
  • }??
  • bzero(&addr,?sizeof(addr));??
  • addr.sin_family?=?AF_INET;??
  • addr.sin_port?=?htons(PORT);??
  • addr.sin_addr.s_addr?=?INADDR_ANY;??
  • if?(bind(sd,?(struct?sockaddr*)?&addr,?sizeof(addr))?!=?0)??
  • {??
  • ??printf("bind?error");??
  • }??
  • if?(listen(sd,?2)?<?0)??
  • {??
  • ??printf("listen?error");??
  • ??return?-1;??
  • }??
  • ??
  • ??
  • ??
  • //?初始化,這里監(jiān)聽了io事件,寫法參考官方文檔的??
  • ev_io_init(&socket_accept,?accept_cb,?sd,?EV_READ);??
  • ev_io_start(loop,?&socket_accept);??
  • ??
  • ??
  • while?(1)??
  • {??
  • ??ev_loop(loop,?0);??
  • }??
  • ??
  • return?0;??
  • }??
  • ??
  • ??
  • ??
  • //accept事件?的回調(diào)塊??
  • void?accept_cb(struct?ev_loop?*loop,?struct?ev_io?*watcher,?int?revents)??
  • {??
  • struct?sockaddr_in?client_addr;??
  • socklen_t?client_len?=?sizeof(client_addr);??
  • int?client_sd;??
  • ??
  • //分派客戶端的ev?io結(jié)構(gòu)??
  • struct?ev_io?*w_client?=?(struct?ev_io*)?malloc?(sizeof(struct?ev_io));??
  • ??
  • //libev的錯誤處理??
  • if(EV_ERROR?&?revents)??
  • {??
  • ??printf("error?event?in?accept");??
  • ??return;??
  • }??
  • ??
  • //accept,普通寫法??
  • client_sd?=?accept(watcher->fd,?(struct?sockaddr?*)&client_addr,?&client_len);??
  • if?(client_sd?<?0)??
  • {??
  • ??printf("accept?error");??
  • ??return;??
  • }??
  • ??
  • printf("someone?connected.\n");??
  • ??
  • //開始監(jiān)聽讀事件了,有客戶端信息就會被監(jiān)聽到??
  • ev_io_init(w_client,?read_cb,?client_sd,?EV_READ);??
  • ev_io_start(loop,?w_client);??
  • }??
  • ??
  • //read?數(shù)據(jù)事件的回調(diào)快??
  • void?read_cb(struct?ev_loop?*loop,?struct?ev_io?*watcher,?int?revents){??
  • char?buffer[BUFFER_SIZE];??
  • ssize_t?read;??
  • ??
  • if(EV_ERROR?&?revents)??
  • {??
  • ??printf("error?event?in?read");??
  • ??return;??
  • }??
  • ??
  • //recv普通socket寫法??
  • read?=?recv(watcher->fd,?buffer,?BUFFER_SIZE,?0);??
  • ??
  • if(read?<?0)??
  • {??
  • ??printf("read?error");??
  • ??return;??
  • }??
  • ??
  • //斷開鏈接的處理,停掉evnet就可以,同時(shí)記得釋放客戶端的結(jié)構(gòu)體!??
  • if(read?==?0)??
  • {??
  • ??printf("someone?disconnected.\n");??
  • ??ev_io_stop(loop,watcher);??
  • ??free(watcher);??
  • ??return;??
  • }??
  • else??
  • {??
  • ??printf("get?the?message:%s\n",buffer);??
  • }??
  • ??
  • //原信息返回,也可以自己寫信息,都一樣.最后記得置零??
  • send(watcher->fd,?buffer,?read,?0);??
  • bzero(buffer,?read);??
  • }??

  • 編譯后,運(yùn)行. 然后打開teminal ,?? telnet 127.0.0.1 9999? 就可以發(fā)送信息了.



    入手c的網(wǎng)絡(luò)編程,將來,對比下erlang的底層網(wǎng)絡(luò)通訊是怎么弄的


    ~~by dp

    總結(jié)

    以上是生活随笔為你收集整理的[c语言 ] 用libev 写个echo服务器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。