软件工程 2016.7.5日报

软件工程 2016.7.5日报



  今天我的主要工作是晚场了客户端功能的搭建、连接了客户端UI与客户端Socket部分的功能,为服务端增加了文件锁避免多个线程对同一文件同时操作。

  具体实现的工作有:

  客户端功能搭建:

    在客户端完成了通信功能的实现:

  补全了昨天空缺的代码,在收到消息时进行相应的处理:

 1                     if (arrMsg[0] == SEND_MSG)
 2                     {
 3                         ReceiveMsgFromServer(msgReceive);
 4                     }
 5                     else if (arrMsg[0] == IS_RECEIVE_MSG)
 6                     {
 7                         Application.Current.Dispatcher.Invoke(new Action(delegate
 8                         {
 9                             MessageBox.Show("发送消息成功");
10                         }));
11                     }
12                     else if (arrMsg[0] == IS_NOT_RECEIVE_MSG)
13                     {
14                         Application.Current.Dispatcher.Invoke(new Action(delegate
15                         {
16                             MessageBox.Show("[Error]发送消息失败");
17                         }));
18                     }
19                     else if (arrMsg[0] == INVALID_MESSAGE)
20                     {
21                         Application.Current.Dispatcher.Invoke(new Action(delegate
22                         {
23                             MessageBox.Show("[Error]通信过程出错");
24                         }));
25                     }
26                     else
27                     {
28                         Application.Current.Dispatcher.Invoke(new Action(delegate
29                         {
30                             MessageBox.Show("[Error]通信过程出错");
31                         }));
32                     }

  其中,ReceiveMsgFromServer(string str);的具体实实现如下:

 1         #region --- Receive Room History Message ---
 2         /// <summary>
 3         ///     Receive Message
 4         /// </summary>
 5         /// <param name="msgReceive"></param>
 6         private void ReceiveMsgFromServer(string msgReceive)
 7         {
 8             MsgHandler msgHandler = (MsgHandler)JsonConvert.DeserializeObject(msgReceive, typeof(MsgHandler));
 9             string roomId = msgHandler.roomId;
10             List<string> msgList = msgHandler.msgList;
11
12             Application.Current.Dispatcher.Invoke(new Action(delegate
13             {
14                 tucaoWall.Document.Blocks.Clear();
15                 string room = (string)courseList.SelectedItem;
16                  if (room.Equals(roomId))
17                     foreach (string msg in msgList)
18                     {
19                         // TODO : 将消息逐一添加到显示框中
20                         Paragraph newParagraph = new Paragraph();
21
22                         InlineUIContainer inlineUIContainer = new InlineUIContainer()
23                         {
24                             Child = new TextBlock()
25                             {
26                                 Foreground = new SolidColorBrush(Colors.Black),
27                                 TextWrapping = TextWrapping.Wrap,
28                                 Text = msg + "\r\n"
29                             }
30                         };
31                         newParagraph.Inlines.Add(inlineUIContainer);
32
33                         tucaoWall.Document.Blocks.Add(newParagraph);
34                     }
35
36             }));
37         }
38         #endregion

  客户端UI与客户端Socket的连接

   添加了响应控件的响应,用户点击不同的按钮会调用不同的方法与服务器进行交互。由于代码过于琐碎,在此不做列举。

  

  服务器端修改了部分逻辑,同时对文件增加了读写锁。

   由于原来在服务端对每个用户都新建了一个线程,保证了在接受消息端是同步的。但是却没有保证发送消息、处理文件等的并发性(可以同时操纵多个文件)。所以将相关的方法封装为一个类,对于每一个新链接的用户新建一个该类对象,这样每个用户就可以通过自己保存的类对象进行相关的操作,而互不影响。此部分功能实现代码如下:

   添加从用户ip索引处理对象的字典

        public static Dictionary<string, Handler> dictHandler = new Dictionary<string, Handler>();

   处理对象Handler封装的方法包括

        public void CheckRoomList(string s_roomList);
        public void AddMsgToFile(string clientIP, string msg);
        public void InvalidMsg(string clientIP);
        public void SendMessage(string clientIP, byte flag, string msg);

   使用特定ip对应的Handler对象的方法为

 1 if (msgReceiver[0] == CHECK_ROOM_LIST)
 2     dictHandler[socketKey].CheckRoomList(msg);
 3 else if (msgReceiver[0] == REQUEST_ROOM_MSG)
 4     dictHandler[socketKey].GetRoomMsg(socketKey, msg);
 5 else if (msgReceiver[0] == SEND_MSG)
 6     dictHandler[socketKey].AddMsgToFile(socketKey, msg);
 7 else if (msgReceiver[0] == DISCONNECT)
 8      RemoveOfflineUser(socketKey);
 9 else
10      dictHandler[socketKey].InvalidMsg(socketKey);

   实现上述功能之后,还需要处理文件读写同步的问题,同一文件在同一时间不能被多个线程操作,所以为解决此问题需要为每个文件添加一个读写锁,来控制文件读写同步的问题。

   在程序中创建由文件名索引到读写锁的字典

public static Dictionary<string, Object> dictLocker = new Dictionary<string, object>();

   在每次操作文件时都需要进行并发控制,检测相应读写锁的使用情况,使用例子如下:

 1 lock(Server.dictLocker[room])
 2 {
 3     FileStream fs = new FileStream(roomFile, FileMode.Create);
 4     fs.Close();
 5
 6     lock (Server.dictLocker["room"])
 7     {
 8         string romFile = "room.txt";
 9
10         FileStream f = File.OpenWrite(romFile);
11
12         f.Position = f.Length;
13
14         byte[] writeMsg = Encoding.UTF8.GetBytes(room+"\r\n");
15
16         f.Write(writeMsg, 0, writeMsg.Length);
17
18         f.Close();
19     }
20 }

  通过上述方式,实现了文件的读写控制。

时间: 2025-01-05 21:58:14

软件工程 2016.7.5日报的相关文章

软件工程 2016.7.3 日报

软件工程 2016.7.3日报 在周五我初步搭建了吐槽墙的结构,实现了部分的功能.经过与组长的讨论,我们最终决定使用TCP通信的方式实现功能.因为对于这种比较明显的C/S结构,UDP方式的通信会使得整体处理信息的过程延迟比较大,不符合功能需求. 经过讨论分析,Server和Client通信的信息主要有以下几类: 1.Client向Server发送Client房间列表,Server端check本地是否含有所有房间,若不含的话,需要创建新文件存储响应聊天信息. 2.Client向Server请求特定

软件工程 2016.7.4日报

软件工程 2016.7.4日报 今天我进行的主要工作包括了完成服务器端功能的搭建,以及客户端socket通信功能架构的搭建以及部分功能的实现. 对服务器端,在周五的时候我对于接受消息.处理消息部分的功能还没有实现,今天将代码补全,构建出了一个较完善的服务端代码. 今天具体实现的代码如下: 主要实现了检查本地是否包含用户所上的全部课程的聊天室,返回特定聊天室的聊天记录给用户,向特定聊天室记录文件中添加吐槽,以及移除在线好友,处理非法信息等. 在实现的过程中运用的主要技术包括C#文件操作.JSON封

软件工程 2016.6.30 日报

软件工程 2016.6.30 日报 今天主要学习的内容是C# socket网络编程中的TCP通讯技术.socket编程的原理如下: 在服务端的处理流程为: (1)建立服务器端的Socket,开始侦听整个网络中的连接请求. (2)当检测到来自客户端的连接请求时,向客户端发送收到连接请求的信息,并建立与客户端之间的连接. (3)当完成通信后,服务器关闭与客户端的Socket连接. 在服务端的处理流程为: (1)建立客户端的Socket,确定要连接的服务器的主机名和端口. (2)发送连接请求到服务器,

软件工程 2016.6.29 日报

软件工程 2016.6.29 日报 今天我的主要工作就是调查了解我校的加权平均分计算方法,并将程序加权计算部分予以修正. 通过查阅北工大教务公示,获得信息: 第十条学校利用“学分通过率”和“加权平均分”作为衡量学生在校期间学习质量的主要指标.辅修课程.创新学分和第二课堂的学分和成绩不计入学分通过率和加权平均分的计算.创新学分和第二课堂是学生获得毕业资格的必要条件.理工类专业学生应修不少于4学分的创新学分,其他专业应修不少于2学分的创新学分.第二课堂应修满12学分. 同时,通过询问同学获取了在教务

软件工程 2016.6.28 日报

今天,通过调查表的反馈明确了改进方向.作为组长,我负责整个项目的进度管理和质量控制,10天里的主要方向是: 1.不断进行新版本的需求分析从而明确组员行动方向 2.指导测试人员完成高质量的测试 3.撰写主要的文档 今天完成学习一些网络编程处理ip包方面的知识,对我们的平台拓展可能有一定的帮助. linux下ip头选项ipoption的实现(难以实现,setsockopt()函数不支持BSD标准下的IP_OPTION这一关键字) 在windows下 定义ipoptionhdr结构体 typedef

2016 1 9 日报

回忆自己这段时间的学习,最大的收获有2点,第一,差距在变小,第二,看到的自己的潜能. 自己的不足,学习能力一般,接受新鲜事物能力一般,思路比较发散,有时候想不清楚事情,就做了.这个需要尽快解决, 不过还好,这因为自己还不熟悉这个领域,接触了移动端和PC的框架以后,写了一些页面以后,其实现在好多问题都可以解决了. 比来之前的时候,好了太多,今天使用的框架并不复杂,今天遇到问题的逻辑也不突出,今天的事情也不是凌驾于我的能力之上, 只要努力的同学,都可以在这条路上,应该说任何领域走的很好,只要有足够的

2016年下半年项目管理师中高级报考说明

一.报考条件      亲,没有报考门槛,只要您年满18周岁就可.没有专业.职业和学历限制.二.需要购买哪些辅导资料    1.中高项的官方教材都是柳纯录老师主编的,中级考友最好买一本,高级考友无所谓.最好以张老师的课件为主.    2.张老师亲自编写了过关法宝系列资料,考试必备呀.三.培训效果怎样     合格率54%左右,其中,上午合格率84%左右,案例分析68%左右,论文80%左右.     论文押题神准--学员说的.      张老师的培训良心出品.四.我不是IT专业,也不从事IT岗位,

聊一聊前端模板与渲染那些事儿

欢迎大家收看聊一聊系列,这一套系列文章,可以帮助前端工程师们了解前端的方方面面(不仅仅是代码): https://segmentfault.com/blog/frontenddriver 作为现代应用,ajax的大量使用,使得前端工程师们日常的开发少不了拼装模板,渲染模板.我们今天就来聊聊,拼装与渲染模板的那些事儿. 如果喜欢本文请点击右侧的推荐哦,你的推荐会变为我继续更文的动力 1 页面级的渲染 在刚有web的时候,前端与后端的交互,非常直白,浏览器端发出URL,后端返回一张拼好了的HTML串

使用 Raspberry Pi 上的传感器在 Node.js 中创建一个 IoT Bluemix 应用程序

先决条件 一个IBM Bluemix 帐号,一个 Raspberry Pi 2 或 3,一个 PIR 运动传感器 适用于本文的 Github 存储库 如果您是一位精明的 Bluemix 开发人员,您可能只想看看如何在 node.js 中与 IoT 建立连接,或者只想了解如何从此 github 存储库中拉取我的代码. git clone https://github.com/nicolefinnie/iot-nodejs-tutorial 以下是实现与 IBM IoT 平台连接在一起的 4 个 R