<网络编程培训之四> 编写一个UDP聊天室
来源:互联网 发布:手机淘宝爱逛街不见了 编辑:程序博客网 时间:2024/06/16 01:13
系列博客参考:http://blog.csdn.net/zy416548283/article/category/1108400
代码以编号对应放在Github上:https://github.com/zy416548283/networkProgramming
题目
要求是一个国外大学的课程设计:https://www.cs.uoregon.edu/Classes/15F/cis432/ 这里的Assignment–Programming project #1 简单翻译一下题目的要求,具体要求可以参考原文中的要求
使用udp socket编写一个聊天室,要求具备以下功能
* 每个客户端可以加入多个聊天室(channel);
* 启动客户端的时候 默认加入Common这个聊天室;
* /join ChannelName 是加入聊天室,如果聊天室不存在,就创建这个聊天室;
* /leave ChannelName 是退出聊天室
* /switch ChannelName是切换聊天室
* /list 列出当前存在的聊天室
* /who Channel 列出指定聊天室有的成员
* 不加”/”表示用户在当前聊天室的聊天内容
题目解读
- 会使用前面学过的基础Linux下的socket基础api;
- 报文的格式,题目中已经定义好了;
- 会用到select、多线程之类的高级特性;
- 可以使用STL里的一些数据结构,开发速度更快
关于实现
课程设计中也给出了通信用的关键数据结构,如下所示:
#ifndef DUCKCHAT_H#define DUCKCHAT_H/* Path names to unix domain sockets should not be longer than this */#ifndef UNIX_PATH_MAX#define UNIX_PATH_MAX 108#endif/* This tells gcc to "pack" the structure. Normally, gcc will * inserting padding into a structure if it feels it is convenient. * When the structure is packed, gcc gaurantees that all the bytes * will fall exactly where specified. */#define packed __attribute__((packed))/* Define the length limits */#define REQ_MAX 4096#define USERNAME_MAX 32#define CHANNEL_MAX 32#define SAY_MAX 64#define HOST_MAX 256/* Define some types for designating request and text codes */typedef int request_t;typedef int text_t;typedef int s2s_t;/* Define codes for request types. These are the messages sent to the server. */#define REQ_LOGIN 0#define REQ_LOGOUT 1#define REQ_JOIN 2#define REQ_LEAVE 3#define REQ_SAY 4#define REQ_LIST 5#define REQ_WHO 6#define REQ_KEEP_ALIVE 7 /* Only needed by graduate students *//* Define codes for text types. These are the messages sent to the client. */#define TXT_SAY 0#define TXT_LIST 1#define TXT_WHO 2#define TXT_ERROR 3/*#define S2S_JOIN 8#define S2S_LEAVE 9#define S2S_SAY 10*///_____________________________________________________________________/* This structure is used for a generic request type, to the server. */struct request { request_t req_type;} packed;/* Once we've looked at req_type, we then cast the pointer to one of * the types below to look deeper into the structure. Each of these * corresponds with one of the REQ_ codes above. */struct request_login { request_t req_type; /* = REQ_LOGIN */ char req_username[USERNAME_MAX];} packed;struct request_logout { request_t req_type; /* = REQ_LOGOUT */} packed;struct request_join { request_t req_type; /* = REQ_JOIN */ char req_channel[CHANNEL_MAX]; } packed;struct request_leave { request_t req_type; /* = REQ_LEAVE */ char req_channel[CHANNEL_MAX]; } packed;struct request_say { request_t req_type; /* = REQ_SAY */ char req_channel[CHANNEL_MAX]; char req_text[SAY_MAX];} packed;struct request_list { request_t req_type; /* = REQ_LIST */} packed;struct request_who { request_t req_type; /* = REQ_WHO */ char req_channel[CHANNEL_MAX]; } packed;struct request_keep_alive { request_t req_type; /* = REQ_KEEP_ALIVE */} packed;//_____________________________________________________________________/* This structure is used for a generic text type, to the client. */struct text { text_t txt_type;} packed;/* Once we've looked at txt_type, we then cast the pointer to one of * the types below to look deeper into the structure. Each of these * corresponds with one of the TXT_ codes above. */struct text_say { text_t txt_type; /* = TXT_SAY */ char txt_channel[CHANNEL_MAX]; char txt_username[USERNAME_MAX]; char txt_text[SAY_MAX];} packed;/* This is a substructure used by struct text_list. */struct channel_info { char ch_channel[CHANNEL_MAX];} packed;struct text_list { text_t txt_type; /* = TXT_LIST */ int txt_nchannels; struct channel_info txt_channels[0]; // May actually be more than 0} packed;/* This is a substructure used by text_who. */struct user_info { char us_username[USERNAME_MAX];};struct text_who { text_t txt_type; /* = TXT_WHO */ int txt_nusernames; char txt_channel[CHANNEL_MAX]; // The channel requested struct user_info txt_users[0]; // May actually be more than 0} packed;struct text_error { text_t txt_type; /* = TXT_ERROR */ char txt_error[SAY_MAX]; // Error message};#endif
实现源代码放在Github中:https://github.com/zy416548283/networkProgramming/tree/master/4
关于运行与测试
- 课程设计中给出了测试用的server和client,64位Linux下的可执行文件;自测完成后,可以用它给的文件来测试下自己写的server和client
- 我的本地运行结果如下:
1 0
- <网络编程培训之四> 编写一个UDP聊天室
- 网络编程概念。一个UDP构造的聊天室
- 网络编程-UDP协议---简单聊天室程序
- 黑马程序员----网络编程UDP多线程聊天室
- linux网络编程(如何编写一个UDP通信程序)
- VC++之网络编程四 UDP编程实例
- VC++之网络编程四 UDP编程实例
- 网络编程之udp
- 网络编程之UDP
- 网络编程之UDP
- 网络编程之udp
- 网络编程之 UDP
- UDP网络聊天室
- linux网络编程——UDP局域网聊天室
- JAVA网络编程技术 - UDP练习,模仿多线程聊天室
- 网络编程初探--使用UDP协议的简易聊天室
- 10 qt udp编程和网络聊天室的实现
- Java—网络编程实现UDP聊天室(局域网)
- 使用栈判断输入的表达式中括号是否配对
- js中的val(),text()和html()区别
- Caffe之WindowDataLayer 解析
- CountingSort -- 计数排序(C++)
- JavaScript学习(二):原始数据类型-字符串、数字、布尔值、null、undefined
- <网络编程培训之四> 编写一个UDP聊天室
- ubuntu下jdk/maven环境安装
- eclipse中一些常见svn图标的含义
- spring mvc控制器问题
- Installation error code: -103签名不一致错误
- mac 安装 nginx 环境
- 第23讲 项目1:被3或者5整除的数
- centos升级gcc到4.8.1(支持c++11)步骤
- 堆栈窗体QStackedWidget