/// <summary> /// 释放指定TCP客户端信息的资源(不包括ThreadReceiveCommand) /// </summary> /// <param name="tcpClientInfo">TCP客户端信息</param> protected void ReleaseTcpClientInfoWithoutCommand(TcpClientInfo tcpClientInfo) { if (tcpClientInfo.ThreadSendFile != null && tcpClientInfo.ThreadSendFile.ThreadState != ThreadState.Aborted) { tcpClientInfo.ThreadSendFile.Abort(); tcpClientInfo.ThreadSendFile = null; } if (tcpClientInfo.ThreadReceiveFile != null && tcpClientInfo.ThreadReceiveFile.ThreadState != ThreadState.Aborted) { tcpClientInfo.ThreadReceiveFile.Abort(); tcpClientInfo.ThreadReceiveFile = null; } if (tcpClientInfo.Reader != null) { tcpClientInfo.Reader.Close(); tcpClientInfo.Reader = null; } if (tcpClientInfo.Writer != null) { tcpClientInfo.Writer.Close(); tcpClientInfo.Writer = null; } if (tcpClientInfo.TcpClient != null && tcpClientInfo.TcpClient.Connected) { tcpClientInfo.TcpClient.Client.Close(); tcpClientInfo.TcpClient.Close(); tcpClientInfo.TcpClient = null; } if (tcpClientInfo.SendFileStream != null) { tcpClientInfo.SendFileStream.Close(); tcpClientInfo.SendFileStream = null; } }
/// <summary> /// 接收文件 /// </summary> /// <param name="fileDownLoadSaveDir">文件下载目录</param> /// <param name="tcpClientInfo">客户端信息</param> protected void ReceiveFile(string fileDownLoadSaveDir, TcpClientInfo tcpClientInfo) { if (tcpClientInfo == null) { throw new ArgumentNullException("tcpClientInfo"); } int size = 0; long len = 0; string fileSavePath = Path.Combine(fileDownLoadSaveDir, tcpClientInfo.ReceiveFileInfo.FileName.Trim()); if (!Directory.Exists(fileDownLoadSaveDir)) { Directory.CreateDirectory(fileDownLoadSaveDir); } FileStream fs = new FileStream(fileSavePath, FileMode.OpenOrCreate, FileAccess.Write) { Position = 0 }; byte[] buffer = new byte[tcpClientInfo.FileTransferBufferSize]; while (len < tcpClientInfo.ReceiveFileInfo.FileLength) { size = tcpClientInfo.Reader.Read(buffer, 0, buffer.Length); fs.Write(buffer, 0, size); len += size; } fs.Flush(); fs.Close(); }
/// <summary> /// 接收文件 /// </summary> /// <param name="clientName">客户端名称</param> private void ReceiveFile(object clientName) { TcpClientInfo clientInfo = GetTcpClientInfo((string)clientName); if (clientInfo == null) { return; //结束线程 } bool bRet = false; string strError = string.Empty; try { base.ReceiveFile(FileDownLoadSaveDir, clientInfo); bRet = true; } catch (Exception e) { bRet = false; strError = e.Message; } if (bRet) { OnReceiveFileSuccess((string)clientName, Path.GetFullPath(Path.Combine(FileDownLoadSaveDir, clientInfo.ReceiveFileInfo.FileName.Trim()))); } else { OnReceiveFileFail((string)clientName, strError); } }
/// <summary> /// 发送文件 /// </summary> /// <param name="clientName">客户端名称</param> private void SendFile(object clientName) { TcpClientInfo clientInfo = GetTcpClientInfo((string)clientName); if (clientInfo == null) { return; //结束线程 } bool bRet = false; string strError = string.Empty; try { base.SendFile(clientInfo); bRet = true; } catch (Exception e) { bRet = false; strError = e.Message; clientInfo.SendFileStream.Close(); } if (bRet) { OnSendFileSuccess((string)clientName, clientInfo.SendFileStream.Name); } else { OnSendFileFail((string)clientName, strError); } }
/// <summary> /// 发送消息 /// </summary> /// <param name="message">消息</param> /// <param name="tcpClientInfo">客户端信息</param> public void SendMessage(string message, TcpClientInfo tcpClientInfo) { if (tcpClientInfo != null && tcpClientInfo.Writer != null) { tcpClientInfo.Writer.Write(message); tcpClientInfo.Writer.Flush(); } }
/// <summary> /// 释放指定TCP客户端信息的资源 /// </summary> /// <param name="tcpClientInfo">TCP客户端信息</param> protected void ReleaseTcpClientInfo(TcpClientInfo tcpClientInfo) { ReleaseTcpClientInfoWithoutCommand(tcpClientInfo); if (tcpClientInfo.ThreadReceiveCommand != null && tcpClientInfo.ThreadReceiveCommand.ThreadState != ThreadState.Aborted) { tcpClientInfo.ThreadReceiveCommand.Abort(); tcpClientInfo.ThreadReceiveCommand = null; } }
/// <summary> /// 发送文件(暂时不支持多文件) /// </summary> /// <param name="filePath">文件路径,多文件使用分号隔开</param> /// <param name="tcpClientInfo">TCP客户端信息</param> public void SendFile(string filePath, TcpClientInfo tcpClientInfo) { if (string.IsNullOrWhiteSpace(filePath) || tcpClientInfo == null) { return; } tcpClientInfo.SendFileStream = new FileStream(filePath, FileMode.Open); string fileName = Path.GetFileName(filePath); string fileLength = tcpClientInfo.SendFileStream.Length.ToString();//单位为字节 SendMessage(MsgFileTransferReady + MsgFileName.Replace("##", fileName) + MsgFileLength.Replace("##", fileLength), tcpClientInfo); }
/// <summary> /// 释放出错TCP客户端 /// </summary> /// <param name="tcpClientInfo">TCP客户端</param> private void ReleaseErrorClient(TcpClientInfo tcpClientInfo) { if (tcpClientInfo != null) { string strClientName = tcpClientInfo.TcpClient.Client.RemoteEndPoint.ToString(); //释放资源 base.ReleaseTcpClientInfoWithoutCommand(tcpClientInfo); if (TcpClientInfos.ContainsKey(strClientName)) { TcpClientInfos.Remove(strClientName); } } }
/// <summary> /// 断开指定客户端的连接(释放资源) /// </summary> /// <param name="tcpClientInfo">TCP客户端信息</param> public void DisconnectClient(TcpClientInfo tcpClientInfo) { if (tcpClientInfo != null) { string strClientName = tcpClientInfo.TcpClient.Client.RemoteEndPoint.ToString(); //释放资源 ReleaseTcpClientInfo(tcpClientInfo); if (TcpClientInfos.ContainsKey(strClientName)) { TcpClientInfos.Remove(strClientName); } } }
/// <summary> /// 发送文件 /// </summary> /// <param name="tcpClientInfo">客户端信息</param> protected void SendFile(TcpClientInfo tcpClientInfo) { if (tcpClientInfo == null) { throw new ArgumentNullException("tcpClientInfo"); } int size = 0; //初始化读取的流量为0 long len = 0; //初始化已经读取的流量 byte[] buffer = new byte[tcpClientInfo.FileTransferBufferSize]; while (len < tcpClientInfo.SendFileStream.Length) { size = tcpClientInfo.SendFileStream.Read(buffer, 0, buffer.Length); tcpClientInfo.Writer.Write(buffer, 0, size); len += size; } tcpClientInfo.SendFileStream.Flush(); tcpClientInfo.SendFileStream.Close(); tcpClientInfo.Writer.Flush(); }
/// <summary> /// 接收客户端连接 /// </summary> private void ReceiveClient() { string strClientName = string.Empty;//客户端名称 while (true) { try { //限制客户端连接数量 if (MaxClientCount >= 0 && TcpClientInfos.Count >= MaxClientCount) { OnMaxClientCount(MaxClientCount); return; } System.Net.Sockets.TcpClient tcpClient = _tcpListener.AcceptTcpClient(); //阻塞等待客户端连接 strClientName = tcpClient.Client.RemoteEndPoint.ToString(); NetworkStream networkStream = tcpClient.GetStream(); TcpClientInfo clientInfo = new TcpClientInfo(); clientInfo.TcpClient = tcpClient; clientInfo.Writer = new BinaryWriter(networkStream); clientInfo.Reader = new BinaryReader(networkStream); clientInfo.ThreadReceiveCommand = new Thread(ReceiveCommand) { IsBackground = true }; clientInfo.ThreadReceiveCommand.Start(strClientName); //也可以直接传递TcpClient对象 TcpClientInfos[strClientName] = clientInfo; OnClientConnectSuccess(strClientName); } catch (Exception err) { if (!_serverStoped) { OnClientConnectFail(strClientName, err.Message); } } } }
/// <summary> /// 接收指定客户端数据 /// </summary> /// <param name="clientName">客户端名称</param> private void ReceiveCommand(object clientName) { TcpClientInfo clientInfo = GetTcpClientInfo((string)clientName); if (clientInfo == null) { return; //结束线程 } while (true) { try { string receiveString = clientInfo.Reader.ReadString();//阻塞等待客户端发送数据 if (receiveString.StartsWith(MsgClientMessage)) { //客户端发来文本信息 OnReceiveClientMessage((string)clientName, receiveString.Substring(MsgClientMessage.Length)); } else if (receiveString.StartsWith(MsgFileTransferReady)) { //准备文件传输(接收文件) base.ParseFileTransferInfo(receiveString, out clientInfo.ReceiveFileInfo); SendMessage(MsgFileTransferNow, clientInfo); clientInfo.ThreadReceiveFile = new Thread(ReceiveFile) { IsBackground = true }; clientInfo.ThreadReceiveFile.Start(clientName); clientInfo.ThreadReceiveFile.Join();//阻塞等待线程结束 } else if (receiveString.StartsWith(MsgFileTransferNow)) { //开始文件传输(发送文件) clientInfo.ThreadSendFile = new Thread(SendFile) { IsBackground = true }; clientInfo.ThreadSendFile.Start(clientName); clientInfo.ThreadSendFile.Join();//阻塞等待线程结束 } else if (receiveString.StartsWith(MsgClientDisconnect)) { //客户端主动断开连接 ReleaseErrorClient(clientInfo);//释放资源(当前客户端) OnClientDisconnect((string)clientName); break; } else { //接收到未知消息 OnReceiveUnknownMessage((string)clientName, receiveString); } } catch (Exception error) { ReleaseErrorClient(clientInfo);//释放资源(当前客户端) SocketException socketException = (SocketException)(error.InnerException); if (socketException != null) { SocketError socketError = socketException.SocketErrorCode; if ((int)socketError == 10054) { //客户端强制断开连接(如:强制关闭客户端) OnClientForceDisconnect((string)clientName); break; } } OnClientConnectError((string)clientName, error.Message); break; } } }