范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

Go代码epollechoserver代码实现

  基于 epoll 系统调用实现非阻塞的echo server:
  这部分代码是 Go BIO/NIO探讨(7):IO多路复用之epoll 的附录
  package main  import (   "fmt"   "log"   "net"   "os"   "os/signal"   "syscall" )  func ipToSockaddrInet4(ip net.IP, port int) (syscall.SockaddrInet4, error) {   if len(ip) == 0 {     ip = net.IPv4zero   }   ip4 := ip.To4()   if ip4 == nil {     return syscall.SockaddrInet4{}, &net.AddrError{Err: "non-IPv4 address", Addr: ip.String()}   }   sa := syscall.SockaddrInet4{Port: port}   copy(sa.Addr[:], ip4)   return sa, nil }  func isError(ev uint32) bool {   return (ev&uint32(syscall.EPOLLERR)) > 0 || (ev&uint32(syscall.EPOLLHUP)) > 0 || (ev&syscall.EPOLLIN) == 0 }  func main() {   var (     family        = syscall.AF_INET     sotype        = syscall.SOCK_STREAM     _             = "tcp"     listenBacklog = syscall.SOMAXCONN     serverip      = net.IPv4(0, 0, 0, 0)     serverport    = 8080   )    // 创建套接字   sockfd, err := syscall.Socket(family, sotype, 0)   if err != nil {     panic(fmt.Errorf("fails to create socket: %s", err))   }    syscall.CloseOnExec(sockfd)   // epoll edge-triggered 模式支持nonblock   if err := syscall.SetNonblock(sockfd, true); err != nil {     syscall.Close(sockfd)     panic(fmt.Errorf("setnonblock error=%v", err))   }    // 接收到Ctrl+C信号后,关闭socket   c := make(chan os.Signal)   signal.Notify(c, os.Interrupt, syscall.SIGTERM)   go func() {     <-c     log.Println("r- Ctrl+C pressed in Terminal")      if err := syscall.Close(sockfd); err != nil {       log.Printf("Close sockfd %d fails, err=%v ", sockfd, err)     } else {       log.Printf("Server stopped successfully!!!")     }     // 收到信号后需要处理, 否则程序会永久hang住, 需要kill -9      // os.Exit 会导致所有goroutine都会立即停止执行     os.Exit(0)   }()    addr, err := ipToSockaddrInet4(serverip, serverport)   if err != nil {     panic(fmt.Sprintf("fails to convert address %s:%d to socket addr, err=%s", serverip, serverport, err))   }    if err := syscall.Bind(sockfd, &addr); err != nil {     panic(fmt.Sprintf("fails to bind socket %d to address %s:%d, err=%s",       sockfd,       serverip, serverport,       err))   }    if err := syscall.Listen(sockfd, listenBacklog); err != nil {     log.Printf("listen sockfd %d to addr error=%v ", sockfd, err)     panic(fmt.Sprintf("fails to listen socket %d", sockfd))   } else {     log.Printf("Started listening on %s:%d", serverip, serverport)   }    epfd, err := syscall.EpollCreate1(0)   if err != nil {     panic(fmt.Sprintf("create epoll instance fails, err=%s", err))   }   // 默认是 level-triggered,效率更高的poll   epEvent := syscall.EpollEvent{     Fd:     int32(sockfd),     Events: uint32(syscall.EPOLLIN) | uint32(-syscall.EPOLLET),   }    if err := syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, sockfd, &epEvent); err != nil {     panic(fmt.Errorf("epoll_ctl %v fails, err=%s", epfd, err))   }    events := make([]syscall.EpollEvent, 128, 128)   var buf [32 * 1024]byte    for {     // msec < 0, EpollWait 会被阻塞直到有一个 fd 可用     nReady, err := syscall.EpollWait(epfd, events, -1)     if err != nil {       log.Printf("epoll_wait error=%v ", err)       panic(fmt.Errorf("epoll_wait error=%v", err))     }      for i := 0; i < nReady; i++ {       ev := &events[i]       if isError(ev.Events) {         /* An error has occured on this fd, or the socket is not            ready for reading (why were we notified then?) */         log.Printf("epoll error: %s ", err)         // 取消监听         _ = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_DEL, int(ev.Fd), ev)         _ = syscall.Close(int(events[i].Fd))         continue       }        if ev.Fd == int32(sockfd) {         for {           // 监听套接字(server端套接字           clientfd, _, err := syscall.Accept(sockfd)           if err == syscall.EAGAIN || err == syscall.EWOULDBLOCK {             // 所有新创建的tcp conn均已被处理             break           }           // 设置为nonblock           if err := syscall.SetNonblock(clientfd, true); err != nil {             log.Printf("fails to set client socket %v as nonblock, err=%s ", clientfd, err)             continue           }           epEvent.Fd = int32(clientfd)           epEvent.Events = uint32(syscall.EPOLLIN) | uint32(-syscall.EPOLLET)           if err := syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, clientfd, &epEvent); err != nil {             log.Printf("register client socket %v fails, err=%s ", clientfd, err)             syscall.Close(clientfd)             continue           }         }       } else {         // 已连接套接字 tcp conn         for {           nRead, err := syscall.Read(int(ev.Fd), buf[:])           if err == syscall.EAGAIN || err == syscall.EWOULDBLOCK {             // 数据已经读完了             break           } else if err != nil {             log.Printf("fails to read data from sockfd %d, err=%v ", ev.Fd, err)             _ = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_DEL, int(ev.Fd), ev)             _ = syscall.Close(int(ev.Fd))             break           } else if nRead == 0 { // EOF             // Client closed             log.Printf("client sock %d closed ", ev.Fd)             _ = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_DEL, int(ev.Fd), ev)             _ = syscall.Close(int(ev.Fd))             break           } else {             log.Printf("read %d bytes from sock %d ", nRead, ev.Fd)             if _, err := syscall.Write(int(ev.Fd), buf[:nRead]); err != nil {               log.Printf("fails to write data %s into sockfd %d, err=%v ", buf[:nRead], sockfd, err)             }           }         }       }     }   } }

76人官宣签约!威少成最大赢家,篮网也有好消息,爵士大获成功今年NBA休赛期尽管有大型交易,即便米切尔和戈贝尔是全明星级别球员,但他们一人加盟森林狼,一人加盟骑士,也无法改变东西部格局。说白了今年休赛期没有出现任何改变联盟格局的决定,还是相杨鸣高兴早了!杜锋不可怕,这支球队才是辽宁队最大的卫冕障碍杨鸣高兴早了!杜锋不可怕,这支球队才是辽宁队最大的卫冕障碍!北京时间9月14日,漫长的CBA休赛期马上就要结束,新赛季的比赛已经进入了倒计时,从这个休赛期各支球队的操作来看,新赛季忍无可忍,戳破蔡斌谎言,球迷建议郎平3进宫忍无可忍,戳破蔡斌谎言,球迷建议郎平3进宫球迷都知道,刚刚结束的中国女排世联赛的表现,中国女排可以用2个字来形容,那就是糟糕,而主要暴露出来的问题,大家也是有目共睹,主要的原因就是83分钟绝杀!欧冠头号热门21逆转多特,哈兰德2场3球,拒绝庆祝北京时间9月15日凌晨,欧冠小组赛G组第2轮迎来一场焦点战,曼城主场面对一球落后,最终依靠斯通斯和哈兰德的联袂进球,以21逆转多特蒙德,取得2连胜积6分继续排名小组第一。最近几个赛黑色3分钟!热刺补时连丢2球,葡体破两大魔咒,C罗后悔吗在阿尔瓦拉德球场,热刺经历了黑色3分钟,保利尼奥戈麦斯的进球让葡萄牙体育队史首次以两连胜开局,热刺本赛季7场不败纪录被打破。此役是两队首次交锋,在欧冠小组赛首轮双双取胜之后,此役成西昌泸山一馆两碑寻旧事凉山社会考察5山腰间的奴隶社会博物馆今日游西昌市东南边的泸山风景区,见山腰间开阔处建有一座凉山彝族奴隶社会博物馆,遂进内参观。囿于生产力和相对闭塞的自然环境,世居大小凉山的彝族同胞,一千多年里一公安部10月1日起将进一步放宽私家车检验周期太平洋汽车网行业频道9月15日,我们从公安部交通管理局发布的官方信息中了解到,从10月1日起,我国将进一步放宽私家车检验周期。此次改革,将进一步优化调整非营运小微型载客汽车摩托车检李克强主持召开国务院常务会议李克强主持召开国务院常务会议决定进一步延长制造业缓税补缴期限加力助企纾困确定专项再贷款与财政贴息配套支持部分领域设备更新改造扩市场需求增发展后劲部署进一步稳外贸稳外资的举措助力经济邓超与世界冠军对打乒乓!激动到抬腿扑上桌,一旁孙俪大声嘲笑近日,邓超参演了电影中国乒乓,其工作室在社交平台上晒出一则,邓超片场分别与演员及世界冠军打乒乓球的视频,并配文道邓超练球大半年,输球只需3秒钟。画面中,邓超先是和演员切磋,几个暴扣60岁刘德华演唱会难掩老态,嗓子沙哑险失声,结尾演唱直接含泪刘德华线上演唱会来啦!不愧是从黄金时代一路走过来的巨星,刘德华演唱会开播1小时观看人次就火速破亿,中途一度突破3亿,直到最后结束依旧还有3亿人次持续在线观看。如同孙燕姿等歌手一样,面朝大海!平陆运河边上的绝美大学当代广西网讯(记者张友豪李姣梦)日前,平陆运河建设如火如荼,广西通江达海的百年梦想将照进现实。沿着平陆运河规划建设的路线一路向南,在钦江畔运河边,矗立着一所岭南风格鲜明东南亚风情浓
四十六岁了怀孕了,生还是不生?生吧,现在国家鼓励生三胎,况且你正是婚龄阶段,也正是生孩子的年龄。当下老龄化社会逐渐明显,年轻人的社会负担也逐渐加重,未来的劳动力也会逐渐缺乏,如果人口数量下降,会对整个社会有很大怎么让宝宝爱上辅食呢?最近也有很多宝妈留言说宝宝不爱吃辅食,总结了一下我家两个小饭霸的养成记,供大家参考一下哈。说在前面宝宝肯定会有个体差异,我们讲的喂养原则可能不适应于个别的宝宝,宝爸宝妈们也不要过于怀孕16周可以打掉吗?怀孕16周可以打掉吗?怀孕16周可以打掉,但由于胎儿月份比较大,所以需要到大型的正规医院住院进行引产。怀孕16周月份比较大,所以这个时候打掉胎儿,就需要到大型的正规医院住院进行引产想不明白,为什么那么多人看不惯陈亚男呢?中国几千年传统文化,讲究从一而终,不因富贵贫贱抛弃结发妻,不因功成名就而招摇过市。反过来看陈亚楠,依靠大衣哥名声能挣钱了百般刁难朱小伟,目的就一个,踹了朱小伟,直播在粉丝面前说老朱萌新买了个lol账号发现里面有DNF角色,大家帮我看看这样角色值多少钱?赚了吗?大家好,我是吃瓜。今天要说的话题是萌新买了个lol账号发现里面有DNF角色,大家帮我看看这样角色值多少钱?赚了吗?DNF账号买卖是正常的事情,而且由于当初玩家众多现在可以说很多人q和平精英如何用好AK?谢邀在和平精英中,AK不仅威力大,后坐力也不是一般人能掌控,所以玩家们都不是很喜欢用它。经常吐槽的一句话就是AK压不住,如果能为AK多一个配件槽,想都不想肯定是加一个握把了,但现阶澳门赛陈梦和王曼昱半决赛狭路相逢,陈梦能赢得复仇之战吗?WTT澳门赛,上半区女单半决赛对阵揭晓,世界第一陈梦将再次挑战新科世乒赛女单冠军王曼昱。这是两个人继世乒赛之后,再次在半决赛相遇。已经5连败于王曼昱的陈梦,能赢得复仇之战吗?下面也国足沦落到如今这般田地,问题到底出在哪里?要说好的球员,咱不是没有过,要说好的教练,咱们也不是没请过那么问题到底在哪呢?莫非真的是造化弄人,好的球员没遇到好的教练或者好教练没赶上好球员?足协,你来说说呗这问题到底谁出在哪了詹姆斯被质疑!威少被球队孤立,湖人队该何去何从呢?一个烂队,集齐一帮马上过气的老家伙,混个关注,增加点流量,赚点钱得了,还不自量力去争夺什么总冠军,战绩出现反差,实际上是战略认知上出现偏差,期望值定的过高,而球队人员结构的老化,已gucci都有哪些好看的鞋子推荐啊?其实Gucci的鞋子种类比较多,也被很多女孩子追捧,下面我就为大家推荐几款今年比较时尚的款式!1小白鞋,19FW水钻箭头,以前主要是小蜜蜂为主,每一个时代的小白鞋都在更新,这款小白男人多久洗一次头发最科学?别看洗头发简单,这里面学问大着呢。虽说男人头发短,修剪起来快,不像女人头发,理发难度高,洗头发也是比较麻烦。但是,不论男女,洗头发麻烦与否,都得掌握一定的频率。我认为间隔两天到三天