客户端

ubuntu@ubuntu:~/internet/exercise/04_多点通信$ cat chatroomCli.c
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<sys/wait.h>
#include<signal.h>
#include<stdlib.h>#define N 128#define ERR_MSG(msg) do{\printf("line:%d\n",__LINE__);\perror(msg);\
}while(0)#define PORT 1026     //端口号的网络字节序:1024~49151;
#define IP "192.168.10.110"  //ifconfig查看到的本机IPvoid zombie_handler(int sig)
{while(waitpid(-1,NULL,WNOHANG)>0);
}int main(int argc, const char *argv[])
{//子进程退出,父未退,所以产生僵尸进程if(signal(SIGCHLD,zombie_handler)==SIG_ERR){ERR_MSG("signal");return -1;}//创建流式套接字int cfd = socket(AF_INET,SOCK_STREAM,0);if(cfd<0){ERR_MSG("socket");return -1;}printf("socket create success,cfd=%d__%d__\n",cfd,__LINE__);//功能:允许端口快速被重用,快速被复用int reuse = 1;if(setsockopt(cfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0){ERR_MSG("setsockopt");return -1;}//填充服务器自身的地址信息结构体//真实的地址信息结构体根据就地址族指定  AF_INET:man 7 ipstruct sockaddr_in sin;sin.sin_family     =AF_INET;      //必须填充AF_INETsin.sin_port       =htons(PORT);  //端口号的网络字节序,2字节的无符号整型数,16位:1~65535,其中我们自己用1024~49151范围内的sin.sin_addr.s_addr=inet_addr(IP);//ifconfig查看本机IP//登录char ID[20]="";printf("please input the ID:\n");fgets(ID,sizeof(ID),stdin);char L;char buf[N]="";int size = sprintf(buf,"%c%s",L,ID);if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))<0){ERR_MSG("sendto");return -1;}pid_t cpid = fork();if(cpid>0)       //父进程接收系统消息,登录,群聊,下线  {while(1){bzero(buf,sizeof(buf));//接收数据ssize_t res = recv(cfd,buf,sizeof(buf),0);if(res<0){ERR_MSG("recv");return -1;}printf("%s",buf);   //客户端接收到来自服务器转发的信息:系统信息,登录、群聊、下线等}}else if(0==cpid){while(1){//子进程从终端获取数据,quit时下线'Q',非quit群聊'C'char arr[128]="";bzero(arr,sizeof(arr));fgets(arr,sizeof(arr),stdin);if(0==strcasecmp(arr,"quit")){bzero(arr,sizeof(arr));strcat(arr,"下线");sendto(cfd,arr,sizeof(arr),0,(struct sockaddr*)&sin,sizeof(sin)<0);goto END;}else{sendto(cfd,arr,sizeof(arr),0,(struct sockaddr*)&sin,sizeof(sin)<0);continue;}}}else{ERR_MSG("fork");return -1;}END:close(cfd);return 0;
}

服务器

ubuntu@ubuntu:~/internet/exercise/04_多点通信$ cat chatroomSer.c
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>#define ERR_MSG(msg) do{\printf("line:%d\n",__LINE__);\perror(msg);\
}while(0)#define PORT 2333     //端口号的网络字节序:1024~49151;
#define IP "192.168.10.255"  //广播IP
#define N 128pthread_t tid;
//链表 传参
typedef struct snd
{int sfd;struct sockaddr_in cin;struct sockaddr_in sin;struct snd* next;
}*linklist;
//信息结构体
typedef struct
{int type;char name[30];char text[N];
}MSG;int do_login(int sfd,linklist L,MSG rcv_msg,struct sockaddr_in cin);
int do_chat(int sfd,linklist L,MSG rcv_msg,struct sockaddr_in cin);
int do_quit(int sfd,linklist L,MSG rcv_msg,struct sockaddr_in cin);
void* SndMsg(void* arg);  //void* arg = (void*)&info
int main(int argc, const char *argv[])
{   if(argc<3){printf("please input the ip&port\n");return -1;}//创建报式套接字int sfd = socket(AF_INET,SOCK_DGRAM,0);if(sfd<0){ERR_MSG("socket");return -1;}printf("socket create success,sfd=%d__%d__\n",sfd,__LINE__);//填充接收方的地址信息结构体//真实的地址信息结构体根据就地址族指定  AF_INET:man 7 ipstruct sockaddr_in sin;sin.sin_family     =AF_INET;      //必须填充AF_INETsin.sin_port       =htons(atoi(argv[2]));  //端口号的网络字节序,2字节的无符号整型数,16位:1~65535,其中我们自己用1024~49151范围内的sin.sin_addr.s_addr=inet_addr(argv[1]);//广播IP//绑定接收方的IP和端口if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0){ERR_MSG("bind");return -1;}printf("bind success __%d__\n",__LINE__);//创建线程struct snd info;pthread_create(&tid,NULL,SndMsg,(void*)&info);//创建链表存储客户端信息linklist L= (linklist)malloc(sizeof(struct snd));L->next = NULL;//接收消息char buf[128]="";ssize_t res = 0;struct sockaddr_in cin;   //存储客户端的地址信息socklen_t len = sizeof(cin);MSG rcv_msg;while(1){bzero(rcv_msg.text,sizeof(rcv_msg.text));//接收数据res = recvfrom(sfd,&rcv_msg,sizeof(rcv_msg),0,(void*)&cin,&len);if(res<0){ERR_MSG("recvfrom");return -1;}int type = ntohs(rcv_msg.type);switch(type){case 'L':do_login(sfd,L,rcv_msg,cin);break;case 'C':do_chat(sfd,L,rcv_msg,cin);break;case 'Q':do_quit(sfd,L,rcv_msg,cin);break;default:printf("input fasle\n");}}   if(close(sfd)<0){ERR_MSG("close");return -1;}return 0;
}int do_login(int sfd,linklist L,MSG rcv_msg,struct sockaddr_in cin)
{//登陆成功printf("%s [%s:%d]登陆成功\n",rcv_msg.name,\(char*)inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));sprintf(rcv_msg.text,"------%s登陆成功-----",rcv_msg.name);while(L->next!=NULL){L=L->next;if(sendto(sfd,&rcv_msg,sizeof(rcv_msg),0,(void*)&(L->cin),sizeof(L->cin))<0){ERR_MSG("sendto");return -1;}}linklist temp = (linklist)malloc(sizeof(struct snd));temp->cin = cin;temp->next = NULL;L->next = temp;return 0;
}
int do_chat(int sfd,linklist L,MSG rcv_msg,struct sockaddr_in cin)
{char buf[258]="";sprintf(buf,"%s:%s",rcv_msg.name,rcv_msg.text);strcat(rcv_msg.text,buf);while(L->next!=NULL){L = L->next;if(memcmp(&cin,&L->cin,sizeof(cin))!=0){if(sendto(sfd,&rcv_msg,sizeof(rcv_msg),0,(void*)&(L->cin),sizeof(L->cin))<0){ERR_MSG("sendto");return -1;}}}return 0;
}int do_quit(int sfd,linklist L,MSG rcv_msg,struct sockaddr_in cin)
{if(0==strncasecmp(rcv_msg.text,"quit",4)){char buf[258]="";sprintf(buf,"%s:%s",rcv_msg.name,"用户下线");strcat(rcv_msg.text,buf);while(L->next!=NULL){L = L->next;if(memcmp(&cin,&L->cin,sizeof(cin))!=0){if(sendto(sfd,&rcv_msg,sizeof(rcv_msg),0,(void*)&(L->cin),sizeof(L->cin))<0){ERR_MSG("sendto");return -1;}}else   //删除已下线用户地址信息{linklist temp = L->next;L->next = temp->next;free(temp);}}}return 0;
}//分支线程:从终端获取数据并发送系统消息
void* SndMsg(void* arg)  //void* arg = (void*)&info
{char receive[128]="";//发送数据fgets(receive,sizeof(receive),stdin);receive[strlen(receive)-1]=0;int sfd = ((struct snd*)arg)->sfd;struct sockaddr_in sin = ((struct snd*)arg)->sin;MSG rcv_msg;sprintf(rcv_msg.text,"system:%s",receive);if(sendto(sfd,&rcv_msg,sizeof(rcv_msg),0,(void*)&sin,sizeof(sin))<0){ERR_MSG("sendto");return NULL;}printf("系统消息发送成功\n");}

简易聊天室(未完善版)相关推荐

  1. 简易聊天室(Python版)

    目录 简介 运行效果 代码 客户端 服务器 自定义库 通讯协议及相关配置定义库(DY.py) 数据库调用库(SJK.py) 套接字库(TJZ.py) 套接字通讯库(服务器端)(TJZ_FZ.py) 简 ...

  2. 视频教程-网络聊天室Java基础版(Socket_Swing编程)仿QQ聊天-Java

    网络聊天室Java基础版(Socket_Swing编程)仿QQ聊天 IT行业资深从业者,7年资深Java高级开发,Java架构师.曾就职银行.电信等行业多家上市公司.担任项目负责人,软件架构师.有丰富 ...

  3. Express+Socket.IO 实现简易聊天室

    代码地址如下: http://www.demodashi.com/demo/12477.html 闲暇之余研究了一下 Socket.io,搭建了一个简易版的聊天室,如有不对之处还望指正,先上效果图: ...

  4. Java WebSocket编程与网页简易聊天室

    在webSocket还未引入前,许多开发人员通过各种非正规手段来完成更新网站的最新信息和到所有当前访问者的任务,其中一种手段就是通过浏览器向服务器轮询更新,但这种手段的网络延迟比较明显,其用户体验比较 ...

  5. 2020暑假集训项目——Java简易聊天室

    经过一周的学习与搬砖,我成功的完成了暑假集训的第一个项目--Java简易聊天室,这里对整个项目做一个总结.(文末附下载地址) 本项目支持的功能: 1.可同时开启多个客户端进行多人聊天: 2.可与在线的 ...

  6. vue php聊天室,Laravel + Swoole 打造IM简易聊天室

    Laravel + Swoole 打造IM简易聊天室 最近在学习Swoole,利用Swoole扩展让PHP生动了不少,本篇就来Swoole开发一款简易的IM聊天室 应用场景:实现简单的即时消息聊天室. ...

  7. 超详细:实现过程-Linux 环境下的简易聊天室,采用CS模型,实现多客户端之间的稳定数据传输。--注册和登录(但之后会连续更新内容,直至全部实现)

    前言 在学完不够全面的Linux操作系统编程后(这也意味着我后期也要不断学习,这也符合我活到老学到老的人生观点),需要以一些项目来检测自己的所学,毕竟实践见真章. 所以在今后的几天里,我将以无界面聊天 ...

  8. 连夜撸了一个简易聊天室

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 分不清轮询.长轮询?不知道什么时候该用websocket还 ...

  9. 撸一个简易聊天室,不信你学不会实时消息推送(附源码)

    点击上方 好好学java ,选择 星标 公众号重磅资讯,干货,第一时间送达 今日推荐:推荐 19 个 github 超牛逼项目!个人原创100W +访问量博客:点击前往,查看更多 分不清轮询.长轮询? ...

  10. java聊天室程序_Java简易聊天室程序socket

    Java简易聊天室程序socket chatroomdemo.java package com.socket.demo; import java.io.IOException; import java ...

最新文章

  1. [NC15034]德玛西亚万岁
  2. Spring Cloud【Finchley】-12使用Hystrix Dashboard实现Hystrix数据的可视化监控
  3. 带电检测必要性_接地电阻检测分析的必要性
  4. linux下日志文件的查找(tail和grep)
  5. PHP 修改配置文件后重启命名
  6. 下一步目标:整理出1套相对成熟的ios 开发框架
  7. UAC在注册表中的对应位置
  8. 7-6 计算符号函数的值 (10 分)
  9. html5学习笔记(progress)
  10. 什么是列联表分析(Contingency table analysis)?
  11. 基于QT实现的旅游路线查询系统
  12. 用布尔代数简化下列各逻辑表达式
  13. 解决undefined reference to symbol ‘LZ4_decompress_safe‘问题
  14. 暑假实训-3_Oracle数据库-3_单行函数
  15. AXI 总线基本概念1 - 如何理解outstanding传输
  16. 在python中是没有NULL的,取而代之的是None,它的含义是为空
  17. 驰骋工作流-表单引擎- ccform
  18. [Android 4.4.2] 泛泰A850 Mokee4.4.2 20140509 RC2.0 by syhost
  19. python 游戏辅助lol_某顶之奕赌狗神器自用自动拿牌,python界面版全部源码以修复bug...
  20. π-Day快乐:Python可视化π

热门文章

  1. Physically Based Rendering
  2. 通过freemaker导出word文档SpringBoot+idea,做成浏览器下载
  3. 让人工智能解数学题,可能没你想象的那么简单
  4. 《活下去的理由》——如何生活 我觉得有用但不总是遵循的 40 条建议
  5. 虚拟机linux系统 (deepin) ens33网卡没有网、没有分配ip的解决办法
  6. Python小白逆袭大神[作业]Day5-综合大作业
  7. java键盘循环输入5个学生的成绩_键盘录入5个学生的信息根据总分从高到低输出在控制台...
  8. 网上炒作的哪些日赚千元不是梦的手机赚钱项目是真的吗
  9. IDEA中如果优雅Debug
  10. 爱奇艺PC Web NodeJS中间层实践