UNIX TCP回射服务器/客户端之使用epoll模型的服务器

程序简介:这是一个运用epoll系列函数进行IO复用的服务器模型。它是目前UNIX与LINUX平台上效率最高,最受欢迎的IO复用传输模型。

其他的不说了,直接粘贴代码吧!

服务器端:

#include "my_unp.h"  int main(void)    
{    int listenfd, connfd, sockfd, epfd;  int i, maxi, nfds;  ssize_t n;    char buf[MAXLINE];    socklen_t clilen;    struct sockaddr_in cliaddr;    struct sockaddr_in servaddr;  //声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件    struct epoll_event ev, events[256];    //创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大    epfd = Epoll_create(256);  //创建用于TCP协议的套接字      listenfd = Socket(AF_INET, SOCK_STREAM, 0);    memset(&servaddr, 0, sizeof(servaddr));    servaddr.sin_family = AF_INET;    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);    servaddr.sin_port = htons(SERV_PORT);    //把socket和socket地址结构联系起来    Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));  //开始监听LISTENQ端口    Listen(listenfd, LISTENQ);  //设置与要处理的事件相关的文件描述符和事件  ev.data.fd = listenfd;    ev.events = EPOLLIN|EPOLLET;    //注册epoll事件    Epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd,&ev);    maxi = 0;  while(1)  {    //等待epoll事件的发生    //返回需要处理的事件数目nfds,如返回0表示已超时。    nfds = Epoll_wait(epfd, events, 20, 500);    //处理所发生的所有事件    for(i=0; i < nfds; ++i)    {    //如果新监测到一个SOCKET用户连接到了绑定的SOCKET端口,建立新的连接。    if(events[i].data.fd == listenfd)    {    connfd = Accept(listenfd,(SA*)&cliaddr, &clilen);    printf("connection from %s, port %d.\n",        Inet_ntop(AF_INET, (void*)&cliaddr.sin_addr, buf, sizeof(buf)),        ntohs(cliaddr.sin_port));    //设置用于读操作的文件描述符和事件  ev.data.fd = connfd;    ev.events = EPOLLIN|EPOLLET;    //注册事件  Epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);  }    //如果是已经连接的用户,并且收到数据,那么进行读入。    else if(events[i].events & EPOLLIN)    {    sockfd = events[i].data.fd;  if ( sockfd < 0 )    continue;    n = read(sockfd, buf, MAXLINE);  if ( n < 0)    {      // Connection Reset:你连接的那一端已经断开了,  //而你却还试着在对方已断开的socketfd上读写数据!    if (errno == ECONNRESET)    {    Close(sockfd);    events[i].data.fd = -1;    }    else    error_quit("read error");  }    //如果读入的数据为空    else if ( n == 0 )  {    Close(sockfd);    events[i].data.fd = -1;    }    else  {  //设置用于写操作的文件描述符和事件  ev.data.fd = sockfd;  ev.events = EPOLLOUT|EPOLLET;  //注册事件  Epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);  }  }  //如果有数据发送  else if(events[i].events & EPOLLOUT)  {  sockfd = events[i].data.fd;  Writen(sockfd, buf, n);    //设置用于读操作的文件描述符和事件  ev.data.fd = sockfd;  ev.events = EPOLLIN|EPOLLET;  //注册事件  Epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);  }  }  }  return 0;    
} 


客户端的测试例子:

#include "my_unp.h" 

void str_cli(FILE *fp, int sockfd)  
{  
 char sendline[MAXLINE], recvline[MAXLINE];  
 int len;

 //从终端获取一行字符串,将其写入套接字  
 //然后从套接字一行字符串,将其写入终端  
 while( Fgets(sendline, MAXLINE, fp) != NULL )  
 {  
  Writen(sockfd, sendline, strlen(sendline));  
  len = Read(sockfd, recvline, MAXLINE);
  if( len == 0 )  
   error_quit("str_cli: server terminated prematurely");  
  recvline[len] = 0;
  Fputs(recvline, stdout);  
 }  

int main(int argc, char **argv)  
{  
 int sockfd;  
 struct sockaddr_in servaddr;  
 if( argc != 2 )  
  error_quit("usage: client <IPAddress>"); 

 //创建用于TCP协议的套接字  
 sockfd = Socket(AF_INET, SOCK_STREAM, 0);  
 memset(&servaddr, 0, sizeof(servaddr));  
 servaddr.sin_family = AF_INET;  
 servaddr.sin_port = htons(SERV_PORT); 

 //将程序的参数1(argv[1])转换成套接字地址结构  
 Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);  
 向服务器发起连接,连接成功后client_socket代表了客户机和服务器的一个socket连接  
 Connect(sockfd, (SA*)&servaddr, sizeof(servaddr)); 

 str_cli(stdin, sockfd);  
 return 0;  
}

运行示例(红色字体的为输入)(假设某个回射字符串的服务器已经启动)

www.linuxidc.com@ubuntu:~/code$ gcc my_unp_v1.c client.c -o client
www.linuxidc.com@ubuntu:~/code$ ./client 127.0.0.1
ABCD
ABCD
Ctrl+D




本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/464142.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

枚举和结构

1&#xff0e; 枚举 a) 枚举类型是一种特殊的值类型&#xff0c;它用于声明一组具有相同性质的常量&#xff0c; b) 声明枚举 在C#中使用关键字enum类声明枚举&#xff0c;其形式如下。 enum 枚举名 { List1value1, List2value2, List3value3, …. …

_beginthreadex 一定要自己写 CloseHandle 可以不用 _endthreadex

_beginthreadex 一定要自己写 CloseHandle 可以不用 _endthreadex 天哪,好久不 写忘记了.一直记得线程的句柄只是 createthread 才需要关闭,可能是我用 AfxBeginThread 太多了. 以后直接这样好了 ::CloseHandle((HANDLE)_beginthreadex(NULL, 0,threadRun_client,(void *)tp, 0…

嵌入式界的顶流开源项目,RetroPie 是怎么设计的?

RetroPie 是啥&#xff1f;一个用于将树梅派等板子转变为游戏机的开源项目。树梅派上运行 RetroPieGithub:https://github.com/RetroPie/RetroPie-Setup第一感觉&#xff0c;基于 Shell&#xff0c;有啥牛逼的。但仔细想想&#xff0c;一个简单的项目能获得 9.4K 的 Star&#…

java线程池,信号量使用demo

直接上代码 package org.jimmy.threadtest20181121;import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit;public class TestThread20181128 {public Semaphore semaphore new Semaphore(2, true)…

使用epoll+时间堆实现高性能定时器

在开发Linux网络程序时&#xff0c;通常需要维护多个定时器&#xff0c;如维护客户端心跳时间、检查多个数据包的超时重传等。如果采用Linux的SIGALARM信号实现&#xff0c;则会带来较大的系统开销&#xff0c;且不便于管理。 本文在应用层实现了一个基于时间堆的高性能定时器&…

Spring JDBC最佳实践(2)

2019独角兽企业重金招聘Python工程师标准>>> 使用DataSourceUtils进行Connection的管理 由上节代码可知&#xff0c;JdbcTemplate在获取Connection的时候&#xff0c;并不是直接调用DataSource的getConnection(),而是调用了如下的代码&#xff1a; Connection con …

我所感受到的上海

大家好&#xff0c;文章转自张老师的公众号&#xff0c;文章的我不是小编本人&#xff0c;小编现居深圳&#xff0c;刚接受了一场大雨的洗礼。前两天公众号抽奖的书籍已经发货&#xff0c;中奖的朋友们注意查收。当格蠹园里的大灰反复犹豫到底应该在哪里生产的时候&#xff0c;…

时间操作(Java版)—获取给定日期N天后的日期

版权声明&#xff1a;本文为博主原创文章。未经博主同意不得转载。https://blog.csdn.net/wangshuxuncom/article/details/34896777 获取给定日期N天后的日期import java.util.Calendar;public class Test {public static void main(String[] args) {System.out.println(new Te…

设计模式学习笔记五——Prototype模式

动机&#xff1a;使用原型实例指定创建对象的种类&#xff0c;然后通过拷贝这些原型来创建新的对象。某些结构复杂对象面临着剧烈变化&#xff0c;但拥有比较稳定一致的接口&#xff0c;如何隔离出这些易变对象&#xff0c;使客户程序不随之改变&#xff1f;场景&#xff1a;Th…

2011年最佳代码

2019独角兽企业重金招聘Python工程师标准>>> 2011年最佳代码 try { if(you.bevieve(it) true || you.believe(it) false) { I.believe(it); } } catch(Exception ex) { throw new Exception("Its a miracle!"); } finally { it.justHappened(); } 转载于…

使用Epoll 在 Linux 上开发高性能应用服务器

epoll是Linux提供一种多路复用的技术&#xff0c;类似各个平台都支持的select&#xff0c;只是epoll在内核的实现做了更多地优化&#xff0c;可以支持比select更多的文件描述符&#xff0c;当然也支持 socket这种网络的文件描述符。Linux上的大并发的接入服务器&#xff0c;目前…

昨晚两点睡

深圳下雨两天&#xff0c;我们居家办公两天&#xff0c;不过奇怪的事情是&#xff0c;这两天我都到公司上班&#xff0c;昨天早上没有下雨&#xff0c;我想着应该要去公司&#xff0c;结果到了公司才知道原来今天可以居家办公。不过&#xff0c;在公司才有上班的感觉&#xff0…

hashmap详解

一.hashmap的数据结构 HashMap采取数组加链表的存储方式(哈希表)来实现。亦即数组&#xff08;散列桶&#xff09;中的每一个元素都是链表 二.hashmap的构造函数 HashMap()&#xff1a;构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。 HashMap(int initia…

最近忙,三个字

最近忙&#xff0c;三个字 转载于:https://www.cnblogs.com/Liunsh/archive/2007/06/13/782352.html

书籍推荐-记这几年看的书

这几年看了不少书&#xff0c;大部分是自掏腰包&#xff0c;看一本好书是享受&#xff0c;我很喜欢这种感觉。 这些是我这几年看书的一些心得&#xff0c;对于一些新手来说&#xff0c;可能有点帮助。 这几年一直在走技术路线&#xff0c;所以看的大部分都是技术方面的书籍&…

不复位MCU直接调试运行程序,让bug闻风丧胆

大家周末好呀&#xff0c;文章转自bug菌的公众号&#xff0c;文章介绍步复位情况下调试bug&#xff0c;希望对大家有用。1调试窘境经常有朋友在开发中遇到这样的窘境&#xff0c;当单片机程序运行异常以后&#xff0c;由于调试信息做得并不是很全面&#xff0c;导致相应的问题场…

数据库设计中的14个技巧

数据库设计中的14个技巧 1. 原始单据与实体之间的关系   可以是一对一、一对多、多对多的关系。在一般情况下&#xff0c;它们是一对一的关系&#xff1a;即一张原始单据对 应且只对应一个实体。在特殊情况下&#xff0c;它们可能是一对多或多对一的关系&#xff0c;即一张原…

游三圣乡山中湖岛有感

游三圣乡山中湖岛有感——代腾飞 2007年6月10日 于成都池塘水绿萍飘荡柳絮随风四飞扬独坐湖亭把歌唱夕阳西下断愁肠 转载于:https://www.cnblogs.com/daitengfei/archive/2007/06/26/795914.html

这次比opencv快⑥倍!!!

打败opencv ,哦&#xff0c;是快了3倍上回书说道&#xff0c;我用汇编neon实现去畸变算法比opencv快3倍&#xff0c;这都不算啥&#xff0c;这次新增了透视变换算法&#xff0c;二者加起来比opencv快6倍&#xff01;拭目以待吧。啥玩意是透视变换&#xff1f;相信你们都开过高级…

数据和数据类型

一、什么是数据&#xff1a; 数据(date)是事实或观察的结果&#xff0c;是对客观事物的逻辑归纳&#xff0c;是用于表示客观事物的未加工的原始素材。 1&#xff09;数据是信息的表现形式和载体&#xff0c;可以是符号、文字、数字、语音、图像、视频等。数据和信息是不可分离…