软件工程 2016.7.3 日报

软件工程 2016.7.3日报


 

  在周五我初步搭建了吐槽墙的结构,实现了部分的功能。经过与组长的讨论,我们最终决定使用TCP通信的方式实现功能。因为对于这种比较明显的C/S结构,UDP方式的通信会使得整体处理信息的过程延迟比较大,不符合功能需求。

  经过讨论分析,Server和Client通信的信息主要有以下几类:

    1、Client向Server发送Client房间列表,Server端check本地是否含有所有房间,若不含的话,需要创建新文件存储响应聊天信息。

    2、Client向Server请求特定房间的聊天记录。

    3、Client向Server发送特定房间的吐槽消息。

    4、Server向Client发送特定房间的聊天记录。

    5、Server向Client发送Client端向Server端发送的消息是否更新成功的信息。

  由此我定义了一下状态字,存于所有消息的第一位,用于标记消息后续部分的作用:

1     private const byte CHECK_ROOM_LIST = 0;
2     private const byte REQUEST_ROOM_MSG = 1;
3     private const byte SEND_MSG = 2;
4     private const byte DISCONNECT = 3;
5     private const byte IS_RECEIVE_MSG = 4;
6     private const byte IS_NOT_RECEIVE_MSG = 5;
7     private const byte INVALID_MESSAGE = 6;

  对于上述消息通信,Client端向Server端发送的消息包含两部分内容,一为房间id,二为吐槽消息,所以需要定义一个结构体保存两部分的内容,而后使用JSON解析工具进行包装、解析等。结构体定义如下:

 1     public struct MsgHandler
 2     {
 3         public string roomId;
 4         public string msg;
 5 
 6         public MsgHandler(string r, string m)
 7         {
 8             roomId = r; msg = m;
 9         }
10     }

  除此之外,实现了服务端的逻辑框架,以及部分的功能,已实现的代码如下:

    开启服务器

 1         public void StartServer()
 2         {
 3             // Create a socket, use IPv4, stream connection and TCP
 4             socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 5 
 6             // create a endpoing which binds the ip and port 
 7             IPAddress ipAddress = IPAddress.Parse(ipAddr);
 8             IPEndPoint endPoint = new IPEndPoint(ipAddress, port);
 9 
10             try
11             {
12                 // bind the watching socket to the endpoint
13                 socketWatch.Bind(endPoint);
14 
15                 // set the length of waiting queue
16                 socketWatch.Listen(20);
17 
18                 // Create a watching thread
19                 threadWatch = new Thread(WatchConnection);
20                 // Set the background property
21                 threadWatch.IsBackground = true;
22                 // Start the thread
23                 threadWatch.Start();
24 
25                 Console.WriteLine();
26                 Console.WriteLine("                          ---Server Start---");
27                 Console.WriteLine();
28 
29                 return;
30             }
31             catch (SocketException se)
32             {
33                 Console.WriteLine("[SocketERROR]" + se.Message);
34                 return;
35             }
36             catch (Exception e)
37             {
38                 Console.WriteLine("[ERROR]" + e.Message);
39                 return;
40             }
41         }

    监听客户请求

 1         private void WatchConnection()
 2         {
 3             // keep watching 
 4             while (true)
 5             {
 6                 Socket socketConnection = null;
 7                 try
 8                 {
 9                     // watch the request, if has, create a socket for it
10                     socketConnection = socketWatch.Accept();
11                     string socketKey = socketConnection.RemoteEndPoint.ToString();
12                     
13                     // save every socket with the key in the form of IP : port
14                     dictSocket.Add(socketKey, socketConnection);
15 
16                     Console.WriteLine("User IP : {0} has connected...", socketKey);
17 
18                     // Create a thread to watch the data sent from client for every socket
19                     // Create the communicate thread
20                     Thread threadCommunicate = new Thread(ReceiveMsg);
21                     threadCommunicate.IsBackground = true;
22                     threadCommunicate.Start(socketConnection);
23 
24                     dictThread.Add(socketKey, threadCommunicate);
25 
26                 }
27                 catch (SocketException se)
28                 {
29                     Console.WriteLine("[ERROR]" + se.Message);
30                     return;
31                 }
32                 catch (Exception e)
33                 {
34                     Console.WriteLine("[ERROR]" + e.Message);
35                     return;
36                 }
37             }
38         }

    监听用户信息

 1         private void ReceiveMsg(object socketClientPara)
 2         {
 3             Socket socketClient = socketClientPara as Socket;
 4             string socketKey = socketClient.RemoteEndPoint.ToString();
 5 
 6             while (true)
 7             {
 8                 // define a buffer for received message
 9                 byte[] msgReceiver = new byte[1024 * 1024 * 2];
10 
11                 // length of received message
12                 int length = -1;
13 
14                 try
15                 {
16                     length = socketClient.Receive(msgReceiver);
17                 }
18                 catch (SocketException se)
19                 {
20                     Console.WriteLine("[ERROR]" + socketKey + " receive error. Message: " + se.Message);
21 
22                     dictSocket[socketKey].Close();
23                     Thread tmp = dictThread[socketKey];
24 
25                     // Remove the error object
26                     dictSocket.Remove(socketKey);
27                     dictThread.Remove(socketKey);
28                     tmp.Abort();
29 
30                     return;
31                 }
32                 catch (Exception e)
33                 {
34                     Console.WriteLine("[ERROR]" + e.Message);
35                     return;
36                 }
37 
38                 string msg = Encoding.UTF8.GetString(msgReceiver, 1, length - 1);
39 
40                 if (msgReceiver[0] == CHECK_ROOM_LIST)
41                     CheckRoomList(msg);
42                 else if (msgReceiver[0] == REQUEST_ROOM_MSG)
43                     GetRoomMsg(socketKey, msg);
44                 else if (msgReceiver[0] == SEND_MSG)
45                     AddMsgToFile(socketKey, msg);
46                 else if (msgReceiver[0] == DISCONNECT)
47                     RemoveOfflineUser(socketKey);
48                 else
49                     InvalidMsg(socketKey);
50             }
51         }

    发送消息

 1         private void SendMessage(string clientIP, byte flag, string msg)
 2         {
 3             try
 4             {
 5                 byte[] arrMsg = Encoding.UTF8.GetBytes(msg);
 6                 byte[] sendArrMsg = new byte[arrMsg.Length + 1];
 7 
 8                 // set the msg type
 9                 sendArrMsg[0] = flag;
10                 Buffer.BlockCopy(arrMsg, 0, sendArrMsg, 1, arrMsg.Length);
11 
12                 dictSocket[clientIP].Send(sendArrMsg);
13             }
14             catch (SocketException se)
15             {
16                 Console.WriteLine("[SocketERROR] send message error : {0}", se.Message);
17             }
18             catch (Exception e)
19             {
20                 Console.WriteLine("[ERROR] send message error : {0}", e.Message);
21             }
22         }
原文地址:https://www.cnblogs.com/fanfan-blogs/p/5639236.html