软件工程 2016.7.4日报

软件工程 2016.7.4日报


 

  今天我进行的主要工作包括了完成服务器端功能的搭建,以及客户端socket通信功能架构的搭建以及部分功能的实现。

  对服务器端,在周五的时候我对于接受消息、处理消息部分的功能还没有实现,今天将代码补全,构建出了一个较完善的服务端代码。

  今天具体实现的代码如下:

    主要实现了检查本地是否包含用户所上的全部课程的聊天室,返回特定聊天室的聊天记录给用户,向特定聊天室记录文件中添加吐槽,以及移除在线好友,处理非法信息等。

    在实现的过程中运用的主要技术包括C#文件操作、JSON封装/解析数据、socket TCP通信等。

  1         #region --- Check Room List ---
  2         /// <summary>
  3         ///     Check the existence of every room in room list received from client
  4         /// </summary>
  5         /// <param name="msg">string of room list</param>
  6         private void CheckRoomList(string s_roomList)
  7         {
  8             // TODO : check the existence of chat file of each room
  9             List<string> roomList = (List<string>)JsonConvert.DeserializeObject(s_roomList, typeof(List<string>));
 10 
 11             foreach (string room in roomList)
 12             {
 13                 string roomFile = room + ".txt";
 14                 if (!File.Exists(@roomFile))
 15                 {
 16                     FileStream fs = new FileStream(roomFile, FileMode.Create);
 17                     fs.Close();
 18                 }                   
 19             }
 20 
 21         }
 22         #endregion
 23 
 24         #region --- Get Room Message ---
 25         /// <summary>
 26         ///     get the history message of the specific chat room
 27         /// </summary>
 28         /// <param name="clientIP">the client IP</param>
 29         /// <param name="msg">the room ID</param>
 30         private void GetRoomMsg(string clientIP, string roomId)
 31         {
 32             // TODO : get the history of specific chat room
 33             string roomFile = roomId + ".txt";
 34 
 35             List<string> msgList = new List<string>();
 36 
 37             String sendMsg = "";
 38 
 39             if (File.Exists(@roomFile))
 40             {
 41                 StreamReader sr = new StreamReader(roomFile, Encoding.Default);
 42                 
 43                 String lineMsg;
 44                 while ((lineMsg = sr.ReadLine()) != null)
 45                     msgList.Add(lineMsg);
 46                 sendMsg = JsonConvert.SerializeObject(msgList);
 47             }
 48             else
 49             {
 50                 FileStream fs = new FileStream(roomFile, FileMode.Create);
 51                 fs.Close();
 52             }
 53 
 54             SendMessage(clientIP, REQUEST_ROOM_MSG, sendMsg);
 55         }
 56         #endregion
 57 
 58         #region --- Add Message To File ---
 59         /// <summary>
 60         ///     put the message into the specific room
 61         /// </summary>
 62         /// <param name="clientIP">the client IP</param>
 63         /// <param name="msg">the string include the room id and received message</param>
 64         private void AddMsgToFile(string clientIP, string msg)
 65         {
 66             // TODO : put the message into the specific room
 67             MsgHandler msgHandler = (MsgHandler)JsonConvert.DeserializeObject(msg, typeof(MsgHandler));
 68 
 69             string roomFile = msgHandler.roomId + ".txt";
 70 
 71             FileStream fs = new FileStream(roomFile, FileMode.OpenOrCreate);
 72             StreamWriter sw = new StreamWriter(fs);
 73             sw.WriteLine(msgHandler.msg);
 74             sw.Close();
 75             fs.Close();
 76         }
 77         #endregion
 78 
 79         #region --- Remove Offline User ---
 80         /// <summary>
 81         ///     remove off line user
 82         /// </summary>
 83         /// <param name="clientIP">the client IP</param>
 84         private void RemoveOfflineUser(string clientIP)
 85         {
 86             Console.WriteLine("User IP : " + clientIP + " has went off line.");
 87 
 88             if (dictSocket.ContainsKey(clientIP))
 89             {
 90                 dictSocket[clientIP].Close();
 91                 dictSocket.Remove(clientIP);
 92             }               
 93 
 94             if (dictThread.ContainsKey(clientIP))
 95             {
 96                 Thread tmp = dictThread[clientIP];
 97                 dictThread.Remove(clientIP);
 98                 tmp.Abort();
 99             }
100                 
101         }
102         #endregion
103 
104         #region --- Invalid Message ---
105         /// <summary>
106         ///     Handle the situation of invalid message
107         /// </summary>
108         /// <param name="clientIP">the client ip</param>
109         private void InvalidMsg(string clientIP)
110         {
111             // TODO : send invalid warning to client
112             SendMessage(clientIP, INVALID_MESSAGE, "");
113         }
114         #endregion

    在客户端我构建了一个程序的架子,并且实现了部分功能。留下没有实现的功能涉及到和UI端的交互问题,目前我还没有想的比较清楚要如何完成这一部分的交互。因为我client在收到消息时是不太容易能够让UI端知道 的,所以要通知UI端对控件内容作更改目前也没有比较好的解决方法。目前想到的方法就是我这边直接去操作UI端的控件,不必通知UI,由我这边直接对空间内容进行修改。但这个方法总觉得不理想,如果有人能够对此类问题有一个较好的解决方法的话请留言告诉我,谢谢!

    今天在UI端实现的代码主要如下:

  1         #region --- Connect To The Server ---
  2         /// <summary>
  3         ///     Connect to the server
  4         /// </summary>
  5         public Client()
  6         {
  7             // get IP address
  8             IPAddress address = IPAddress.Parse(ipAddr);
  9             // create the endpoint
 10             IPEndPoint endpoint = new IPEndPoint(address, port);
 11             // create the socket, use IPv4, stream connection and TCP protocol
 12             socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 13             try
 14             {
 15                 // Connect to the Server
 16                 socketClient.Connect(endpoint);
 17 
 18                 threadClient = new Thread(ReceiveMsg);
 19                 threadClient.IsBackground = true;
 20                 threadClient.Start();
 21             }
 22             catch (SocketException se)
 23             {
 24                 MessageBox.Show("[SocketError]Connection failed: " + se.Message);
 25             }
 26             catch (Exception ex)
 27             {
 28                 MessageBox.Show("[Error]Connection failed: " + ex.Message);
 29             }
 30         }
 31         #endregion
 32 
 33         #region --- Check Room List ---
 34         /// <summary>
 35         ///     check room list
 36         /// </summary>
 37         /// <param name="roomList"></param>
 38         public void CheckRoomList(List<string> roomList)
 39         {
 40             string s_roomList = JsonConvert.SerializeObject(roomList);
 41 
 42             SendMsg(CHECK_ROOM_LIST, s_roomList);
 43         }
 44         #endregion
 45 
 46         #region --- Add New Message ---
 47         /// <summary>
 48         ///     add new message
 49         /// </summary>
 50         /// <param name="roomId"></param>
 51         /// <param name="msg"></param>
 52         public void AddNewMsg(string roomId, string msg)
 53         {
 54             MsgHandler msgHandler = new MsgHandler(roomId, msg);
 55             string sendMsg = JsonConvert.SerializeObject(msgHandler);
 56             
 57             SendMsg(SEND_MSG, sendMsg);
 58         }
 59         #endregion
 60 
 61         #region --- Off Line ---
 62         /// <summary>
 63         ///     go off line
 64         /// </summary>
 65         public void GoOffLine()
 66         {
 67             SendMsg(DISCONNECT, "");
 68         }
 69         #endregion
 70 
 71         #region --- Send Message ---
 72         /// <summary>
 73         ///     Send Message
 74         /// </summary>
 75         /// <param name="flag">msg type</param>
 76         /// <param name="msg">message</param>
 77         private void SendMsg(byte flag, string msg)
 78         {
 79             try
 80             {
 81                 byte[] arrMsg = Encoding.UTF8.GetBytes(msg);
 82                 byte[] sendArrMsg = new byte[arrMsg.Length + 1];
 83 
 84                 // set the msg type
 85                 sendArrMsg[0] = flag;
 86                 Buffer.BlockCopy(arrMsg, 0, sendArrMsg, 1, arrMsg.Length);
 87 
 88                 socketClient.Send(sendArrMsg);
 89             }
 90             catch (SocketException se)
 91             {
 92                 Console.WriteLine("[SocketError] send message error : {0}", se.Message);
 93             }
 94             catch (Exception e)
 95             {
 96                 Console.WriteLine("[Error] send message error : {0}", e.Message);
 97             }
 98         }
 99         #endregion
100 
101         #region --- Receive Message ---
102         /// <summary>
103         ///     receive message
104         /// </summary>
105         private void ReceiveMsg()
106         {
107             while (true)
108             {
109                 // define a buffer for received message
110                 byte[] arrMsg = new byte[1024 * 1024 * 2];
111 
112                 // length of message received
113                 int length = -1;
114 
115                 try
116                 {
117                     // get the message
118                     length = socketClient.Receive(arrMsg);
119 
120                     // encoding the message
121                     string msgReceive = Encoding.UTF8.GetString(arrMsg, 1, length-1);
122 
123                     if (arrMsg[0] == SEND_MSG)
124                     {
125 
126                     }
127                     else if (arrMsg[0] == IS_RECEIVE_MSG)
128                     {
129 
130                     }
131                     else if (arrMsg[0] == IS_NOT_RECEIVE_MSG)
132                     {
133 
134                     }
135                     else if (arrMsg[0] == INVALID_MESSAGE)
136                     {
137 
138                     }
139                     else
140                     {
141 
142                     }
143 
144                 }
145                 catch (SocketException se)
146                 {
147                     //MessageBox.Show("【错误】接收消息异常:" + se.Message);
148                     return;
149                 }
150                 catch (Exception e)
151                 {
152                     //MessageBox.Show("【错误】接收消息异常:" + e.Message);
153                     return;
154                 }
155             }
156         }
157         #endregion

    在ReceiveMsg中那几个if else中空出来的部分就是涉及到与UI端交互的部分。

    除此之外,今天晚上在和组长进行讨论时,发现对于服务端在操作文件时要为每个文件加一个锁,这样才能保证数据的同步。所以这也是之后需要修改的地方。

原文地址:https://www.cnblogs.com/fanfan-blogs/p/5642207.html