private void SendAck(byte[] data) { //发送ACK报文 MyDataGram pro = MyDataGram.DecodeMessage(data); MyDataGram ack = new MyDataGram(); ack.DstID = pro.SrcID; ack.SrcID = pro.DstID; ack.Text = "__ack__" + pro.Text; ack.Type = MessageType.Text; string tempIP = ""; var resp = CSCore_instance.Query("q" + pro.SrcID); if (resp == "n") { MessageBox.Show("当前好友不在线!"); return; } else { tempIP = resp; } SendUDPData(MyDataGram.EncodeMessage(ack), tempIP, ttPort);//danger! }
public void SaveOneHistory(MyDataGram mdg) { /* * 数据格式: ME_xxx_FRI_xxx.txt * 发送方$信息类型$内容$时间 * ... #time */ string Time = DateTime.Now.ToLongDateString().ToString(); var MyID = mdg.DstID; var FriID = mdg.SrcID; string temp = ""; temp = MyID + "$" + mdg.Type.ToString() + "$" + mdg.Text + "$" + Time; string FileName = "ME_" + MyID + "_FRIEND_" + FriID + ".txt"; File.Delete(@".\data\" + FileName); var fs = new FileStream(@".\data\" + FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite); StreamWriter sw = new StreamWriter(fs); //规定数据结构:FriendID_FriendAlias sw.WriteLine(temp); sw.Flush(); sw.Close(); fs.Close(); }
private bool MatchP2PFile(MyDataGram mdg) { if (P2PFileBuffer == null && P2PFileIDList == null && P2PFileIndexPool == null && ActualFileLength == 0 && P2pMyOriginalPart == null) { return(false); } else { var arr = mdg.GroupFileID.Split(' '); List <string> tempList = new List <string>(); int flag = 0; foreach (var id in arr) { if (id != "") { if (!P2PFileIDList.Contains(id)) { flag = 1; } } } if (flag == 1) { return(false); } return(true); } }
private void SendUDP() { if (friendID[0] == ' ') { MessageBox.Show("暂不支持UDP群组通话"); return; } var text = EditMessage.Text; EditMessage.Text = ""; if (text == "") { MessageBox.Show("发送消息不能为空!"); return; } var temp = "q" + friendID; var resp = CSCore_instance.Query(temp); if (resp == "n") { MessageBox.Show("当前好友不在线!"); this.Close(); return; } else { friendIP = resp; } var msg = new ChattingMessage(); msg.CMType = MessageType.Text; msg.Content = text; msg.DstID = friendID; msg.SrcID = MyID; msg.SendTime = DateTime.Now.ToString(); //P2P发送 MyDataGram mdg = new MyDataGram(); mdg.SrcID = MyID; mdg.Text = text; mdg.DstID = friendID; mdg.Type = MessageType.Text; P2PCore_instance.SendUDPData(MyDataGram.EncodeMessage(mdg), friendIP, SendDataPort); P2PCore_instance.AddUdpMessage(MyDataGram.EncodeMessage(mdg), friendIP, SendDataPort); //回显 msg.Content = "我: " + msg.Content; msg.hori = HorizontalAlignment.Right; ChattingMessageList.Add(msg); ChattingWindowListBox.ScrollIntoView(msg); }
private void SendGroupMessage(string text) { var msg = new ChattingMessage(); foreach (var id in GroupIDList) { if (id == MyID) { continue; } //check online var temp = "q" + id; var resp = CSCore_instance.Query(temp); if (resp == "n") { //MessageBox.Show("当前好友不在线!"); //this.Close(); continue; } else { friendIP = resp; } msg.CMType = MessageType.Text; msg.Content = text; msg.DstID = id; msg.SrcID = MyID; msg.SendTime = DateTime.Now.ToString(); //P2P发送 MyDataGram mdg = new MyDataGram(); mdg.SrcID = MyID; mdg.Text = text; mdg.DstID = id; mdg.GroupID = friendID; mdg.Type = MessageType.Text; P2PCore_instance.SendData(MyDataGram.EncodeMessage(mdg), friendIP, SendDataPort); } if (msg.Content == "__init__") { return; } //回显 msg.Content = "我: " + msg.Content; msg.hori = HorizontalAlignment.Right; ChattingMessageList.Add(msg); ChattingWindowListBox.ScrollIntoView(msg); //遍历所有的group_id 给所有其他人发一个奇怪的message }
private void ReceiveListener() { while (listening) { Thread.Sleep(500); byte[] msg = null; if (inter.messages.Count > 0) { //have new tcp message! msg = inter.messages.Dequeue(); } if (msg != null && msg.Length > 0) { MyDataGram pro = MyDataGram.DecodeMessage(msg); if (pro.Type != MessageType.Disable) { //DistributeMessage(pro); Dispatcher.BeginInvoke(new Dis(DistributeMessage), pro); } } } }
private void AlarmNewMessage(MyDataGram mdg) { //群组消息 string NewMsgAlias = ""; foreach (var fri in FriendList) { if (mdg.SrcID == fri.FriendID) { NewMsgAlias = fri.FriendAlias; } if (mdg.GroupID != "") { //群组 if (fri.FriendID[0] == ' ') { if (GroupIDMatch(mdg.GroupID, fri.FriendID)) { NewMsgAlias = fri.FriendAlias; } } } } if (NewMsgAlias != "") { MessageBox.Show("你收到一个来自: " + NewMsgAlias + "的消息!"); //打开再放进去这一条消息 var hist = new History(); hist.SaveOneHistory(mdg); } else { MessageBox.Show("你收到来自陌生人: " + mdg.SrcID + "的消息!"); var hist = new History(); hist.SaveOneHistory(mdg); } }
public static MyDataGram DecodeMessage(byte[] msg) { /* Protocol * Begin Match: 4B * SrcID: 4B * DstID: 4B * File Name: 4B * File Part Length: 4B * GroupID Length: 4B * GroupID: ?? * * GroupFileIDLength: 4B * GroupFileID: ??? * GroupFileIndex: 4B * * DATA max = 32MB * End Match: 4B */ int MessageLength = msg.Length; MyDataGram result = new MyDataGram(); uint msgBeginMatch = BitConverter.ToUInt32(msg, 0); uint msgEndMatch = BitConverter.ToUInt32(msg, MessageLength - 4); if (msgBeginMatch != BeginMatch || msgEndMatch != EndMatch) { return(result); } uint type = BitConverter.ToUInt32(msg, 4); result.Type = (MessageType)type; result.SrcID = BitConverter.ToUInt32(msg, 8).ToString(); result.DstID = BitConverter.ToUInt32(msg, 12).ToString(); int FileNameLength = BitConverter.ToInt32(msg, 16); int FileLength = BitConverter.ToInt32(msg, 20); int GroupIDLength = BitConverter.ToInt32(msg, 24); if (GroupIDLength != -1) { byte[] GroupNamePart = new byte[GroupIDLength]; Array.Copy(msg, 28, GroupNamePart, 0, GroupIDLength); result.GroupID = Encoding.UTF8.GetString(GroupNamePart); } else { result.GroupID = ""; GroupIDLength = 0; } if (type == 1) { byte[] FileNamePart = new byte[FileNameLength]; Array.Copy(msg, 28 + GroupIDLength, FileNamePart, 0, FileNameLength); result.Text = Encoding.UTF8.GetString(FileNamePart); } else { byte[] FileContent = new byte[FileLength]; byte[] FileNamePart = new byte[FileNameLength]; Array.Copy(msg, 28 + GroupIDLength, FileNamePart, 0, FileNameLength); int GroupFileIDLength = BitConverter.ToInt32(msg, 28 + GroupIDLength + FileNameLength); if (GroupFileIDLength >= 0) { //P2P byte[] GroupFileNamePart = new byte[GroupFileIDLength]; Array.Copy(msg, 32 + GroupIDLength + FileNameLength, GroupFileNamePart, 0, GroupFileIDLength); result.GroupFileID = Encoding.UTF8.GetString(GroupFileNamePart); result.GroupFileIndex = BitConverter.ToInt32(msg, 32 + GroupIDLength + FileNameLength + GroupFileIDLength); Array.Copy(msg, 36 + GroupIDLength + FileNameLength + GroupFileIDLength, FileContent, 0, FileLength); } else { Array.Copy(msg, 32 + GroupIDLength + FileNameLength, FileContent, 0, FileLength); } result.Text = Encoding.UTF8.GetString(FileNamePart); result.FileContent = FileContent; } return(result); }
public static byte[] EncodeMessage(MyDataGram mdg) { /* Protocol * Begin Match: 4B * SrcID: 4B * DstID: 4B * File Name: 4B * File Part Length: 4B * GroupID Length: 4B * GroupID: ??? * * GroupFileIDLength: 4B * GroupFileID: ??? * GroupFileIndex: 4B * * DATA max = 32MB * End Match: 4B */ List <byte> tempmsg = new List <byte>(); bool isFile = false; int FileLength = -1; int FileNameLength = -1; int GroupIdLength = -1; int GroupFileIdLength = -1; if (mdg.GroupID != null) { GroupIdLength = Encoding.UTF8.GetByteCount(mdg.GroupID); } if (mdg.Type == MessageType.File || mdg.Type == MessageType.Image) { isFile = true; FileLength = mdg.FileContent.Length; if (GroupIdLength != -1) { GroupFileIdLength = Encoding.UTF8.GetByteCount(mdg.GroupFileID); } } FileNameLength = Encoding.UTF8.GetByteCount(mdg.Text); tempmsg.AddRange(BitConverter.GetBytes(BeginMatch)); tempmsg.AddRange(BitConverter.GetBytes((uint)mdg.Type)); tempmsg.AddRange(BitConverter.GetBytes(Convert.ToUInt32(mdg.SrcID))); tempmsg.AddRange(BitConverter.GetBytes(Convert.ToUInt32(mdg.DstID))); tempmsg.AddRange(BitConverter.GetBytes(FileNameLength)); tempmsg.AddRange(BitConverter.GetBytes(FileLength)); tempmsg.AddRange(BitConverter.GetBytes(GroupIdLength)); if (GroupIdLength != -1) { tempmsg.AddRange(Encoding.UTF8.GetBytes(mdg.GroupID)); } tempmsg.AddRange(Encoding.UTF8.GetBytes(mdg.Text)); tempmsg.AddRange(BitConverter.GetBytes(GroupFileIdLength)); if (isFile) { if (GroupIdLength != -1) { //P2PFile tempmsg.AddRange(Encoding.UTF8.GetBytes(mdg.GroupFileID)); tempmsg.AddRange(BitConverter.GetBytes(mdg.GroupFileIndex)); } tempmsg.AddRange(mdg.FileContent); } tempmsg.AddRange(BitConverter.GetBytes(EndMatch)); return(tempmsg.ToArray()); }
private void AccecptUdp() { bool OnGoing = true; while (OnGoing) { //todo:加功能,发送端的计时器 //收到udp Thread.Sleep(50); try { var buff = Udplistener.Receive(ref endpoint); int flag = 0; lock (inter) { MyDataGram pro = MyDataGram.DecodeMessage(buff); if (pro.Text.Length > 7) { if (pro.Text.Substring(0, 7) == "__ack__") { for (int i = 0; i < UdpMessageList.Count; i++) { var tempudp = MyDataGram.DecodeMessage(UdpMessageList[i].data); if (tempudp.SrcID == pro.DstID && tempudp.DstID == pro.SrcID) { if (tempudp.Text == pro.Text.Substring(7)) { //成功收到了对应的ack MessageBox.Show("收到了ACK报文."); UdpMessageList.RemoveAt(i); flag = 1; } } } } } if (pro.Type != MessageType.Disable) { if (pro.Text.Length < 7) { SendAck(buff); } else if (pro.Text.Substring(0, 7) != "__ack__") { SendAck(buff); } } if (flag == 0) { inter.messages.Enqueue(buff); } } } catch { //do nothing } lock (inter) { OnGoing = inter.listening; } } }
private async void DistributeMessage(MyDataGram mdg) { //群组的greetings消息:直接加入到通讯录 if (mdg.GroupID != "" && mdg.Text == "__init__" && mdg.DstID == account) { //Greetings Message //Add to Addresbook MilessFriend nf = new MilessFriend(); foreach (var fri in FriendList) { if (fri.FriendID == mdg.SrcID) { nf.FriendAlias = fri.FriendAlias; break; } } nf.FriendAlias = "Group with:" + nf.FriendAlias; nf.FriendID = mdg.GroupID; int chachong = 0; foreach (var fri in FriendList) { var a = fri.FriendID; //为分组 if (a[0] == ' ') { if (GroupIDMatch(fri.FriendID, a)) { chachong = 1; } } } if (chachong == 0) { //本组之前没有出现过 FriendList.Add(nf); listFriends.ScrollIntoView(nf); } return; } var ChattingWindowNumber = ChatWindowList.Count; if (ChattingWindowNumber == 0) { AlarmNewMessage(mdg); } else { int FindWindow = 0; foreach (var cw in ChatWindowList) { if (mdg.GroupID != "") { //由组内成员的学号判断是否为同一分组 if (GroupIDMatch(mdg.GroupID, cw.GetWindowInfo())) { cw.ReceiveMessage(mdg); FindWindow = 1; break; } } if (mdg.SrcID == cw.GetWindowInfo()) { //分给相应的窗口信息 cw.ReceiveMessage(mdg); FindWindow = 1; break; } } if (FindWindow == 0) { AlarmNewMessage(mdg); } } }
public void ReceiveMessage(MyDataGram mdg) { var msg = new ChattingMessage(); msg.SrcID = mdg.SrcID; msg.DstID = mdg.DstID; msg.CMType = (MessageType)(uint)mdg.Type; //文件处理 if (msg.CMType == MessageType.File || msg.CMType == MessageType.Image) { //if (mdg.GroupID[0]==' ') if (mdg.GroupID != "") { if (MatchP2PFile(mdg)) { //same file } else { P2PFileBuffer = null; P2PFileIDList = null; P2PFileIndexPool = null; ActualFileLength = 0; P2pMyOriginalPart = null; } if (mdg.GroupFileIndex == MyP2PIndex) { //ask! if (P2PFileIndexPool == null) { MessageBox.Show("Fatal!"); return; } //向请求方给予你的部分 MyDataGram Askdg = new MyDataGram(); Askdg.DstID = mdg.SrcID; Askdg.SrcID = mdg.DstID; Askdg.GroupFileID = mdg.GroupFileID; Askdg.GroupID = mdg.GroupID; Askdg.Text = mdg.Text; Askdg.GroupFileIndex = MyP2PIndex; Askdg.Type = MessageType.File; Askdg.FileContent = P2pMyOriginalPart; P2PCore_instance.SendData(MyDataGram.EncodeMessage(Askdg), friendIP, SendDataPort); } else { //receive! var arr = mdg.GroupFileID.Split(' '); if (P2PFileIDList == null) { P2PFileIDList = new List <string>(); MyP2PIndex = mdg.GroupFileIndex; } foreach (var id in arr) { if (id != "" && id != mdg.SrcID) { P2PFileIDList.Add(id); } } int Totalnum = P2PFileIDList.Count; //MessageBox.Show("Get P2P file part: " + mdg.GroupFileIndex + "in Total " + P2PFileIDList.Count().ToString() + "Parts"); if (P2PFileIndexPool == null) { P2PFileIndexPool = new int[Totalnum]; } int filecutter = mdg.FileContent.Length; if (P2PFileBuffer == null) { //larger than actual. P2PFileBuffer = new byte[filecutter * (Totalnum + 1)]; ActualFileLength = 0; P2pMyOriginalPart = new byte[filecutter]; Buffer.BlockCopy(mdg.FileContent, 0, P2pMyOriginalPart, 0, filecutter); } //put in P2PFileIndexPool[mdg.GroupFileIndex - 1] = 1; Buffer.BlockCopy(mdg.FileContent, 0, P2PFileBuffer, (mdg.GroupFileIndex - 1) * filecutter, filecutter); ActualFileLength += filecutter; int flag = 0; foreach (int i in P2PFileIndexPool) { if (i != 1) { flag = 1; } } byte[] FinalFile = null; if (flag == 0) { //finish FinalFile = new byte[ActualFileLength]; Buffer.BlockCopy(P2PFileBuffer, 0, FinalFile, 0, ActualFileLength); } if (FinalFile != null) { var question = "收到P2P的完整文件: " + mdg.GroupID + ",确定接受嘛?"; MessageBoxResult rst = MessageBox.Show(question, "Get File!", MessageBoxButton.YesNo); if (rst == MessageBoxResult.Yes) { //MessageBox.Show(msg.Content); var folder_dir = "./" + msg.SrcID + "/"; if (!Directory.Exists(folder_dir)) { Directory.CreateDirectory(folder_dir); } var FileFullName = folder_dir + mdg.Text; FileStream fs = File.OpenWrite(FileFullName); fs.Write(FinalFile, 0, ActualFileLength); fs.Close(); MessageBox.Show("接收文件成功,储存在: " + FileFullName); } else { return; } } else { //not enough file: Ask file from others for (int i = 0; i < P2PFileIndexPool.Length; i++) { if (P2PFileIndexPool[i] == 0) { //没有此部分文件 MyDataGram Askdg = new MyDataGram(); Askdg.DstID = P2PFileIDList[i]; Askdg.SrcID = MyID; Askdg.GroupFileID = mdg.GroupFileID; Askdg.GroupID = mdg.GroupID; Askdg.Text = mdg.Text; Askdg.GroupFileIndex = i + 1; Askdg.Type = MessageType.File; Askdg.FileContent = P2pMyOriginalPart; P2PCore_instance.SendData(MyDataGram.EncodeMessage(Askdg), friendIP, SendDataPort); } } } } } else { var question = "你收到来自: " + msg.SrcID + "的文件,确定接受嘛?"; MessageBoxResult rst = MessageBox.Show(question, "Get File!", MessageBoxButton.YesNo); if (rst == MessageBoxResult.Yes) { //MessageBox.Show(msg.Content); var folder_dir = "./" + msg.SrcID + "/"; if (!Directory.Exists(folder_dir)) { Directory.CreateDirectory(folder_dir); } var FileFullName = folder_dir + mdg.Text; FileStream fs = File.OpenWrite(FileFullName); fs.Write(mdg.FileContent, 0, mdg.FileContent.Length); fs.Close(); MessageBox.Show("接收文件成功,储存在: " + FileFullName); if (mdg.Type == MessageType.Image) { mdg.Text = FileFullName; } } else { return; } } } //询问 if (mdg.GroupID != null) { msg.Content = msg.SrcID + ": " + mdg.Text; } else { msg.Content = friendAlias + ": " + mdg.Text; } if (mdg.Type == MessageType.Image) { msg.Content = mdg.Text; string fullpath = Path.GetFullPath(msg.Content); msg.BitMapSource = new BitmapImage(new Uri(fullpath, UriKind.Absolute)); } msg.SendTime = DateTime.Now.ToString(); ChattingMessageList.Add(msg); ChattingWindowListBox.ScrollIntoView(msg); }
private async void SendFile_MouseLeftButtonUpAsync(object sender, MouseButtonEventArgs e) { //MessageBox.Show("Send File called!"); //open dialog OpenFileDialog filedlg = new OpenFileDialog { Title = "请选择要发送的文件", CheckFileExists = true, CheckPathExists = true, Multiselect = false }; if (filedlg.ShowDialog() == true) { Array.Clear(FileBuffer, 0, FileMaxSize); string filename = filedlg.FileName; FileInfo info = new FileInfo(filename); if (info.Length > FileMaxSize) { MessageBox.Show("文件过大,支持最大文件: 16MB"); return; } //MessageBox.Show(filename); if (friendID[0] == ' ') { //P2P文件传输 List <string> OnLineIDList = new List <string>(); List <string> OnLineIPList = new List <string>(); string GroupFileID = " "; foreach (var id in GroupIDList) { if (id != MyID) { var temp = "q" + id; var resp = CSCore_instance.Query(temp); if (resp != "n") { //danger! OnLineIDList.Add(id); OnLineIPList.Add(resp); GroupFileID += id + " "; } } } int TotalOnlineNum = OnLineIDList.Count(); if (TotalOnlineNum == 0) { MessageBox.Show("无人在线, 别发了吧..."); return; } //load file string ShortName = Path.GetFileName(filename); FileStream fs = File.OpenRead(filename); int FileLength = await fs.ReadAsync(FileBuffer, 0, FileBuffer.Length); var FullFile = new byte[FileLength]; Buffer.BlockCopy(FileBuffer, 0, FullFile, 0, FileLength); //cut file int flag = 0; int filecutter = (int)Math.Floor((double)(FileLength / TotalOnlineNum)); for (int i = 0; i < TotalOnlineNum; i++) { var mdg = new MyDataGram(); mdg.SrcID = MyID; mdg.DstID = OnLineIDList[i]; mdg.Text = ShortName; mdg.Type = MessageType.File; mdg.GroupFileIndex = i + 1; mdg.GroupFileID = GroupFileID; mdg.GroupID = friendID; if (i == TotalOnlineNum - 1) { mdg.FileContent = new byte[FileLength - i * filecutter]; Buffer.BlockCopy(FullFile, i * filecutter, mdg.FileContent, 0, FileLength - i * filecutter); } else { mdg.FileContent = new byte[filecutter]; Buffer.BlockCopy(FullFile, i * filecutter, mdg.FileContent, 0, filecutter); } try { P2PCore_instance.SendData(MyDataGram.EncodeMessage(mdg), OnLineIPList[i], SendDataPort); } catch (Exception ex) { MessageBox.Show("发送失败!接收方: " + OnLineIDList[i]); return; } ChattingMessage cmsg = new ChattingMessage(); cmsg.SrcID = MyID; cmsg.DstID = friendID; cmsg.CMType = mdg.Type; cmsg.Content = ShortName; cmsg.SendTime = DateTime.Now.ToString(); if (cmsg.CMType == MessageType.Image) { cmsg.BitMapSource = new BitmapImage(new Uri(filename, UriKind.Absolute)); } if (flag == 0) { cmsg.hori = HorizontalAlignment.Right; ChattingMessageList.Add(cmsg); ChattingWindowListBox.ScrollIntoView(cmsg); } flag = 1; } } else { var temp = "q" + friendID; var resp = CSCore_instance.Query(temp); if (resp == "n") { MessageBox.Show("当前好友不在线!"); this.Close(); return; } else { friendIP = resp; } string ShortName = Path.GetFileName(filename); var mdg = new MyDataGram(); FileStream fs = File.OpenRead(filename); int FileLength = await fs.ReadAsync(FileBuffer, 0, FileBuffer.Length); mdg.SrcID = MyID; mdg.DstID = friendID; mdg.Text = ShortName; mdg.Type = MessageType.File; if (IsImage(filename)) { mdg.Type = MessageType.Image; } mdg.FileContent = new byte[FileLength]; Buffer.BlockCopy(FileBuffer, 0, mdg.FileContent, 0, FileLength); try { P2PCore_instance.SendData(MyDataGram.EncodeMessage(mdg), friendIP, SendDataPort); } catch (Exception ex) { MessageBox.Show("发送失败!"); return; } ChattingMessage cmsg = new ChattingMessage(); cmsg.SrcID = MyID; cmsg.DstID = friendID; cmsg.CMType = mdg.Type; cmsg.Content = ShortName; cmsg.SendTime = DateTime.Now.ToString(); if (cmsg.CMType == MessageType.Image) { cmsg.BitMapSource = new BitmapImage(new Uri(filename, UriKind.Absolute)); } cmsg.hori = HorizontalAlignment.Right; ChattingMessageList.Add(cmsg); ChattingWindowListBox.ScrollIntoView(cmsg); } } MessageBox.Show("文件成功发送!"); return; }