功能:
        1)用户登录提示.
        
        2)服务器转发客户端发来的消息给其他客户端.
        
        3)当前客户端输入quit可以退出自己,并且服务器转发退出提示.
  
        4)服务器会转发自己从终端输入的内容给所有客户端.

注意:

1)服务器端需要命令行传参的方式输入端口号.

2)客户端需要命令行传参的方式输入ip地址以及端口号.

3)因为我懒并未设置 “客户端ctrl+c”等信号 退出客户会转发用户退出的功能(你想的话可以在服务器端signal接收下信号,并设置处理方式).

4)本程序用“fork函数”以多进程的方式实现多路复用,请注意.

5)本聊天室仅限于同一网段内进行通信.

6)因为我是一个人测试的,所以重复我是根据端口号来判断的,后面因为懒又不想改了,你们可以改为姓名判断或者是ip判断的.

代码:

注:本人较懒,所以注释有点少

服务器端:

#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include<stdlib.h>
typedef struct
{char name[32];     char text[256];
}MSG;
typedef struct sockadd
{struct sockaddr_in data;struct sockadd *next;
}sock_t;/***************************注意,接收的消息第一个字符代表类型,‘n’为名字,代表用户登录‘t’为消息,代表是用户发的消息*///创建表头
sock_t *cret_sockadd(void)
{sock_t *p=(sock_t *)malloc(sizeof(sock_t));if(NULL==p){perror("sockadd err.");return NULL;}p->next=NULL;return p;
}//用户退出删除用户
void del_sock(sock_t *p,int sockfd,struct sockaddr_in a,char msg[])
{char buf[32]="",quit[]="quit";strncpy(buf,msg+1,1);strcat(buf," sir exit chat.");sock_t *pdel=NULL;sock_t *pt=NULL;sock_t *q=p;while(p->next!=NULL){pt=p;p=p->next;if(p->data.sin_port==a.sin_port){sendto(sockfd,quit,sizeof(quit),0,(struct sockaddr *)&p->data,sizeof(p->data));pdel=p;pt->next=pdel->next;free(pdel);pdel=NULL;puts(buf);while(q->next!=NULL){q=q->next;sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&(q->data),sizeof(q->data));}}}
}//添加用户
int add_sock(sock_t *p,struct sockaddr_in a)
{while(p->next!=NULL)p=p->next;sock_t *pnew=(sock_t *)malloc(sizeof(sock_t));if(NULL==pnew){perror("pnew malloc err.");return -1;}pnew->data=a;pnew->next=p->next;p->next=pnew;return 0;
}int main(int argc, const char *argv[])
{int i;sock_t *p=cret_sockadd();MSG msg;int sockfd=socket(AF_INET,SOCK_DGRAM,0);if(sockfd<0){perror("socket err.");return -1;}struct sockaddr_in servcr;servcr.sin_family=AF_INET;servcr.sin_port=htons(atoi(argv[1]));servcr.sin_addr.s_addr=htonl(INADDR_ANY);struct sockaddr_in clint;socklen_t len=sizeof(clint);char buf[32];if(bind(sockfd,(struct sockaddr *)&servcr,sizeof(servcr))<0){perror("bind err.");return -1;}pid_t pid=fork();if(pid<0){perror("fork err.");return -1;}else if(pid==0)  //子进程,自己发消息给父进程,然后父进程转发消息给客户{char temp[256]="";while(1){bzero(temp,sizeof(temp));bzero(buf,sizeof(buf));fgets(buf,32,stdin);if(buf[strlen(buf)-1]=='\n')buf[(strlen(buf)-1)]='\0';strcat(temp,"tFuWuqi say:");strcat(temp,buf);sendto(sockfd,temp,sizeof(temp),0,(struct sockaddr *)&servcr,sizeof(servcr));}}else{while(1){bzero(&msg,sizeof(msg));recvfrom(sockfd,msg.text,sizeof(msg.text),0,(struct sockaddr *)&clint,&len);if(strcmp(&(msg.text[strlen(msg.text)-4]),"quit")==0){del_sock(p,sockfd,clint,msg.text);continue;}if(msg.text[0]=='n')   //接收的消息第一个字符如果是n代表用户登录{add_sock(p,clint);           sock_t *q=p;printf("%s login\n",msg.text+1);printf("=================\n");strcat(msg.text," login");while(q->next!=NULL){q=q->next;if(q->data.sin_port==clint.sin_port)//不给自己发消息continue;sendto(sockfd,msg.text+1,sizeof(msg.text),0,(struct sockaddr *)&(q->data),sizeof(q->data));}q=NULL;continue;//跳过服务器打印消息}else if(msg.text[0]=='t')//如果是t,代表是消息{sock_t *x=p;while(x->next!=NULL)//转发给其他用户{x=x->next;if(x->data.sin_port==clint.sin_port)//跳过自己continue;sendto(sockfd,msg.text+1,sizeof(msg.text),0,(struct sockaddr *)&(x->data),sizeof(x->data));}x=NULL;}printf("%s\n",(msg.text+1));    //服务器打印消息       printf("=================\n");}wait(NULL);}free(p);p=NULL;close(sockfd);return 0;
}

客户端:

#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>#include <stdlib.h>
typedef struct
{char name[32];char text[256];
}MSG;int main(int argc, const char *argv[])
{int sockfd=socket(AF_INET,SOCK_DGRAM,0);if(sockfd<0){perror("socket err.");return -1;}struct sockaddr_in servcr;servcr.sin_family=AF_INET;servcr.sin_port=htons(atoi(argv[2]));servcr.sin_addr.s_addr=inet_addr(argv[1]);socklen_t len=sizeof(servcr);MSG msg;int s=0;char buf[128]="";msg.name[0]='n';   //把发送的消息第一位赋值‘n’,代表是用户登录printf("please input your name:");fgets(msg.name+1,31,stdin);     //发消息的第一位变为标志位,所以从第二位开始输入if(msg.name[strlen(msg.name)-1]=='\n')  //因为fgets会多一个‘\n’,把其覆盖掉msg.name[(strlen(msg.name)-1)]='\0';int a=sendto(sockfd,msg.name,32,0,(struct sockaddr *)&servcr,sizeof(servcr));//发送登录用户名strcat(msg.name," say:");    //名字与say拼接起来pid_t pid=fork();if(pid<0){perror("fork err.");return -1;}else if(pid==0){while(1){if(s==1)       //如果用户退出会把s置1表示用户退出,这时候结束子进程break;bzero(msg.text,sizeof(msg.text));bzero(buf,sizeof(buf));msg.name[0]='t';    //把标志位为‘t’,代表发送的是消息,会覆盖掉‘n’或者‘t’,消息不受影响printf("Please input:");fflush(NULL);fgets(buf,sizeof(msg.text),stdin);if(buf[strlen(buf)-1]=='\n')buf[(strlen(buf)-1)]='\0';if(strcmp(buf,"quit")==0)s=1;strcat(msg.text,msg.name);//把xx说与发送的消息拼接起来strcat(msg.text,buf); //发送quit,服务器收到会删除用户sendto(sockfd,msg.text,256,0,(struct sockaddr *)&servcr,sizeof(servcr));}exit(0);}else{while(1){bzero(msg.text,sizeof(msg.text));recvfrom(sockfd,msg.text,sizeof(msg.text),0,(struct sockaddr *)&servcr,&len);puts("");puts("=================");if(strcmp(msg.text,"quit")==0) //子进程结束后会跳出,父进程会接收到quit,然后退出进程break;printf("%s\n",msg.text);puts("=================");}wait(NULL);}close(sockfd);return 0;
}

emmm,有很多方面我做的并不是很好,还有其他解决方法,你可以使用别样的方法完成,如果这里有啥做的不对的,欢迎各位大佬帮忙指正,小白在这里感谢,最后,让我们一起加油,一起努力,未来可期!

基于(LinuxC语言)的UDP局域网聊天室相关推荐

  1. 基于Java语言的Web在线聊天室

    在线聊天室 能够实现登录,注册,聊天功能,最终效果如下图所示 注册页面 <%@ page language="java" contentType="text/htm ...

  2. java毕业设计——基于java+TCP+UDP的局域网聊天室系统设计与实现(毕业论文+程序源码)——局域网聊天室系统

    基于java+TCP+UDP的局域网聊天室系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+TCP+UDP的局域网聊天室系统设计与实现,文章末尾附有本毕业设计的论文和源码下载地 ...

  3. python实现简易聊天需要登录博客园zip下载_Python基于Socket实现简易多人聊天室的示例代码...

    前言 套接字(Sockets)是双向通信信道的端点. 套接字可以在一个进程内,在同一机器上的进程之间,或者在不同主机的进程之间进行通信,主机可以是任何一台有连接互联网的机器. 套接字可以通过多种不同的 ...

  4. 基于Node.js + WebSocket 的简易聊天室

    代码地址如下: http://www.demodashi.com/demo/13282.html Node.js聊天室运行说明 Node.js的本质就是运行在服务端的JavaScript.Node.j ...

  5. 基于Linux下的即时通讯聊天室项目(全代码 有注释 可直接运行)

    基于Linux下的即时通讯聊天室项目 一.序言 二.具体功能 三.系统客户要求 四.具体代码 1.服务器代码 2.客户端代码 一.序言 最近在写一个基于Linux下的聊天工具 它适合于局域网内所有人进 ...

  6. 【java毕业设计】基于java+原生Sevlet+socket的聊天室系统设计与实现(毕业论文+程序源码)——聊天室系统

    基于java+原生Sevlet+socket的聊天室系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+原生Sevlet+socket的聊天室系统设计与实现,文章末尾附有本毕业设 ...

  7. 视频教程-实战Go语言:多人聊天室-Go语言

    实战Go语言:多人聊天室 多年互联网从业经验: 有丰富的的企业网站.手游.APP开发经验: 曾担任上海益盟软件技术股份有限公司项目经理及产品经理: 参与项目有益盟私募工厂.睿妙影音家庭物联网设备.手游 ...

  8. 局域网服务器发送消息,Java实现简单局域网聊天室

    本文实例为大家分享了Java实现简单局域网聊天室的具体代码,供大家参考,具体内容如下 Java 的Socket编程: 1.TCP协议是面向连接的.可靠的.有序的.以字节流的方式发送数据,通过三次握手方 ...

  9. 实战Go语言:多人聊天室-欧阳桫-专题视频课程

    实战Go语言:多人聊天室-77人已学习 课程介绍         ·基于Go的网络和并发技术开发多人在线聊天室: ·功能包括:单聊.群聊.昵称.上下线通知.聊天日志等: ·技术栈:TCP通信.协程并发 ...

  10. 基于C/S模式的简单聊天室

    基于C/S模式的简单聊天室 要求: 使用Socket实现网上聊天室,要求基于TCP或UDP协议,用户可以通过客户端连接到服务器端并进行聊天,聊天时可以启动多个客户端:服务器启动后,接收客户端发来的用户 ...

最新文章

  1. [算法]链表的逆序遍历节点
  2. 使用 SetCustomizedString汉化UltraWinGrid的筛选
  3. Python基础语法-三种函数特殊形参定义以及使用方式
  4. java 接口不是不能new吗?- java:使用匿名类直接new接口
  5. ld 用法:gcc 过程最后一步-链接
  6. 大数据发展火爆,云计算平台主打安全至上
  7. 以为GAN只能“炮制假图”?它还有这7种另类用途
  8. Hive分区(静态分区+动态分区)
  9. 管理新语:工作没做好,批评几句,怎么成了诛心
  10. 计算机进pe按键,win10下进入pe系统操作方法
  11. python logging日志分割_Python3测井曲线切割,python3logging,日志
  12. 计算机课堂有趣的游戏,有趣的课堂游戏作文范文5篇
  13. Multisim里导入没有的元器件(以NPN型三极管2N9013为例)
  14. 数字信号处理中均值、均方值、均方差、均方根值、均方误差、均方根误差、方差、协方差、标准差对比分析及统计学意义
  15. 北京知产局:鼓励当事人用区块链,获取、固定知识产权纠纷证据
  16. 10个方法教你提升表达能力
  17. 勋章菊的养殖方法和注意事项
  18. Excel·VBA按行拆分工作表
  19. android 蓝牙电话号码,Android拨打电话和蓝牙状态监听
  20. 原来华为手机的语音助手这么好用,说话即可语音翻译,方便又实用

热门文章

  1. 基于cesium的三维城市建筑可视化系统(shp数据导入cesium的三种可行方法)
  2. android日记功能的实现6,我的android studio学习日记
  3. 哈希表实现电话号码查找系统
  4. 小米平板2刷哪个系统更流畅_教程:小米平板2轻松刷Win10
  5. OCR技术发展综述与达观数据的实践经验
  6. 如何将UCI数据集转换成Matlab可用格式
  7. 方舟建筑代码指令大全
  8. java 使用itextpdf分割pdf文件,pdf分页
  9. 浅谈新一代PGIS技术在智慧消防中的创新应用
  10. 缺少比较器,运放来救场!(运放当做比较器电路记录)