收藏 分销(赏)

UDP局域网聊天室实现.pdf

上传人:天**** 文档编号:2645438 上传时间:2024-06-03 格式:PDF 页数:11 大小:637.26KB
下载 相关 举报
UDP局域网聊天室实现.pdf_第1页
第1页 / 共11页
UDP局域网聊天室实现.pdf_第2页
第2页 / 共11页
UDP局域网聊天室实现.pdf_第3页
第3页 / 共11页
UDP局域网聊天室实现.pdf_第4页
第4页 / 共11页
UDP局域网聊天室实现.pdf_第5页
第5页 / 共11页
点击查看更多>>
资源描述

1、UDP局域网聊天室实现1.UDP聊天室基本功能分析2.UDP实现流程分析(客户端,服务器)3.UDP聊天功能实现(群聊,私聊)4.总结1.UDP基本功能分析 在学完网络中UDP的编程之后,我们想通过实现一个UDP的聊天室来实际运用一下!那么聊天室需要哪些功能呢!我们可以类比 QQ的聊天的功能,QQ最基本的功能:1.登录注册2.聊天3.退出 那么我们也大致实现这些功能。我们做一些简化,不需要登录注册的功能,登录时,给所有连接上来的客户端发送消息,告诉说谁登录上来了客户端给服务器发送消息时就指定需要聊天的对象。我们分析一下我们聊天的过程:(1).我们实心的效果是 如:A-B(A与B进行聊天)A与B

2、聊天 实际上是 A-“消息”-服务器转发-消息-B(2).服务器发送消息 服务器-A -B -C 这是一个群发的消息2.UDP实现流程分析(客户端,服务器)分析客户端的流程:客户端:整体的流程首先是 网络的基本编程s o c k e tp i d =f o r k();i f (p i d 0)/父进程,主要功能,数据发送 w h i l e (1)/大循环 1.发送一个登录的消息,告诉大家我上线了 2.从键盘获得数据 a.聊天的对端的名字 S Y S T E R M 群聊消息 非S Y S T E R M 私聊消息 c.聊天的内容 d.输入q u i t 时,结束 3.聊天结束,发送一个聊天

3、结束的消息给大家,告诉大家说我下线了 e l s e i f (p i d =0)/子进程,主要功能,数据接收 w h i l e (1)1.接收数据 2.显示数据 分析服务器端的流程:整体的流程是 UDP的网络服务器的 基本编程s o c k e tb i n dp i d =f o r k();i f (p i d 0)/父进程 发数据,系统级别的消息,给所有客户端发送消息 1.从键盘获得数据 2.发送给服务器自己 e l s e i f (p i d =0)/子进程,接收数据,处理消息 1.接收发过来的消息 2.根据消息类型进行处理 a.登录消息 b.退出消息 d.群聊消息 这三类消息都

4、需要给每个客户端发送 e.私聊消息 需要进行指定聊天对象 分析数据结构体:首先我们要考虑一个服务器端的程序如何给每个客户端依次发送消息?1.UDP中如果向某个客户端发送消息,那么我们需要指定对端的地址信息(ip+port)的信息 那么服务器端如何保留这些客户端的信息就是我们需要关注的问题?想想看如何可以实现?。balabala那么我们这里就用的非常广泛的一种数据结构,链表来实现对 客户端地址信息的保留。链表的特点,就不需要说了。我们这里主要关注其 可以动态增长的特点来使用那么这一问题解决之后,我们要做的就是实现相关的数据结构的操作。那么我们分析一下该链表的数据结构构建。数据结构 地址信息节点:

5、t y p e d e f s t r u c t n o d e s t r u c t s o c k a d d r _ i n a d d r;s t r u c t n o d e *n e x t;d a t a _ t;/消息类型#d e f i n e C L I E N T _ T A L K 1 0 0 /私聊+c l i e n t n a m e#d e f i n e S E R V E R _ T A L K 2 0 0 /给所有客户端发送#d e f i n e C L I E N T _ L O G I N 3 0 0 /有客户端登陆,地址存入链表#d e f

6、i n e C L I E N T _ L O G O U T 4 0 0 /有客户端退出,地址从链表删除/消息结构体t y p e d e f s t r u c t l o n g t y p e;/消息类型 c h a r s r c _ n a m e 2 0 ;/自己客户端名字,在运行客户端命令行指定名字 c h a r d s t _ n a m e 2 0 ;/对方客户端名字,在运行客户端命令行指定名字 /客户端登陆时给服务器发自己的名字和地址,/*/私聊时客户端用于指定对方名字,在服务器端可以根据名字找到对应对方的地址 /服务器端转发私聊消息时如果要知道是谁发送,根据地址在链表

7、中查找名字/*/c h a r m t e x t B U F _ S Z ;/消息正文 m s g _ t;分析函数实现:服务器端:1.i n t s e n d _ a s s i g n _ c l i e n t(i n t s e r f d,L i n k l i s t *h e a d,m s g _ t *p m s g);功能:通过名字查找对应的客户端是否存在,存在则发送消息 不存在返回出错信息表示客户端不存在 给指定的客户端发送消息 参数:s e r f d 进行通信的s o c k e t 对应的文件描述符 h e a d 链表的头指针 p m s g 指定的客户端的名

8、字返回值:0 成功 -1 表示没有找到对应的客户端 2.b r o a d c a s t _ a l l _ c l i e n t(i n t s e r f d,L i n k l i s t *h e a d,m s g _ t *p m s g);功能:实现对每个客户端发送消息参数:同上返回值:0 成功3.s t r u c t s o c k a d d r _ i n *f i n d _ a s s i g n _ c l i e n t(L i n k l i s t *h e a d,c h a r *n a m e);功能:从链表中查找对应名字的客户端,找到之后返回其地址

9、信息 3.UDP聊天功能实现(群聊,私聊)/1.头文件#i f n d e f _ H E A D _ H _#d e f i n e _ H E A D _ H _#i n c l u d e#i n c l u d e#i n c l u d e#i n c l u d e#i n c l u d e#i n c l u d e#i n c l u d e#i n c l u d e#i n c l u d e#i n c l u d e /*S e e N O T E S */#i n c l u d e#i n c l u d e#i n c l u d e#i n c l u d e

10、 /#d e f i n e _ D E B _ 1#d e f i n e B U F _ S Z 1 0 2 4#d e f i n e C L I E N T _ T A L K 1 0 0#d e f i n e S E R V E R _ T A L K 2 0 0#d e f i n e C L I E N T _ L O G I N 3 0 0#d e f i n e C L I E N T _ L O G O U T 4 0 0#d e f i n e h a n d l e _ e r r o r(m s g)d o p e r r o r(m s g);e x i t(E

11、X I T _ F A I L U R E);w h i l e(0)t y p e d e f s t r u c t s o c k a d d r s a _ t;t y p e d e f s t r u c t l o n g t y p e;/消息类型 /c h a r n a m e 2 0 ;/客户端名字/L O N G I N 时给服务器发自己的名字,私聊时指定对方名字 c h a r s r c _ n a m e 2 0 ;c h a r d s t _ n a m e 2 0 ;c h a r m t e x t B U F _ S Z ;/消息正文 m s g _ t

12、;/链表的结点数据/t y p e d e f s t r u c t s o c k a d d r _ i n d a t a _ t;/t y p e d e f i n t d a t a _ t;t y p e d e f s t r u c t s t r u c t s o c k a d d r _ i n a d d r;/客户端地址 c h a r n a m e 2 0 ;/客户端名字 d a t a _ t;/链表的结点类型t y p e d e f s t r u c t _ n o d e _ d a t a _ t d a t a;s t r u c t _ n

13、o d e _ *n e x t;l i n k n o d e _ t,*l i n k l i s t _ t;/创建链表的操作e x t e r n l i n k l i s t _ t c r e a t e _ e m p t y _ l i n k l i s t();/插入链表e x t e r n i n t i n s e r t _ h e a d _ l i n k l i s t(l i n k l i s t _ t h e a d,d a t a _ t d a t a);/删除链表e x t e r n i n t d e l e t e _ a s s i g

14、 n _ n o d e(l i n k l i s t _ t h e a d,d a t a _ t d a t a);#e n d i f/2.链表操作的函数实现#i n c l u d e h e a d.h l i n k l i s t _ t c r e a t e _ e m p t y _ l i n k l i s t()l i n k n o d e _ t *h e a d =N U L L;h e a d =(l i n k n o d e _ t *)m a l l o c(s i z e o f(l i n k n o d e _ t);h e a d-n e x

15、 t =N U L L;r e t u r n h e a d;i n t i n s e r t _ h e a d _ l i n k l i s t(l i n k l i s t _ t h e a d,d a t a _ t d a t a)l i n k n o d e _ t *t e m p =N U L L;t e m p =(l i n k n o d e _ t *)m a l l o c(s i z e o f(l i n k n o d e _ t);t e m p-d a t a =d a t a;t e m p-n e x t =h e a d-n e x t;h

16、 e a d-n e x t =t e m p;r e t u r n 0;i n t d e l e t e _ a s s i g n _ n o d e(l i n k l i s t _ t h e a d,d a t a _ t d a t a)l i n k n o d e _ t *p =h e a d;l i n k n o d e _ t *t e m p =N U L L;/*w h i l e(p-n e x t&p-n e x t-d a t a !=d a t a)*/w h i l e(p-n e x t&(m e m c m p(&p-n e x t-d a t

17、a,&d a t a,s i z e o f(d a t a)!=0)p =p-n e x t;i f(p-n e x t =N U L L)r e t u r n -1;t e m p =p-n e x t;p-n e x t =t e m p-n e x t;f r e e(t e m p);t e m p =N U L L;r e t u r n 0;#i f 0i n t p r i n t _ l i n k l i s t(l i n k l i s t _ t h e a d)l i n k n o d e _ t *p =h e a d-n e x t;w h i l e(p)

18、p r i n t f(%-4 d ,p-d a t a);p =p-n e x t;p u t c h a r(n );r e t u r n 0;i n t m a i n(i n t a r g c,c o n s t c h a r *a r g v )l i n k l i s t _ t h e a d =N U L L;i n t i =0;h e a d =c r e a t e _ e m p t y _ l i n k l i s t();f o r(i =0;i n e x t;w h i l e(p)i f(s t r n c m p(p m s g-s r c _ n

19、 a m e,p-d a t a.n a m e,2 0)!=0)/不给自己回发消息 s e n d t o(s o c k f d,p m s g,s i z e o f(m s g _ t),0,(s a _ t *)&p-d a t a.a d d r,s i z e o f(s a _ t);/*p r i n t f(m s g.m t e x t =%s n ,m s g.m t e x t);*/#i f d e f _ D E B _ p u t s(=b r o a d c a s t=);p r i n t f(I p:t%s n ,i n e t _ n t o a(p-

20、d a t a.s i n _ a d d r);p r i n t f(P o r t:t%d n ,n t o h s(p-d a t a.s i n _ p o r t);p r i n t f(I n f o:t%s n ,p m s g-m t e x t);p u t s(=);#e n d i f p =p-n e x t;r e t u r n 0;s t r u c t s o c k a d d r _ i n *f i n d _ c l i e n t _ a d d r(l i n k l i s t _ t a d d r l i s t,c h a r *p n

21、a m e)l i n k n o d e _ t *p =a d d r l i s t-n e x t;w h i l e(p)i f(s t r c m p(p-d a t a.n a m e,p n a m e)=0)b r e a k;p =p-n e x t;i f(p =N U L L)r e t u r n N U L L;r e t u r n&p-d a t a.a d d r;i n t s e n d _ a s s i g n _ c l i e n t(i n t s o c k f d,l i n k l i s t _ t a d d r l i s t,m s

22、 g _ t *p m s g,s t r u c t s o c k a d d r _ i n *m y a d d r)s t r u c t s o c k a d d r _ i n *p a d d r =N U L L;p a d d r =f i n d _ c l i e n t _ a d d r(a d d r l i s t,p m s g-d s t _ n a m e);i f(p a d d r =N U L L)/未找到指定客户端,回送失败信息 p m s g-t y p e =C L I E N T _ T A L K;s p r i n t f(p m s

23、g-m t e x t,E r r o r,%s c l i e n t n o t e x i s t!n ,p m s g-d s t _ n a m e);s p r i n t f(p m s g-d s t _ n a m e,%s ,p m s g-s r c _ n a m e);s e n d t o(s o c k f d,p m s g,s i z e o f(m s g _ t),0,(s a _ t *)m y a d d r,s i z e o f(s a _ t);r e t u r n -1;/找到指定客户端,直接转发 s e n d t o(s o c k f

24、d,p m s g,s i z e o f(m s g _ t),0,(s a _ t *)p a d d r,s i z e o f(s a _ t);r e t u r n 0;i n t m a i n(i n t a r g c,c o n s t c h a r *a r g v )/*i n t n =0;*/m s g _ t m s g;p i d _ t p i d =0;d a t a _ t d a t a;i n t s o c k f d =0;/*s t a t i c s t r u c t s o c k a d d r _ i n a d d r b a k;

25、*/*c h a r b u f B U F _ S Z =0 ;*/s o c k l e n _ t a d d r l e n =s i z e o f(s a _ t);s t r u c t s o c k a d d r _ i n p e e r _ a d d r;s t r u c t s o c k a d d r _ i n s e r v e r _ a d d r;l i n k l i s t _ t a d d r _ l i s t =N U L L;/1.命令行参数的处理 i f (a r g c !=3)f p r i n t f(s t d e r r,U

26、 s a g e%s i p p o r t n ,a r g v 0 );e x i t(E X I T _ F A I L U R E);/1.创建s o c k e t i f(s o c k f d =s o c k e t(A F _ I N E T,S O C K _ D G R A M,0)0)h a n d l e _ e r r o r(s o c k e t );/2.填充地址信息 b z e r o(&s e r v e r _ a d d r,s i z e o f(s e r v e r _ a d d r);s e r v e r _ a d d r.s i n _

27、 f a m i l y =A F _ I N E T;s e r v e r _ a d d r.s i n _ p o r t =h t o n s(a t o i(a r g v 2 );s e r v e r _ a d d r.s i n _ a d d r.s _ a d d r =i n e t _ a d d r(a r g v 1 );/3.绑定地址信息 i f(b i n d(s o c k f d,(s a _ t *)&s e r v e r _ a d d r,s i z e o f(s a _ t)0)h a n d l e _ e r r o r(b i n d

28、);i f(p i d =f o r k()0)/服务器端:父进程 1.从键盘获得数据,2.发送给服务器自己,有子进程接受处理 w h i l e(1)p u t c h a r();f g e t s(m s g.m t e x t,s i z e o f(m s g.m t e x t),s t d i n);m s g.m t e x t s t r l e n(m s g.m t e x t)-1 =0 ;m s g.t y p e =S E R V E R _ T A L K;/服务器端的消息,相当与系统消息 s p r i n t f(m s g.s r c _ n a m e,S

29、 Y S T E M );/服务器端名为S Y S T E R M s e n d t o(s o c k f d,&m s g,s i z e o f(m s g),0,(s a _ t *)&s e r v e r _ a d d r,s i z e o f(s a _ t);e l s e /创建空链表 a d d r _ l i s t =c r e a t e _ e m p t y _ l i n k l i s t();w h i l e(1)r e c v f r o m(s o c k f d,&m s g,s i z e o f(m s g),0,(s a _ t *)&p

30、 e e r _ a d d r,&a d d r l e n);#i f d e f _ D E B _ p u t s(=);p r i n t f(I p:t%s n ,i n e t _ n t o a(p e e r _ a d d r.s i n _ a d d r);p r i n t f(P o r t:t%d n ,n t o h s(p e e r _ a d d r.s i n _ p o r t);p r i n t f(I n f o:t%s n ,m s g.m t e x t);p u t s(=);#e n d i f s w i t c h(m s g.t y

31、 p e)c a s e C L I E N T _ T A L K:/转发给对应的客户端 s e n d _ a s s i g n _ c l i e n t(s o c k f d,a d d r _ l i s t,&m s g,&p e e r _ a d d r);b r e a k;c a s e S E R V E R _ T A L K:/转发给所有的客户端#i f d e f _ D E B _ p r i n t f(S o m e o n e t a l k!n );#e n d i f b r o a d c a s e _ t o _ c l i e n t(s o

32、 c k f d,a d d r _ l i s t,&m s g);b r e a k;c a s e C L I E N T _ L O G I N:/登录消息,通知所有的客户端#i f d e f _ D E B _ p r i n t f(C L I E N T _ L O G I N n );#e n d i f b r o a d c a s e _ t o _ c l i e n t(s o c k f d,a d d r _ l i s t,&m s g);/链表中数据 b z e r o(&d a t a,s i z e o f(d a t a);d a t a.a d d

33、r =p e e r _ a d d r;s p r i n t f(d a t a.n a m e,%s ,m s g.s r c _ n a m e);i n s e r t _ h e a d _ l i n k l i s t(a d d r _ l i s t,d a t a);/*i n s e r t _ h e a d _ l i n k l i s t(a d d r _ l i s t,p e e r _ a d d r);*/b r e a k;c a s e C L I E N T _ L O G O U T:/登出消息,通知所有的客户端#i f d e f _ D E

34、 B _ p r i n t f(C L I E N T _ L O G O U T n );#e n d i f /链表中数据 b z e r o(&d a t a,s i z e o f(d a t a);d a t a.a d d r =p e e r _ a d d r;s p r i n t f(d a t a.n a m e,%s ,m s g.s r c _ n a m e);d e l e t e _ a s s i g n _ n o d e(a d d r _ l i s t,d a t a);/*d e l e t e _ a s s i g n _ n o d e(a

35、d d r _ l i s t,p e e r _ a d d r);*/b r o a d c a s e _ t o _ c l i e n t(s o c k f d,a d d r _ l i s t,&m s g);b r e a k;d e f a u l t:p r i n t f(O t h e r m e s s a g e t y p e!n );c o n t i n u e;c l o s e(s o c k f d);r e t u r n 0;/4.客户端#i n c l u d e h e a d.h/./c l i e n t i p p o r t c l i

36、 e n t _ n a m ei n t m a i n(i n t a r g c,c o n s t c h a r *a r g v )/*i n t n =0;*/m s g _ t m s g;p i d _ t p i d =0;i n t s o c k f d =0;/*c h a r b u f B U F _ S Z =0 ;*/s o c k l e n _ t a d d r l e n =s i z e o f(s a _ t);/*s t r u c t s o c k a d d r _ i n p e e r _ a d d r;*/s t r u c t s

37、 o c k a d d r _ i n s e r v e r _ a d d r;/1.命令行参数的判断 i f (a r g c 4)f p r i n t f(s t d e r r,U s a g e%s i p p o r t c l i e n t _ n a m e n ,a r g v 0 );e x i t(E X I T _ F A I L U R E);/1.创建套接字 i f(s o c k f d =s o c k e t(A F _ I N E T,S O C K _ D G R A M,0)0)h a n d l e _ e r r o r(s o c k e

38、t );/2.填充地址结构信息 b z e r o(&s e r v e r _ a d d r,s i z e o f(s e r v e r _ a d d r);s e r v e r _ a d d r.s i n _ f a m i l y =A F _ I N E T;s e r v e r _ a d d r.s i n _ p o r t =h t o n s(a t o i(a r g v 2 );s e r v e r _ a d d r.s i n _ a d d r.s _ a d d r =i n e t _ a d d r(a r g v 1 );/3.填充登录信息

39、 b z e r o(&m s g,s i z e o f(m s g);m s g.t y p e =C L I E N T _ L O G I N;s p r i n t f(m s g.s r c _ n a m e,%s ,a r g v 3 );s p r i n t f(m s g.m t e x t,%s c l i e n t l o g i n!,a r g v 3 );s e n d t o(s o c k f d,&m s g,s i z e o f(m s g),0,(s a _ t *)&s e r v e r _ a d d r,s i z e o f(s a _

40、t);i f(p i d =f o r k()0)/父进程 1.从键盘获得数据,2.发送给服务器端 w h i l e(1)p r i n t f(I n p u t c l i e n t n a m e:);/填入对方名字 f g e t s(m s g.d s t _ n a m e,s i z e o f(m s g.d s t _ n a m e),s t d i n);m s g.d s t _ n a m e s t r l e n(m s g.d s t _ n a m e)-1 =0 ;/清空输入缓冲区 /*w h i l e(g e t c h a r()!=n );*/*

41、p u t c h a r();*/p r i n t f(I n p u t :);/填入内容 f g e t s(m s g.m t e x t,s i z e o f(m s g.m t e x t),s t d i n);m s g.m t e x t s t r l e n(m s g.m t e x t)-1 =0 ;i f(s t r n c m p(m s g.m t e x t,q u i t ,4)=0)b r e a k;i f(s t r n c m p(m s g.d s t _ n a m e,S Y S T E R M ,7)=0)/填入 群聊 消息类型 m s

42、g.t y p e =S E R V E R _ T A L K;e l s e /填入 私聊 消息类型 m s g.t y p e =C L I E N T _ T A L K;/填入客户端自己名字 s p r i n t f(m s g.s r c _ n a m e,%s ,a r g v 3 );s e n d t o(s o c k f d,&m s g,s i z e o f(m s g),0,(s a _ t *)&s e r v e r _ a d d r,s i z e o f(s a _ t);/填充登出消息 /填入消息类型 m s g.t y p e =C L I E N

43、 T _ L O G O U T;/填入客户端自己名字 s p r i n t f(m s g.s r c _ n a m e,%s ,a r g v 3 );s p r i n t f(m s g.m t e x t,c l i e n t l o g o u t!);s e n d t o(s o c k f d,&m s g,s i z e o f(m s g),0,(s a _ t *)&s e r v e r _ a d d r,s i z e o f(s a _ t);k i l l(p i d,S I G U S R 1);/杀死子进程 w a i t(N U L L);/回收子

44、进程 e l s e w h i l e(1)r e c v f r o m(s o c k f d,&m s g,s i z e o f(m s g),0,(s a _ t *)&s e r v e r _ a d d r,&a d d r l e n);p u t s(=);#i f d e f _ D E B _ p r i n t f(I p:t%s n ,i n e t _ n t o a(s e r v e r _ a d d r.s i n _ a d d r);p r i n t f(P o r t:t%d n ,n t o h s(s e r v e r _ a d d r.

45、s i n _ p o r t);#e n d i f p r i n t f(:t%s n ,m s g.s r c _ n a m e,m s g.m t e x t);p u t s(=);c l o s e(s o c k f d);r e t u r n 0;运行验证:1.分别运行客户端和服务器程序./s e r v e r 1 2 7.0.0.1 8 8 8 8 2.运行两个客户端程序./c l i e n t 1 2 7.0.0.1 8 8 8 8 AA 客户端运行之后,运行B 客户端./c l i e n t 1 2 7.0.0.1 8 8 8 8 B之后A 端的效果服务器发送 系统级别 的消息客户端A 的情况:客户端B 的情况:注意:B 本身不会接受到自己的群聊消息后续可以依次测试:1 .服务器端输入信息 发送消息的情况 2 .输入q u i t 退出的情况 3 .指定客户端进行聊天的情况4.总结 本练习集合了数据结构的相关使用,以及UDP网络编程的知识,实现了一个小的功能,初步体会了知识之间的一个贯穿和学习 学习要掌握逻辑性,理清关系。理解+记忆的学习!

展开阅读全文
部分上传会员的收益排行 01、路***(¥15400+),02、曲****(¥15300+),
03、wei****016(¥13200+),04、大***流(¥12600+),
05、Fis****915(¥4200+),06、h****i(¥4100+),
07、Q**(¥3400+),08、自******点(¥2400+),
09、h*****x(¥1400+),10、c****e(¥1100+),
11、be*****ha(¥800+),12、13********8(¥800+)。
相似文档                                   自信AI助手自信AI助手
百度文库年卡

猜你喜欢                                   自信AI导航自信AI导航
搜索标签

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        获赠5币

©2010-2024 宁波自信网络信息技术有限公司  版权所有

客服电话:4008-655-100  投诉/维权电话:4009-655-100

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :gzh.png    weibo.png    LOFTER.png 

客服