/// <summary> /// 合并分组发送的数据 /// </summary> /// <param name="buff">当前接收的其中一组数据</param> private void BuffMerge(byte[] buff, EndPoint remote, int len, int timeout = 30000) { RecvBuff recvBuff = new RecvBuff(); //top(1) +区分标识符int64(8) + 分包总数int32(4) + 当前分包int32(4) + data + last(1) if (buff[0] != topBuff) { return; } recvBuff.id = BitConverter.ToInt64(buff, 1); int maxCount = BitConverter.ToInt32(buff, 9); int count = BitConverter.ToInt32(buff, 13); if (buff[len - 1] != lastBuff) { return; } int index = -1;//当前操作的recvBuffs中的序列项 bool isExist = false; for (int i = 0; i < recvBuffs.Count; i++) { if (recvBuffs[i].id == recvBuff.id) { isExist = true; index = i;//记录即将修改的位置 RecvBuff recvBuff_t = recvBuffs[i]; ++recvBuff_t.count; recvBuff_t.timeout = DateTime.Now; recvBuff_t.buf[count] = new byte[len - 18]; Buffer.BlockCopy(buff, 17, recvBuff_t.buf[count], 0, recvBuff_t.buf[count].Length); recvBuffs[i] = recvBuff_t; break; } else { TimeSpan ts1 = new TimeSpan(recvBuffs[i].timeout.Ticks); TimeSpan ts2 = new TimeSpan(DateTime.Now.Ticks); TimeSpan ts3 = ts1.Subtract(ts2).Duration(); //你想转的格式 ts3.TotalMilliseconds.ToString(); if (ts3.TotalMilliseconds > timeout) { recvBuffs.RemoveAt(i);//超时,删除该id的全部记录 --i; } } } if (!isExist)//如果是没有记录的 { log.Message = "接收到一个连接: " + maxCount.ToString(); Trace(this, log); recvBuff.timeout = DateTime.FromBinary(recvBuff.id); recvBuff.buf = new byte[maxCount][]; recvBuff.buf[count] = new byte[len - 18]; Buffer.BlockCopy(buff, 17, recvBuff.buf[count], 0, recvBuff.buf[count].Length); recvBuff.count = 1; index = recvBuffs.Count;//记录即将插入的位置 recvBuffs.Add(recvBuff); } if (maxCount == recvBuffs[index].count) //数据已经收集全 { List <byte> callbackBuff = new List <byte>(); foreach (byte[] tbuf in recvBuffs[index].buf) { callbackBuff.AddRange(tbuf); } RecvBuffEventArgs arg = new RecvBuffEventArgs(); arg.endPoint = remote; arg.buff = callbackBuff.ToArray(); recvBuffs.RemoveAt(index);//完成任务,删除该id的全部记录 RecvCallback(this, arg); } else if (maxCount < recvBuffs[index].count) { recvBuffs.Clear(); } }
//클라이언트에서 넘어오는 데이터 처리 void SessionRecvData(Session sender, RecvBuff e) { if (e.msgType == (int)MsgType.String) { string s = System.Text.Encoding.UTF8.GetString(e.memoryStream.ToArray()); JObject jObject = JObject.Parse(s); Int32 packetID = (Int32)jObject["PacketID"]; PacketResponse response = new PacketResponse((PacketID)packetID, s); if (packetID == (int)PacketID.PacketID_Connect_Req) { PacketData_ConnectReq req = response.Parsing <PacketData_ConnectReq>(); RecvConnectReq(sender, response); //로그인 한 사람이 있으면 각 클라이언트 리스트를 전달한다. List <String> presentSessionList = new List <string>(); //현재로그인 인원 foreach (Session session in sessionList) { presentSessionList.Add(session.userId); } req.presentSessionList = presentSessionList; //유저정보를 취득하여 보낸다. req.userList = _db.getUserLIst(); //로그인인원에게 리스트 갱신처리 foreach (Session session in sessionList) { // 로그인한사람의 리스트 처리 if (session.userId.Equals(sender.userId)) { //공지사항 리스트를 가져간다. req.noticeList = _db.getNoticeList(); //메세지 리스트를 가져간다. req.messageList = _db.getUnReadBoarderDetail(sender.userId); } else { req.noticeList = null; req.messageList = null; } session.Send(req); } } else if (packetID == (int)PacketID.PacketID_Notice_Detail) { PacketData_NoticeDetail req = response.Parsing <PacketData_NoticeDetail>(); Invoke((MethodInvoker) delegate { req.noticeDetail = _db.getNoticeDetail(req.noticeNum, sender.userId); Session session = GetSessionFromList(sender.userId); if (session != null) { session.Send(req); } }); } else if (packetID == (int)PacketID.PacketID_Send_Notice) { PacketData_SendNotice req = response.Parsing <PacketData_SendNotice>(); int boardNo = 0; if (req.noticeProcess.Equals("U")) { _db.updateNoticeDetail(req.noticeDetail); boardNo = req.noticeNum; req.noticeProcess = "R"; } else if (req.noticeProcess.Equals("D")) { _db.deleteNoticeDetail(req.noticeNum); req.noticeProcess = "D"; } else { req.noticeDetail.Add("ID_READER", sender.userId); _db.insertNoticeDetail(req.noticeDetail); req.noticeProcess = "R"; } //req.boardNo = boardNo; //처리 후 읽기 모드 req.noticeList = _db.getNoticeList(); //req.noticeDetail_Rev = _db.getNoticeDetail(boardNo.ToString(), sender.userId); Invoke((MethodInvoker) delegate { //로그인되어 있는 사람 모드에게 오픈처리 foreach (Session session in sessionList) { session.Send(req); } }); } else if (packetID == (int)PacketID.PacketID_Notice_Find) { PacketData_NoticeFind req = response.Parsing <PacketData_NoticeFind>(); req.noticeList = _db.getNoticeListFind(req.criFind); Invoke((MethodInvoker) delegate { Session session = GetSessionFromList(sender.userId); if (session != null) { session.Send(req); } }); } //메세지 관리함 else if (packetID == (int)PacketID.PacketID_Message_Mng) { PacketData_MessageMng req = response.Parsing <PacketData_MessageMng>(); Invoke((MethodInvoker) delegate { req.messageList = _db.getBoarderRcvList(req.criInfo); Session session = GetSessionFromList(sender.userId); if (session != null) { session.Send(req); } }); } //메세지 상세보기 else if (packetID == (int)PacketID.PacketID_Message_Detail) { PacketData_MessageDetail req = response.Parsing <PacketData_MessageDetail>(); Invoke((MethodInvoker) delegate { req.messageDetail = _db.getMessageDetail(req.criInfo); req.messageReaderDetail = _db.getMessageReaderDetail(req.criInfo); Session session = GetSessionFromList(sender.userId); if (session != null) { session.Send(req); } }); } //메세지 검색하기 else if (packetID == (int)PacketID.PacketID_Message_Search) { PacketData_MessageSearch req = response.Parsing <PacketData_MessageSearch>(); Invoke((MethodInvoker) delegate { req.messageList = _db.getBoarderRcvList(req.criInfo); Session session = GetSessionFromList(sender.userId); if (session != null) { session.Send(req); } }); } //메세지 회신 else if (packetID == (int)PacketID.PacketID_Message_ReWrite) { PacketData_MessageReWrite req = response.Parsing <PacketData_MessageReWrite>(); req.messageDetail = _db.getMessageDetail(req.criInfo); Invoke((MethodInvoker) delegate { Session session = GetSessionFromList(sender.userId); if (session != null) { session.Send(req); } }); } //메세지 보내기 else if (packetID == (int)PacketID.PacketID_Send_Msg) { PacketData_SendMessage req = response.Parsing <PacketData_SendMessage>(); int boardNo = _db.insertMessageDetail(req.messageDetail, req.revUserId, sender.userId); req.boardNo = boardNo; Invoke((MethodInvoker) delegate { foreach (String rcvUser in req.revUserId) { Session session = GetSessionFromList(rcvUser); if (session != null) { session.Send(req); } } }); } //메세지 읽기 처리 else if (packetID == (int)PacketID.PacketID_Send_Msg_Read) { PacketData_SendMessage_Read req = response.Parsing <PacketData_SendMessage_Read>(); _db.updateBoardDetail(req.criInfo); } else if (packetID == (int)PacketID.PacketID_Make_Room) { PacketData_MakeRoom req = response.Parsing <PacketData_MakeRoom>(); Invoke((MethodInvoker) delegate { lv_roomList.BeginUpdate(); ListViewItem lvi = new ListViewItem(req.roomNo); Room _room = new Room(); lv_roomList.Items.Add(lvi); List <Session> _roomSessionList = new List <Session>(); foreach (String rcvUser in req.revUserId) { Session session = GetSessionFromList(rcvUser); if (session != null) { _roomSessionList.Add(session); session.Send(req); } } lv_roomList.EndUpdate(); //방의 소유주 _room.mainUserID = req.makeUserId; _room.roomNo = req.roomNo; _room.sessionList = _roomSessionList; roomList.Add(_room); }); } else if (packetID == (int)PacketID.PacketID_Close_Room) { PacketData_CloseRoom req = response.Parsing <PacketData_CloseRoom>(); Invoke((MethodInvoker) delegate { var toRemoveRoom = new List <String>(); foreach (Room _item in roomList) { if (_item.roomNo.Equals(req.roomNo)) { int idx = 0; var toRemoveSession = new List <String>(); while (idx < _item.sessionList.Count) { Session session = _item.sessionList[idx]; if (session.userId.Equals(req.userId)) { toRemoveSession.Add(session.userId); session = null; } if (session != null) { session.Send(req); } ++idx; } _item.sessionList.RemoveAll(d => toRemoveSession.Contains(d.userId)); if (_item.sessionList.Count < 1) { toRemoveRoom.Add(_item.roomNo); lv_roomList.BeginUpdate(); for (int i = 0; i < lv_roomList.Items.Count; i++) { ListViewItem fItem = lv_roomList.Items[i]; if (fItem.SubItems[0].Text.Equals(req.roomNo)) { fItem.Remove(); break; } } lv_roomList.EndUpdate(); } } } roomList.RemoveAll(d => toRemoveRoom.Contains(d.roomNo)); }); } else if (packetID == (int)PacketID.PacketID_Room_Msg) { PacketData_SendRoomMessage req = response.Parsing <PacketData_SendRoomMessage>(); Invoke((MethodInvoker) delegate { recvBox.Text += req.message; foreach (Room _item in roomList) { if (_item.roomNo.Equals(req.roomNo)) { foreach (Session session in _item.sessionList) { if (session != null) { session.Send(req); } } } } }); } } else if (e.msgType == (int)MsgType.File) { } }
public void RecvHeaderCallBack(IAsyncResult ar) { try { int rec = socket.EndReceive(ar); if (rec == 0) { if (Disconnected != null) { Disconnected(this); //Disconnected = null; //Disconnected 함수에서 Close()를 호출 Close에서 null 진행 return; } } if (rec != HEADER_SIZE) { throw new Exception(); } } catch (SocketException se) { switch (se.SocketErrorCode) { case SocketError.ConnectionAborted: case SocketError.ConnectionReset: if (Disconnected != null) { Disconnected(this); //Disconnected = null; //Disconnected 함수에서 Close()를 호출 Close에서 null 진행 return; } break; } } catch (ObjectDisposedException) { return; } catch (NullReferenceException) { return; } catch (Exception ex) { Console.WriteLine(ex.Message); return; } header.datasSize = convertEndian(BitConverter.ToInt32(headerBuff, 0)); header.msgType = BitConverter.ToInt32(headerBuff, 4); if (header.msgType == (int)MsgType.File) { header.fileNameSize = BitConverter.ToInt32(headerBuff, 8); header.fileName = System.Text.Encoding.Default.GetString(headerBuff, 12, header.fileNameSize); recvFileName = header.fileName; // Utils.GetAddSecondFileName(header.fileName); //Console.Write("MsgType File"); //System.Threading.Thread.Sleep(300); } recvBuff = new RecvBuff(header.datasSize); //Array.Clear(recvBuff.byteBuf, 0, recvBuff.byteBuf.Length); recvBuff.msgType = header.msgType; //if (header.msgType == (int)MsgType.File) // recvBuff.fileName = header.fileName; socket.BeginReceive(recvBuff.byteBuf, 0, header.datasSize, SocketFlags.None, RecvDatasCallBack, null); }
//클라이언트에서 넘어오는 데이터 처리 void SessionRecvData(Session sender, RecvBuff e) { if (e.msgType == (int)MsgType.String) { string s = System.Text.Encoding.UTF8.GetString(e.memoryStream.ToArray()); JObject jObject = JObject.Parse(s); Int32 packetID = (Int32)jObject["PacketID"]; PacketResponse response = new PacketResponse((PacketID)packetID, s); if (packetID == (int)PacketID.PacketID_Connect_Req) { PacketData_ConnectReq req = response.Parsing <PacketData_ConnectReq>(); RecvConnectReq(sender, response); //로그인 한 사람이 있으면 각 클라이언트 리스트를 전달한다. List <String> presentSessionList = new List <string>(); //현재로그인 인원 foreach (Session session in sessionList) { presentSessionList.Add(session.userId); } req.presentSessionList = presentSessionList; //로그인인원에게 리스트 갱신처리 foreach (Session session in sessionList) { session.Send(req); } } else if (packetID == (int)PacketID.PacketID_Send_Notice) { PacketData_SendNotice req = response.Parsing <PacketData_SendNotice>(); Invoke((MethodInvoker) delegate { //로그인되어 있는 사람 모드에게 오픈처리 foreach (Session session in sessionList) { session.Send(req); } }); } else if (packetID == (int)PacketID.PacketID_Send_Msg) { PacketData_SendMessage req = response.Parsing <PacketData_SendMessage>(); Invoke((MethodInvoker) delegate { foreach (String rcvUser in req.revUserId) { Session session = GetSessionFromList(rcvUser); if (session != null) { session.Send(req); } } }); } else if (packetID == (int)PacketID.PacketID_Make_Room) { PacketData_MakeRoom req = response.Parsing <PacketData_MakeRoom>(); Invoke((MethodInvoker) delegate { lv_roomList.BeginUpdate(); ListViewItem lvi = new ListViewItem(req.roomNo); Room _room = new Room(); lv_roomList.Items.Add(lvi); List <Session> _roomSessionList = new List <Session>(); foreach (String rcvUser in req.revUserId) { Session session = GetSessionFromList(rcvUser); if (session != null) { _roomSessionList.Add(session); session.Send(req); } } lv_roomList.EndUpdate(); //방의 소유주 _room.mainUserID = req.makeUserId; _room.roomNo = req.roomNo; _room.sessionList = _roomSessionList; roomList.Add(_room); }); } else if (packetID == (int)PacketID.PacketID_Close_Room) { PacketData_CloseRoom req = response.Parsing <PacketData_CloseRoom>(); Invoke((MethodInvoker) delegate { var toRemoveRoom = new List <String>(); foreach (Room _item in roomList) { if (_item.roomNo.Equals(req.roomNo)) { int idx = 0; var toRemoveSession = new List <String>(); while (idx < _item.sessionList.Count) { Session session = _item.sessionList[idx]; if (session.userId.Equals(req.userId)) { toRemoveSession.Add(session.userId); session = null; } if (session != null) { session.Send(req); } ++idx; } _item.sessionList.RemoveAll(d => toRemoveSession.Contains(d.userId)); if (_item.sessionList.Count < 1) { toRemoveRoom.Add(_item.roomNo); lv_roomList.BeginUpdate(); for (int i = 0; i < lv_roomList.Items.Count; i++) { ListViewItem fItem = lv_roomList.Items[i]; if (fItem.SubItems[0].Text.Equals(req.roomNo)) { fItem.Remove(); break; } } lv_roomList.EndUpdate(); } } } roomList.RemoveAll(d => toRemoveRoom.Contains(d.roomNo)); }); } else if (packetID == (int)PacketID.PacketID_Room_Msg) { PacketData_SendRoomMessage req = response.Parsing <PacketData_SendRoomMessage>(); Invoke((MethodInvoker) delegate { recvBox.Text += req.message; foreach (Room _item in roomList) { if (_item.roomNo.Equals(req.roomNo)) { foreach (Session session in _item.sessionList) { if (session != null) { session.Send(req); } } } } }); } } else if (e.msgType == (int)MsgType.File) { } }