Linux 即时聊天系统(tcp)epoll 版

简介:

  1.系统使用TCP来实现

  2.服务端 ctrl+d 能够使当前的客户端退出,但是服务端能够继续运行,并等待,响应其他的客户端的请求。ctrl+c 结束服务端进程

  3.ctrl+c 结束客户端进程

  4.服务器主要是用 epoll 模型实现,支持高并发

  <测试并可以正常运行>

  系统版本:Linux version 4.4.0-78-generic ([email protected]) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) )

 //头文件 1 #include <arpa/inet.h>
 2 #include <sys/socket.h>
 3 #include <netinet/in.h>
 4 #include <stdio.h>
 5 #include <netdb.h>
 6 #include <string.h>
 7 #include <sys/types.h>
 8 #include <sys/socket.h>
 9 #include <unistd.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <errno.h>
13 #include <sys/time.h>
14 #include <sys/epoll.h>
15 #include <signal.h>
  //服务端代码  1 #include"func.h"
  2
  3 int main(int argc,char *argv[]){
  4     //socket
  5     int sfd = socket(AF_INET,SOCK_STREAM,0);
  6     if(sfd == -1){
  7         perror("sfd");
  8         return -1;
  9     }
 10     //bind
 11     struct sockaddr_in server;
 12     memset(&server,0,sizeof(struct sockaddr_in));
 13     server.sin_family = AF_INET;
 14     server.sin_port = htons(atoi(argv[2]));
 15     server.sin_addr.s_addr = inet_addr(argv[1]);
 16     int ret;
 17     ret = bind(sfd,(struct sockaddr *)&server,sizeof(server));
 18     if(ret == -1){
 19         perror("bind");
 20         return -1;
 21     }
 22     //listen
 23     ret = listen(sfd,10);
 24     if(ret == -1){
 25         perror("listen");
 26         return -1;
 27     }
 28
 29     printf("i am server\n");
 30
 31     //epoll创建
 32     int epfd = epoll_create(1);
 33
 34     struct epoll_event event,evs[3];
 35     //注册sfd
 36     memset(&event,0,sizeof(event));
 37     event.events = EPOLLIN;
 38     event.data.fd = sfd;
 39     epoll_ctl(epfd,EPOLL_CTL_ADD,sfd,&event);
 40     //注册0
 41     memset(&event,0,sizeof(event));
 42     event.events = EPOLLIN;
 43     event.data.fd = 0;
 44     epoll_ctl(epfd,EPOLL_CTL_ADD,0,&event);
 45
 46     int ret1,i,len,new_fd;
 47     char buf[128]={0};
 48
 49     //新建client
 50     struct sockaddr_in client;
 51     while(1){
 52         memset(evs,0,sizeof(evs));
 53         int ret1 = epoll_wait(epfd,evs,3,-1);
 54         if(ret1 > 0){
 55             for(i=0; i<ret1; i++){
 56                 //sfd 有client请求建立里连接
 57                 if(evs[i].data.fd == sfd){
 58                     memset(&client,0,sizeof(client));
 59                     len = sizeof(client);
 60                     new_fd = accept(sfd,(struct sockaddr*)&client,&len);
 61                     if(new_fd == -1){
 62                         perror("accept");
 63                         return -1;
 64                     }
 65                     //注册new_fd
 66                     memset(&event,0,sizeof(event));
 67                     event.events = EPOLLIN;
 68                     event.data.fd = new_fd;
 69                     epoll_ctl(epfd,EPOLL_CTL_ADD,new_fd,&event);
 70                     //打印客户端ip,端口
 71                     printf("client ip=%s,port=%d\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
 72                 }
 73                 //0 服务端输入
 74                 if(evs[i].data.fd == 0){
 75                     memset(buf,0,sizeof(buf));
 76                     ret = read(0,buf,sizeof(buf));
 77                     if(ret <= 0){
 78                         printf("bye bye\n");
 79                         close(new_fd);
 80                         //删除new_fd
 81                         memset(&event,0,sizeof(event));
 82                         event.events = EPOLLIN;
 83                         event.data.fd = new_fd;
 84                         epoll_ctl(epfd,EPOLL_CTL_DEL,new_fd,&event);
 85                         break;
 86                     }
 87                     ret = send(new_fd,buf,strlen(buf)-1,0);
 88                     if(ret == -1){
 89                         perror("send");
 90                         return -1;
 91                     }
 92                 }
 93                 //new_fd 读客户端的数据
 94                 if(evs[i].data.fd == new_fd){
 95                     memset(buf,0,sizeof(buf));
 96                     ret = recv(new_fd,buf,sizeof(buf),0);
 97                     if(ret == -1){
 98                         perror("recv");
 99                         return -1;
100                     }else if(ret == 0){
101                         printf("bye bye\n");
102                         close(new_fd);
103                         //删除new_fd
104                         memset(&event,0,sizeof(event));
105                         event.events = EPOLLIN;
106                         event.data.fd = new_fd;
107                         epoll_ctl(epfd,EPOLL_CTL_DEL,new_fd,&event);
108                         break;
109                     }
110                     printf("%s\n",buf);
111                 }
112             }
113         }
114     }
115     close(sfd);//关闭sfd
116     close(new_fd);//关闭new_fd
117     close(epfd);//关闭epfd
118     return 0;
119 }
 //客户端代码(客户端并未使用epoll,有兴趣的可以自己进行修改) 1 #include"func.h"
 2
 3 int main(int argc,char *argv[]){
 4     //socket
 5     int sfd = socket(AF_INET,SOCK_STREAM,0);
 6     if(sfd == -1){
 7         perror("socket");
 8         return -1;
 9     }
10     //connect
11     int ret;
12     struct sockaddr_in ser;
13     memset(&ser,0,sizeof(ser));
14     ser.sin_family = AF_INET;
15     ser.sin_addr.s_addr = inet_addr(argv[1]);
16     ser.sin_port = htons(atoi(argv[2]));
17     ret = connect(sfd,(struct sockaddr*)&ser,sizeof(ser));
18     if(ret == -1){
19         perror("connect");
20         return -1;
21     }
22     printf("i am client\n");
23     char buf[128]={0};
24     fd_set rdset;
25     while(1){
26         FD_ZERO(&rdset);
27         FD_SET(0,&rdset);
28         FD_SET(sfd,&rdset);
29         ret = select(sfd+1,&rdset,NULL,NULL,NULL);
30         if(ret > 0){
31             if(FD_ISSET(0,&rdset)){
32                 memset(buf,0,sizeof(buf));
33                 ret = read(0,buf,sizeof(buf));
34                 if(ret <= 0){
35                     printf("bye bye\n");
36                     break;
37                 }
38                 ret = send(sfd,buf,strlen(buf)-1,0);
39                 if(ret == -1){
40                     perror("send");
41                     return -1;
42                 }
43             }
44             if(FD_ISSET(sfd,&rdset)){
45                 memset(buf,0,sizeof(buf));
46                 ret = recv(sfd,buf,sizeof(buf),0);
47                 if(ret == -1){
48                     perror("recv");
49                     return -1;
50                 }else if(ret == 0){
51                     printf("bye bye\n");
52                     break;
53                 }
54                 printf("%s\n",buf);
55             }
56         }
57     }
58     close(sfd);
59
60     return 0;
61 }
时间: 2024-11-05 02:36:55

Linux 即时聊天系统(tcp)epoll 版的相关文章

LINUX服务介绍(清晰版)

http://www.linuxdiyf.com/viewarticle.php?id=172539 服务列表(按字母顺序排列) 服务名 必需(是/否) 用途描述 注解 acon 否 语言支持 特别支持左手书写语言:阿拉伯语,波斯语和希伯莱语 acpi 否 电源管理 手提电脑电池电扇监控器 acpid 否 监听精灵进程 此进程监听并分配内核中的acpi事件 adsl 否 内部ADSL开关控制 只有你的计算机内部有互联网连接adsl开关时才用到此服务 alsa 否 高级Linux声音构件 这个单独

从linux源码看epoll

从linux源码看epoll前言在linux的高性能网络编程中,绕不开的就是epoll.和select.poll等系统调用相比,epoll在需要监视大量文件描述符并且其中只有少数活跃的时候,表现出无可比拟的优势.epoll能让内核记住所关注的描述符,并在对应的描述符事件就绪的时候,在epoll的就绪链表中添加这些就绪元素,并唤醒对应的epoll等待进程.本文就是笔者在探究epoll源码过程中,对kernel将就绪描述符添加到epoll并唤醒对应进程的一次源码分析(基于linux-2.6.32内核

在虚拟机linux环境下编译windows版adb fastboot

原文出自:http://blog.chinaunix.net/uid-20546441-id-1746200.html 我根据虚拟机编译遇到的问题进行一些添加 [前提条件] Linux Android源码完整 虚拟机磁盘空间100G左右(60G用来存放代码和编译后的文件) swap 30G左右,若太小会导致在编译后提示缺失文件 [具体步骤] 理论上,只要下一个windows版本的SDK,里面就自带了fastboot和adb工具. 但我最近确实遇到了一个需要在linux下编译出windows版本的

总结二:Linux系统的常见发行版(发行商)

总结二:Linux系统的常见发行版(发行商) 三大分支: 1.Slackware Slackware Linux是由Patrick Volkerding开发的GNU/Linux发行版.与很多其他的发行版不同,它坚持KISS(Keep It Simple Stupid)的原则. 比较著名分支发行版: S.u.s.E SUSE(发音 /sus/).SUSE Linux 原来是德国的 SuSE Linux AG公司发行维护的Linux发行版,是属于此公司的注册商标.第一个版本出现在1994年年初.20

Linux内核LTS长期支持版生命周期

Longterm release kernels Version Maintainer Released Projected EOL 4.9 Greg Kroah-Hartman 2016-12-11 Jan, 2019 4.4 Greg Kroah-Hartman 2016-01-10 Feb, 2018 4.1 Sasha Levin 2015-06-21 Sep, 2017 3.18 Sasha Levin 2014-12-07 Jan, 2017 3.16 Ben Hutchings 2

Linux 小知识翻译 - 「Linux」和「发行版」之间的关系

「Linux」本来指的仅仅是内核.5年之前大多都是这么认为的,但是最近不这么说了. 最近一般都说「Linux」是个 OS,这里的OS,不仅仅是内核,而是指电脑的整体环境(除了内核,还包括一些外围的软件). 内核本来是作为硬件和各种应用软件之间的桥梁而存在的,只有内核的PC是无法使用的. 因此,会将各式各样的软件和内核组合在一起,作为一个可以运行的OS来打包,打包后的OS就被称为「Linux发行版」. 最近,把「Linux发行版」称为「Linux」的情况也比较多了. 但是,「Linux内核」只有一

查看linux中的TCP连接数【转】

转自:http://blog.csdn.net/he_jian1/article/details/40787269 查看linux中的TCP连接数 本文章已收录于:  计算机网络知识库  分类: 安全测试总结(2)  性能经验总结(107)  版权声明:本文为博主原创文章,未经博主允许不得转载. 一.查看哪些IP连接本机 netstat -an 二.查看TCP连接数 1)统计80端口连接数netstat -nat|grep -i "80"|wc -l 2)统计httpd协议连接数ps

node.js+Express.js+Jade+MongoDB开发Web即时聊天系统视频教程下载

ode.js+Express.js+Jade+MongoDB开发Web即时聊天系统视频教程下载  联系QQ:1026270010  一.课程背景 1.什么是Node.js ? Node.js 是一个可以快速构建网络服务及应用的平台 .该平台的构建是基于Chrome's JavaScript runtime,也就是说,实际上它是对Google V8引擎(应用于Google Chrome浏览器)进行了封装. V8引擎执行Javascript的速度非常快,性能非常好.Node对一些特殊用例进行了优化,

linux应用开发-TCP/IP

linux应用开发-TCP/IP 一 OSI开放系统互联模型 二 协议结构 三 TCP协议 四 常用协议 五 两者区别 六 socket的TCP和UDP的连接方式 1 TCP 2 UDP 七 体系结构