/// <summary> /// 全新的decode,将去头去尾的bytes放进来decode即可 /// </summary> /// <param name="full_byte">去头去尾后的整个报文</param> /// <param name="info_base">返回值</param> /// <param name="file_fragment">若为文件类型报文,将携带文件片段信息</param> /// <returns></returns> public bool decodemes(byte[] full_byte, out SKMsgInfoBase info_base, out byte[] file_fragment) { file_fragment = null; info_base = null; bool ret = false; try { int json_len = BitConverter.ToInt32(full_byte, 0) - 12; int another_len = BitConverter.ToInt32(full_byte, 4); byte[] json_bytes = new byte[json_len]; Array.Copy(full_byte, 8, json_bytes, 0, json_len); JObject json_object = JObject.Parse(Encoding.UTF8.GetString(json_bytes)); int id = (int)json_object["id"]; string type_s = (string)json_object["type"]; string time_s = (string)json_object["time"]; string md5 = (string)json_object["md5"]; string stu_num = (string)json_object["stu_num"]; md5 = md5.ToLower(); SKMsgInfoBase.mestype type = get_type(type_s); switch (type) { case SKMsgInfoBase.mestype.EXIT: case SKMsgInfoBase.mestype.RESPONSE: case SKMsgInfoBase.mestype.FRIEND_INVITE: { info_base = new SKMsgInfoBase(); info_base.stu_num = stu_num; info_base.id = id; info_base.type = type; info_base.verified = true; info_base.timestamp = DateTime.ParseExact(time_s, "yyyy.MM.dd HH:mm:ss", null); break; } case SKMsgInfoBase.mestype.FILE: { info_base = new SKMsgInfoFile(); info_base.stu_num = stu_num; SKMsgInfoFile info_file = (SKMsgInfoFile)info_base; info_file.id = id; info_file.type = type; info_file.verified = true; info_file.timestamp = DateTime.ParseExact(time_s, "yyyy.MM.dd HH:mm:ss", null); info_file.max_fragment = (int)json_object["data"]["max_fragment"]; info_file.this_fragment = (int)json_object["data"]["this_fragment"]; if (another_len != 0) { file_fragment = new byte[another_len]; Array.Copy(full_byte, 8 + json_len, file_fragment, 0, another_len); } break; } case SKMsgInfoBase.mestype.FILE_INVITE: { info_base = new SKMsgInfoFileInvite(); info_base.stu_num = stu_num; SKMsgInfoFileInvite info_file_invite = (SKMsgInfoFileInvite)info_base; info_file_invite.id = id; info_file_invite.type = type; info_file_invite.verified = true; info_file_invite.timestamp = DateTime.ParseExact(time_s, "yyyy.MM.dd HH:mm:ss", null); info_file_invite.size = (int)json_object["data"]["size"]; info_file_invite.file_name = (string)json_object["data"]["file_name"]; break; } case SKMsgInfoBase.mestype.GROUP_TEXT: { info_base = new SKMsgInfoGroupText(); info_base.stu_num = stu_num; SKMsgInfoGroupText info_group_text = (SKMsgInfoGroupText)info_base; info_group_text.id = id; info_group_text.type = type; info_group_text.verified = true; info_group_text.timestamp = DateTime.ParseExact(time_s, "yyyy.MM.dd HH:mm:ss", null); int list_len = (int)json_object["data"]["list_len"]; info_group_text.text_pack.name = (string)json_object["data"]["name"]; info_group_text.text_pack.text = (string)json_object["data"]["text"]; for (int i = 0; i < list_len; i++) { info_group_text.stu_num_list.Add((string)json_object["data"]["stu_num_list"][i]); } break; } case SKMsgInfoBase.mestype.TEXT: { info_base = new SKMsgInfoText(); info_base.stu_num = stu_num; SKMsgInfoText info_text = (SKMsgInfoText)info_base; info_text.id = id; info_text.type = type; info_text.verified = true; info_text.timestamp = DateTime.ParseExact(time_s, "yyyy.MM.dd HH:mm:ss", null); info_text.text_pack.name = (string)json_object["data"]["name"]; info_text.text_pack.text = (string)json_object["data"]["text"]; break; } case SKMsgInfoBase.mestype.SYNC: { info_base = new SKMsgInfoSync(); info_base.stu_num = stu_num; info_base.id = id; info_base.type = type; info_base.verified = true; info_base.timestamp = DateTime.ParseExact(time_s, "yyyy.MM.dd HH:mm:ss", null); SKMsgInfoSync info_sync = (SKMsgInfoSync)info_base; info_sync.comment = (string)json_object["data"]["comment"]; info_sync.name = (string)json_object["data"]["name"]; info_sync.head_60_60 = from_base64((string)json_object["data"]["head"]); break; } default: { ret = false; break; } } ret = true; } catch (Exception) { ret = false; } return(ret); }
private void SendFileThread(object this_object) { try { SendFileDialog sfd = new SendFileDialog(); ip_with_file_path ip_and_file_path = (ip_with_file_path)this_object; Socket send_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); send_socket.SendBufferSize = SKServer.max_byte_once; IAsyncResult connect_result = send_socket.BeginConnect(ip_and_file_path.ip, int.Parse( ip_and_file_path.tar_stu_num.Substring(ip_and_file_path.tar_stu_num.Length - 4)), null, null); connect_result.AsyncWaitHandle.WaitOne(max_connect_senconds * 1000);//10s if (!connect_result.IsCompleted) { send_socket.Close(); return; } if (!File.Exists(ip_and_file_path.file_full_path)) { throw new Exception("文件不存在!"); } long size = (new FileInfo(ip_and_file_path.file_full_path)).Length; if (size > int.MaxValue) { throw new Exception("文件大小超过2G!"); } int size_i = (int)size; int max_fragment = (int)Math.Ceiling((double)size_i / SKServer.max_fragment_size); FileStream fs = new FileStream(ip_and_file_path.file_full_path, FileMode.Open); BinaryReader sr = new BinaryReader(fs); sfd.init(max_fragment, ip_and_file_path.stu_num); sfd.Show(); for (int i = 0; i < max_fragment; i++) { sfd.update(i); int this_time_send_len = ((i == max_fragment - 1) && (size_i % SKServer.max_fragment_size == 0)) ? (size_i % SKServer.max_fragment_size) : SKServer.max_fragment_size; byte[] to_send = new byte[this_time_send_len]; int len = sr.Read(to_send, 0, this_time_send_len); SKMsgInfoFile smif = new SKMsgInfoFile(); smif.id = i; smif.max_fragment = max_fragment; smif.this_fragment = i; smif.timestamp = DateTime.Now; smif.type = SKMsgInfoBase.mestype.FILE; smif.stu_num = ip_and_file_path.stu_num; byte[] send_byte; if (!skmessage.encodemes(smif, out send_byte, to_send)) { throw new Exception("转码失败,中断发送"); } List <byte[]> send_byte_buffer = new List <byte[]>(); send_byte_buffer.Add(SKServer.head_2_bytes); send_byte_buffer.Add(send_byte); send_byte_buffer.Add(SKServer.end_2_bytes); byte[] final_send = byte_connect(send_byte_buffer); send_socket.Send(final_send); //Thread.Sleep(10); byte[] small_response = new byte[2]; send_socket.Receive(small_response); if (small_response[0] == 0x0D && small_response[1] == 0x0A) { continue; } else { Thread.Sleep(1000); } } sr.Close(); fs.Close(); SKMsgInfoBase exit_info = new SKMsgInfoBase(); exit_info.id = 1; exit_info.stu_num = ip_and_file_path.stu_num; exit_info.timestamp = DateTime.Now; exit_info.type = SKMsgInfoBase.mestype.EXIT; byte[] send_byte2; if (!skmessage.encodemes(exit_info, out send_byte2)) { throw new Exception("转码失败,中断发送"); } List <byte[]> send_byte_buffer2 = new List <byte[]>(); send_byte_buffer2.Add(SKServer.head_2_bytes); send_byte_buffer2.Add(send_byte2); send_byte_buffer2.Add(SKServer.end_2_bytes); byte[] final_send2 = byte_connect(send_byte_buffer2); send_socket.Send(final_send2); Thread.Sleep(10); //send_socket.Close(); ip_and_file_path.m.WaitOne(); file_threads.Remove(ip_and_file_path); ip_and_file_path.m.ReleaseMutex(); } catch (Exception e) { System.Windows.Forms.MessageBox.Show("文件传输中断"); return; } return; }
/// <summary> /// 全新的encode,将SKMsgInfoBase放进来即可 /// </summary> /// <param name="info_base">要发送的消息</param> /// <param name="jsonb">返回的字节数组</param> /// <param name="file_fragment">可选,文件片段</param> /// <returns></returns> public bool encodemes(SKMsgInfoBase info_base, out byte[] jsonb, byte[] file_fragment = null) { int len1 = 0; jsonb = null; bool ret = false; try { string s = string.Empty; JObject j = new JObject(); s += "{"; s += "\"else\":{},"; s += "\"id\":" + info_base.id.ToString() + ","; s += "\"time\":\"" + info_base.timestamp.ToString("yyyy.MM.dd HH:mm:ss") + "\","; s += "\"stu_num\":\"" + info_base.stu_num + "\","; switch (info_base.type) { case SKMsgInfoBase.mestype.EXIT: { s += "\"type\":\"exit\","; s += "\"data\":{},"; List <byte[]> con_byte = new List <byte[]>(); con_byte.Add(BitConverter.GetBytes(info_base.id)); con_byte.Add(Encoding.UTF8.GetBytes("exit")); con_byte.Add(Encoding.UTF8.GetBytes(info_base.timestamp.ToString("yyyy.MM.dd HH:mm:ss"))); s += "\"md5\":\"" + getmd5(byte_connect(con_byte)) + "\""; s += "}"; ret = true; break; } case SKMsgInfoBase.mestype.FILE: { SKMsgInfoFile info_file = (SKMsgInfoFile)info_base; s += "\"type\":\"file\","; s += "\"data\":{"; s += "\"max_fragment\":" + info_file.max_fragment.ToString() + ","; s += "\"this_fragment\":" + info_file.this_fragment.ToString(); s += "},"; s += "\"md5\":\"" + getmd5(file_fragment) + "\""; s += "}"; ret = true; break; } case SKMsgInfoBase.mestype.FILE_INVITE: { SKMsgInfoFileInvite info_file_invite = (SKMsgInfoFileInvite)info_base; s += "\"type\":\"file_invite\","; s += "\"data\":{"; s += "\"size\":" + info_file_invite.size.ToString() + ","; s += "\"file_name\":\"" + info_file_invite.file_name.ToString() + "\""; s += "},"; List <byte[]> con_byte = new List <byte[]>(); con_byte.Add(BitConverter.GetBytes(info_base.id)); con_byte.Add(Encoding.UTF8.GetBytes("file_invite")); con_byte.Add(Encoding.UTF8.GetBytes(info_base.timestamp.ToString("yyyy.MM.dd HH:mm:ss"))); s += "\"md5\":\"" + getmd5(byte_connect(con_byte)) + "\""; s += "}"; ret = true; break; } case SKMsgInfoBase.mestype.GROUP_TEXT: { SKMsgInfoGroupText info_group_text = (SKMsgInfoGroupText)info_base; s += "\"type\":\"group_text\","; s += "\"data\":{"; s += "\"name\":\"" + add_special_char(info_group_text.text_pack.name) + "\","; s += "\"text\":\"" + add_special_char(info_group_text.text_pack.text) + "\","; s += "\"list_len\":" + info_group_text.stu_num_list.Count.ToString() + ","; s += "\"stu_num_list\":["; for (int i = 0; i < info_group_text.stu_num_list.Count - 1; i++) { s += "\"" + info_group_text.stu_num_list[i] + "\","; } s += "\"" + info_group_text.stu_num_list[info_group_text.stu_num_list.Count - 1] + "\""; s += "]"; s += "},"; List <byte[]> con_byte = new List <byte[]>(); con_byte.Add(BitConverter.GetBytes(info_group_text.id)); con_byte.Add(Encoding.UTF8.GetBytes("text")); con_byte.Add(Encoding.UTF8.GetBytes(info_group_text.timestamp.ToString("yyyy.MM.dd HH:mm:ss"))); con_byte.Add(Encoding.UTF8.GetBytes(info_group_text.text_pack.name)); con_byte.Add(Encoding.UTF8.GetBytes(info_group_text.text_pack.text)); s += "\"md5\":\"" + getmd5(byte_connect(con_byte)) + "\""; s += "}"; ret = true; break; } case SKMsgInfoBase.mestype.RESPONSE: { s += "\"type\":\"response\","; s += "\"data\":{},"; List <byte[]> con_byte = new List <byte[]>(); con_byte.Add(BitConverter.GetBytes(info_base.id)); con_byte.Add(Encoding.UTF8.GetBytes("response")); con_byte.Add(Encoding.UTF8.GetBytes(info_base.timestamp.ToString("yyyy.MM.dd HH:mm:ss"))); s += "\"md5\":\"" + getmd5(byte_connect(con_byte)) + "\""; s += "}"; ret = true; break; } case SKMsgInfoBase.mestype.FRIEND_INVITE: { s += "\"type\":\"friend_invite\","; s += "\"data\":{},"; List <byte[]> con_byte = new List <byte[]>(); con_byte.Add(BitConverter.GetBytes(info_base.id)); con_byte.Add(Encoding.UTF8.GetBytes("friend_invite")); con_byte.Add(Encoding.UTF8.GetBytes(info_base.timestamp.ToString("yyyy.MM.dd HH:mm:ss"))); s += "\"md5\":\"" + getmd5(byte_connect(con_byte)) + "\""; s += "}"; ret = true; break; } case SKMsgInfoBase.mestype.TEXT: { SKMsgInfoText info_text = (SKMsgInfoText)info_base; s += "\"type\":\"text\","; s += "\"data\":{"; s += "\"name\":\"" + add_special_char(info_text.text_pack.name) + "\","; s += "\"text\":\"" + add_special_char(info_text.text_pack.text) + "\""; s += "},"; List <byte[]> con_byte = new List <byte[]>(); con_byte.Add(BitConverter.GetBytes(info_text.id)); con_byte.Add(Encoding.UTF8.GetBytes("text")); con_byte.Add(Encoding.UTF8.GetBytes(info_text.timestamp.ToString("yyyy.MM.dd HH:mm:ss"))); con_byte.Add(Encoding.UTF8.GetBytes(info_text.text_pack.name)); con_byte.Add(Encoding.UTF8.GetBytes(info_text.text_pack.text)); s += "\"md5\":\"" + getmd5(byte_connect(con_byte)) + "\""; s += "}"; ret = true; break; } case SKMsgInfoBase.mestype.SYNC: { SKMsgInfoSync info_sync = (SKMsgInfoSync)info_base; s += "\"type\":\"sync\","; s += "\"data\":{"; s += "\"name\":\"" + info_sync.name + "\","; s += "\"comment\":\"" + info_sync.comment + "\","; s += "\"head\":\"" + to_base64(info_sync.head_60_60) + "\""; s += "},"; List <byte[]> con_byte = new List <byte[]>(); con_byte.Add(BitConverter.GetBytes(info_base.id)); con_byte.Add(Encoding.UTF8.GetBytes("sync")); con_byte.Add(Encoding.UTF8.GetBytes(info_base.timestamp.ToString("yyyy.MM.dd HH:mm:ss"))); s += "\"md5\":\"" + getmd5(byte_connect(con_byte)) + "\""; s += "}"; ret = true; break; } default: { ret = false; jsonb = null; break; } } if (ret) { List <byte[]> final = new List <byte[]>(); byte[] first_part = Encoding.UTF8.GetBytes(s); len1 = first_part.Length + 12; if (info_base.type == SKMsgInfoBase.mestype.FILE) { byte[] len1b = BitConverter.GetBytes(len1); byte[] len2b = BitConverter.GetBytes(file_fragment.Length); final.Add(len1b); final.Add(len2b); final.Add(first_part); final.Add(file_fragment); jsonb = byte_connect(final); } else { byte[] len1b = BitConverter.GetBytes(len1); byte[] len2b = BitConverter.GetBytes(0); final.Add(len1b); final.Add(len2b); final.Add(first_part); jsonb = byte_connect(final); } } } catch (Exception) { ret = false; } return(ret); }