/// <summary> /// 接收方发送确认序号 /// </summary> /// <param name="ack">下一个等待接收的序号</param> private void sendAck(uint ack) { ProtocalHandler protocalHandler = new ProtocalHandler(owner.targetName); try { // 封装协议文本 string protocalText = protocalHandler.Pack("file_ack"); protocalText = protocalHandler.Append(protocalText, "file", safeFileNameBase64); protocalText = protocalHandler.Append(protocalText, "ack", ack.ToString()); // 发送 byte[] sendbuf = Encoding.ASCII.GetBytes(protocalText); SocketAsyncEventArgs saEA = new SocketAsyncEventArgs(); saEA.Completed += new EventHandler <SocketAsyncEventArgs>( SendCompletedDoNothing); saEA.SetBuffer(sendbuf, 0, sendbuf.Length); socket.SendAsync(saEA); } catch (Exception ex) { Trace.WriteLine("异常位置:sendAck"); Trace.WriteLine(ex.Message); } }
/// <summary> /// 发送方: /// 发送文件的某个片段 /// </summary> /// <param name="seq">当前序号</param> private void sendingFilePack(uint seq) { ProtocalHandler protocalHandler = new ProtocalHandler(owner.targetName); // 封装协议文本 string protocalText = protocalHandler.Pack("file_data"); protocalText = protocalHandler.Append(protocalText, "file", safeFileNameBase64); protocalText = protocalHandler.Append(protocalText, "seq", seq.ToString()); uint len = FilePacker.BytesOfPack; if (seq == maxSeq - 1) { len = filePacker.GetSizeOfLastPack(); } protocalText = protocalHandler.Append(protocalText, "len", len.ToString()); // 文件内容 byte[] buf = filePacker.GetPack(seq); string dataBase64 = Convert.ToBase64String(buf, 0, (int)len); protocalText = protocalHandler.Append(protocalText, "data", dataBase64); int checksum = 0; for (int i = 0; i < len; i++) { checksum += buf[i]; } checksum = -checksum; protocalText = protocalHandler.Append(protocalText, "checksum", checksum.ToString()); try { // 发送 byte[] sendbuf = Encoding.ASCII.GetBytes(protocalText); SocketAsyncEventArgs saEA = new SocketAsyncEventArgs(); saEA.Completed += new EventHandler <SocketAsyncEventArgs>( SendCompletedDoNothing); saEA.SetBuffer(sendbuf, 0, sendbuf.Length); socket.SendAsync(saEA); } catch (Exception ex) { Trace.WriteLine("异常位置:SendingFilePack"); Trace.WriteLine(ex.Message); } }
/// <summary> /// 发起方: /// 成功建立Socket连接,准备发送1次确认 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void createSocketCompletedEventHandler( object sender, EventArgs ea) { // 取得新建的Socket(如果连接成功) // 此Socket应等于this.socket SocketAsyncEventArgs socketAsyncEA = (SocketAsyncEventArgs)ea; Socket createdSocket = socketAsyncEA.ConnectSocket; if (createdSocket != null && createdSocket == socket) // 连接成功 { // 1次确认,发送name=自己(发起方)用户名 ProtocalHandler protocalHandler = new ProtocalHandler(main.MyName); string protocalText = protocalHandler.Pack("init_gp_request"); // 发送群中所有好友 foreach (string friend in owner.friends) { string friendBase64 = protocalHandler.StringToBase64string(friend); protocalText = protocalHandler.Append( protocalText, "target", friendBase64); } byte[] sendbuf = Encoding.ASCII.GetBytes(protocalText); SocketAsyncEventArgs saEA = new SocketAsyncEventArgs(); saEA.Completed += new EventHandler <SocketAsyncEventArgs>( createdSocketSendNamesCompletedEventHandler); saEA.SetBuffer(sendbuf, 0, sendbuf.Length); socket.SendAsync(saEA); } }
/// <summary> /// 接受方: /// 同意接收文件 /// </summary> public void ClearToSendFile() { ProtocalHandler protocalHandler = new ProtocalHandler(owner.targetName); // 封装协议文本 string protocalText = protocalHandler.Pack("file_cleartosend"); protocalText = protocalHandler.Append(protocalText, "file", safeFileNameBase64); try { fileWriter = new FileWriter(owner.fileName); // 发送 byte[] sendbuf = Encoding.ASCII.GetBytes(protocalText); SocketAsyncEventArgs saEA = new SocketAsyncEventArgs(); saEA.Completed += new EventHandler <SocketAsyncEventArgs>( SendCompletedDoNothing); saEA.SetBuffer(sendbuf, 0, sendbuf.Length); socket.SendAsync(saEA); } catch (Exception ex) { Trace.WriteLine("异常位置:ClearToSendFile"); Trace.WriteLine(ex.Message); } sendTimeOutTimer.Start(); sendErrCount = 0; }
/// <summary> /// 接受方: /// 收到的1次确认为私聊,记录对方的身份信息 /// 此时确定owner /// 发送2次确认 /// </summary> /// <param name="protocalHandler">接收到的协议的封装</param> public void newSocketChatNameReceived(ProtocalHandler protocalHandler) { try { // 对方用户名 string targetNameBase64 = protocalHandler.GetElementTextByTag("name"); string targetName = protocalHandler.Base64stringToString(targetNameBase64); // 打开私聊窗口 main.SetChatFormClient(this, targetName); // 2次确认,发送you = 对方(发起方)用户名 string protocalText = protocalHandler.Pack("init_chat_ok"); protocalText = protocalHandler.Append( protocalText, "you", targetNameBase64); byte[] sendbuf = Encoding.ASCII.GetBytes(protocalText); SocketAsyncEventArgs saEA = new SocketAsyncEventArgs(); saEA.Completed += new EventHandler <SocketAsyncEventArgs>( newSocketUsernameSendEventHandler); saEA.SetBuffer(sendbuf, 0, sendbuf.Length); socket.SendAsync(saEA); } catch (Exception ex) { Trace.WriteLine("异常位置:" + "newSocketChatNameReceived"); Trace.WriteLine(ex.Message); CloseSocket(); } }
/// <summary> /// 发起方: /// 申请发送文件 /// </summary> /// <param name="fileName">文件名(含路径)</param> public void RequestToSendFile(string fileName) { // 打开文件 filePacker = new FilePacker(owner.fileName); maxSeq = filePacker.GetPackNumbers(); owner.BeginInvoke(owner.setProgressDelegate, (int)maxSeq); // 取得文件名,并将文件名编码以便使用 safeFileNameBase64 = owner.GetSafeFileName(fileName); ProtocalHandler protocalHandler = new ProtocalHandler(owner.targetName); safeFileNameBase64 = protocalHandler.StringToBase64string(safeFileNameBase64); // 封装协议文本 string protocalText = protocalHandler.Pack("file_requesttosend"); protocalText = protocalHandler.Append(protocalText, "file", safeFileNameBase64); protocalText = protocalHandler.Append(protocalText, "maxseq", maxSeq.ToString()); try { // 发送 byte[] sendbuf = Encoding.ASCII.GetBytes(protocalText); SocketAsyncEventArgs saEA = new SocketAsyncEventArgs(); saEA.Completed += new EventHandler <SocketAsyncEventArgs>( SendCompletedDoNothing); saEA.SetBuffer(sendbuf, 0, sendbuf.Length); socket.SendAsync(saEA); } catch (Exception ex) { Trace.WriteLine("异常位置:RequestToSendFile"); Trace.WriteLine(ex.Message); } }