/// <summary> /// 向客户端异步发送文件 /// </summary> /// <param name="ip"></param> /// <param name="port"></param> /// <param name="filePath"></param> public async Task SendToClientFileAsync(string ip, int port, string filePath, Message msg) { // 新建 Udp 用于发送文件 var sendClient = new UdpClient(); try { FileInfo fileInfo = new FileInfo(filePath); msg.Type = MessageEnum.FILE; // 设置发送文件标识 msg.FileLength = fileInfo.Length; msg.FileName = Regex.Match(filePath, @"\\([^\\]+\.[^\\]+)").Groups[1].Value; // 获取文件名 byte[] datagram = Encoding.Unicode.GetBytes(JsonConvert.SerializeObject(msg)); IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ip), port); /* * 向‘原’远程客户端发送请求传送文件的请求, * 接收‘新’远程客户端的响应,获取传送文件的端口 * * 注:原远程客户端用于发送消息,新远程客户端用于发送文件 */ await sendClient.SendAsync(datagram, datagram.Length, endPoint); //IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); UdpReceiveResult result = await sendClient.ReceiveAsync().ConfigureAwait(false); // 阻塞直到接收到远程客户端的响应 /* * 开始发送文件 */ byte[] buffer = new byte[MAXSIZE]; using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 1, true)) { int percent = 0; int count = 0; while ((count = await fs.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) > 0) { //await Task.Delay(10); await sendClient.SendAsync(buffer, count, result.RemoteEndPoint); if (Client.SendFileProgressNotify != null) { Client.SendFileProgressNotify(String.Format("{0:F2}%", (percent += count) / msg.FileLength * 100)); } } sendClient.Close(); } } catch (Exception e) { Log.Write(e.Message); } }
public ProcessMessage(Message msg, UdpClient udpClient) { this.msg = msg; this.udpClient = udpClient; datagram = Encoding.Unicode.GetBytes(JsonConvert.SerializeObject(msg)); text = String.Format("{0}-{1}:{2}-{3}", msg.FromUserName, msg.IpAddress, msg.Port, msg.Type); }
public static Action<string> SendFileProgressNotify; // 发送文件进度提示 /// <summary> /// 向服务器异步发送信息 /// </summary> public static async Task SendToServerAsync(string ip, int port, Message msg) { byte[] datagram = Encoding.Unicode.GetBytes(JsonConvert.SerializeObject(msg)); IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ip), port); await udpClient.SendAsync(datagram, datagram.Length, endPoint).ConfigureAwait(false); if (StartClientNotify != null) { StartClientNotify(); // Notify the client } // 发送下线消息,则不再监听消息 if (msg.Type != MessageEnum.SIGN_OUT) { await RecieveClient(); } }
/// <summary> /// use different logic to deal with different message /// </summary> /// <param name="type">message type</param> private static void ProcessMessage(Message msg, IPEndPoint remoteEndPoint) { ProcessMessage processMessage = new ProcessMessage(msg, udpClient); switch (msg.Type) { case MessageEnum.SIGN_IN: processMessage.SignIn_Server(remoteEndPoint); break; case MessageEnum.SIGN_OUT: processMessage.SignOut_Server(remoteEndPoint); break; case MessageEnum.CHAT: //processMessage.Chat(); break; default: Log.Write(String.Format("MessageEnum doesn't have {0}", msg.Type)); break; } }
/// <summary> /// 向客户端异步发送信息 /// </summary> /// <param name="ip">IP</param> /// <param name="port">端口</param> /// <param name="msg">Message</param> public static async Task SendToClientAsync(string ip, int port, Message msg) { byte[] datagram = Encoding.Unicode.GetBytes(JsonConvert.SerializeObject(msg)); IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ip), port); await udpClient.SendAsync(datagram, datagram.Length, endPoint).ConfigureAwait(false); }
/// <summary> /// use different logic to deal with different message /// </summary> /// <param name="type">message type</param> private static async Task ProcessMessage(Message msg, IPEndPoint remote) { ProcessMessage processMessage = new ProcessMessage(msg, udpClient); switch (msg.Type) { case MessageEnum.SIGN_IN: if (SignInNotify != null) { SignInNotify(msg); } break; case MessageEnum.SIGN_OUT: if (SignOutNotify != null) { SignOutNotify(msg); } break; case MessageEnum.CHAT: if (ReceiveMessageNotify != null) { ReceiveMessageNotify(msg); // 通知客户端收到聊天信息 } break; case MessageEnum.FILE: await ReceiveClientFile(msg, remote); break; default: Log.Write(String.Format("MessageEnum doesn't have {0}", msg.Type)); break; } }
/// <summary> /// 从远程客户端接收文件 /// </summary> /// <param name="msg">Message</param> /// <param name="remtoe">IPEndPoint</param> private static async Task ReceiveClientFile(Message msg, IPEndPoint remtoe) { if (msg.Udp) { ProcessFileByUdp process = new ProcessFileByUdp(); await process.ReceiveClientFile(msg, remtoe); } else { ProcessFileByTcp process = new ProcessFileByTcp(); await process.ReceiveClientFile(msg, remtoe); } }
/// <summary> /// 发送文件到远程客户端 /// </summary> /// <param name="ip">IP</param> /// <param name="port">Port</param> /// <param name="filePath">文件路径</param> /// <param name="msg">信息内容</param> public static async Task SendFileToClient(string ip, int port, string filePath, Message msg, bool udp = true) { if (udp) { msg.Udp = true; // Udp 传输文件 ProcessFileByUdp process = new ProcessFileByUdp(); await process.SendToClientFileAsync(ip, port, filePath, msg).ConfigureAwait(false); } else { msg.Udp = false; // Tcp 传输文件 ProcessFileByTcp process = new ProcessFileByTcp(); await process.SendToClientFileAsync(ip, port, filePath, msg).ConfigureAwait(false); } }
/// <summary> /// 接收客户端发送的文件 /// </summary> public async Task ReceiveClientFile(Message msg, IPEndPoint remtoe) { // 新建 Udp 协议用于接收文件 var receiveFile = new UdpClient(); try { /* * 响应远程客户端发送文件的请求 * 通知远程客户端将文件发送至此端口 */ Message send = new Message { Type = MessageEnum.FILE }; byte[] buffer = Encoding.Unicode.GetBytes(JsonConvert.SerializeObject(send)); await receiveFile.SendAsync(buffer, buffer.Length, remtoe); // 响应远程客户端 // 接收并保存到文件 using (FileStream fs = new FileStream(msg.FileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, 1, true)) { int percent = 0; byte[] datagram = new byte[MAXSIZE]; IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0); while ((datagram = (await receiveFile.ReceiveAsync().ConfigureAwait(false)).Buffer).Length > 0) { await fs.WriteAsync(datagram, 0, datagram.Length); // 0 表示从 datagram 起始处写入到 fs 流中 if (Client.ReceiveFileProgressNotify != null) { Client.ReceiveFileProgressNotify(String.Format("{0:F2}%", (percent += datagram.Length) / msg.FileLength * 100)); } } receiveFile.Close(); } } catch (Exception e) { Log.Write(e.Message); } }
/// <summary> /// 向客户端异步发送文件 /// </summary> /// <param name="ip"></param> /// <param name="port"></param> /// <param name="filePath"></param> public async Task SendToClientFileAsync(string ip, int port, string filePath, Message msg) { // 新建 Udp 用于通知服务端,客户端要发送文件了 var sendClient = new UdpClient(); var localClient = new TcpClient(); try { FileInfo fileInfo = new FileInfo(filePath); msg.Type = MessageEnum.FILE; // 设置发送文件标识 msg.FileLength = fileInfo.Length; msg.FileName = Regex.Match(filePath, @"\\([^\\]+\.[^\\]+)").Groups[1].Value; // 获取文件名 byte[] datagram = Encoding.Unicode.GetBytes(JsonConvert.SerializeObject(msg)); IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ip), port); /* * 向‘原’远程客户端发送请求传送文件的请求, * 接收‘新’远程客户端的响应,获取传送文件的 Tcp 服务器 IP 和 Port * * 注:Udp 客户端用于发送通知消息,Tcp 客户端用于发送文件 */ await sendClient.SendAsync(datagram, datagram.Length, endPoint).ConfigureAwait(false); IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); byte[] bytes = (await sendClient.ReceiveAsync().ConfigureAwait(false)).Buffer; // 阻塞直到接收到远程客户端的响应 // 获取服务器的 IP 和 Port string serverIPAndPort = Encoding.Unicode.GetString(bytes); Message receiveIPAndPort = JsonConvert.DeserializeObject<Message>(serverIPAndPort); // 连接到服务器 localClient.Connect(IPAddress.Parse(receiveIPAndPort.IpAddress), receiveIPAndPort.Port); /* * 开始发送文件 */ byte[] buffer = new byte[MAXSIZE]; using (var localStream = localClient.GetStream()) using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 1, true)) { int percent = 0; int count = 0; do { count = await fs.ReadAsync(buffer, 0, buffer.Length); // 0 表示读入到 buffer 中的起始位置 if (Client.SendFileProgressNotify != null) { Client.SendFileProgressNotify(String.Format("{0:F2}%", (percent += count) / msg.FileLength * 100)); } //await Task.Delay(10); await localStream.WriteAsync(buffer, 0, count); } while (count > 0); } } catch (Exception e) { Log.Write(e.Message); } finally // 关闭相关资源 { if (sendClient != null) { sendClient.Close(); } if (localClient != null && localClient.Connected) { localClient.Close(); } } }
/// <summary> /// 接收客户端发送的文件 /// </summary> public async Task ReceiveClientFile(Message msg, IPEndPoint remtoe) { // 新建 Udp 协议用于接收文件 var receiveFile = new UdpClient(); const int PORT = 8555; var hostName = Dns.GetHostName(); var localadd = Dns.GetHostEntry(hostName).AddressList.FirstOrDefault(i => i.AddressFamily == AddressFamily.InterNetwork); TcpListener listener = null; TcpClient localClient = null; try { listener = new TcpListener(localadd, PORT); listener.Start(); // 服务器开启监听 /* * 响应远程客户端发送文件的请求 * 通知远程客户端将文件发送至 TcpListener 端口 */ Message send = new Message { Type = MessageEnum.FILE, IpAddress = localadd.ToString(), Port = PORT }; byte[] buffer = Encoding.Unicode.GetBytes(JsonConvert.SerializeObject(send)); await receiveFile.SendAsync(buffer, buffer.Length, remtoe).ConfigureAwait(false); // 响应远程客户端 localClient = await listener.AcceptTcpClientAsync(); // 等待远程客户端连接 // 接收并保存到文件 using (var remoteStream = localClient.GetStream()) using (FileStream fs = new FileStream(msg.FileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, 1, true)) { int percent = 0; int count = 0; byte[] datagram = new byte[MAXSIZE]; do { count = await remoteStream.ReadAsync(datagram, 0, datagram.Length); await fs.WriteAsync(datagram, 0, count).ConfigureAwait(false); // 0 表示从 datagram 起始处写入到 fs 流中 if (Client.ReceiveFileProgressNotify != null) { Client.ReceiveFileProgressNotify(String.Format("{0:F2}%", (percent += count) / msg.FileLength * 100)); } } while (count > 0); } } catch (Exception e) { Log.Write(e.Message); } finally // 关闭相关资源 { if (receiveFile != null) { receiveFile.Close(); } if (localClient != null && localClient.Connected) { localClient.Close(); } if (listener != null) { listener.Stop(); } } }