using System; using System.Net; using System.Net.Sockets; using System.IO; using System.Text; namespace TRI_TCP_Client { /// /// Net : 提供静态方法,对常用的网络操作进行封装 /// public sealed class Net { private Net() { } /// /// 向远程主机发送数据 /// /// 要发送数据且已经连接到远程主机的 Socket /// 待发送的数据 /// 发送数据的超时时间,以秒为单位,可以精确到微秒 /// 0:发送数据成功;-1:超时;-2:发送数据出现错误;-3:发送数据时出现异常 /// /// 当 outTime 指定为-1时,将一直等待直到有数据需要发送 /// public static int SendData(Socket socket, byte[] buffer, int outTime) { if (socket == null || socket.Connected == false) { throw new ArgumentException("参数socket 为null,或者未连接到远程计算机"); } if (buffer == null || buffer.Length == 0) { throw new ArgumentException("参数buffer 为null ,或者长度为 0"); } int flag = 0; try { int left = buffer.Length; int sndLen = 0; while (true) { if ((socket.Poll(outTime * 100, SelectMode.SelectWrite) == true)) { // 收集了足够多的传出数据后开始发送 sndLen = socket.Send(buffer, sndLen, left, SocketFlags.None); left -= sndLen; if (left == 0) { // 数据已经全部发送 flag = 0; break; } else { if (sndLen > 0) { // 数据部分已经被发送 continue; } else { // 发送数据发生错误 flag = -2; break; } } } else { // 超时退出 flag = -1; break; } } } catch (SocketException) { flag = -3; } return flag; } /// /// 向远程主机发送文件 /// /// 要发送数据且已经连接到远程主机的 socket /// 待发送的文件 /// 文件发送时的缓冲区大小 /// 发送缓冲区中的数据的超时时间 /// 0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误 /// /// 当 outTime 指定为-1时,将一直等待直到有数据需要发送 /// public static int SendFile(Socket socket, string filePath, int maxBufferLength, int outTime) { if (filePath == null || maxBufferLength <= 0) { throw new ArgumentException("待发送的文件名称为空或发送缓冲区的大小设置不正确."); } int flag = 0; try { FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); long fileLen = fs.Length; // 文件长度 long leftLen = fileLen; // 未读取部分 int readLen = 0; // 已读取部分 byte[] buffer = null; if (fileLen <= maxBufferLength) { //文件可以一次读取(+1指代结束标识符) buffer = new byte[fileLen + 1]; readLen = fs.Read(buffer, 0, (int)(fileLen + 1)); buffer[fileLen] = (byte)'`'; flag = SendData(socket, buffer, outTime); } else { //循环读取文件,并发送 while (leftLen != 0) { if (leftLen < maxBufferLength) { buffer = new byte[leftLen]; readLen = fs.Read(buffer, 0, Convert.ToInt32(leftLen)); } else { buffer = new byte[maxBufferLength]; readLen = fs.Read(buffer, 0, maxBufferLength); } if ((flag = SendData(socket, buffer, outTime)) < 0) { break; } leftLen -= readLen; } //在结尾带上结束标识符: "`" SendData(socket, System.Text.Encoding.Default.GetBytes("`"), outTime); } fs.Flush(); fs.Close(); } catch (IOException) { //读取待发送文件发生错误 flag = -4; } return flag; } /// /// 使用TCP发送文件 /// /// /// /// /// public static string TCPSend(Socket socket, string path, int maxBufferLength, int outTime) { string res = null; int _flag; //先发送一个标记:"1000"标记为传文件 //D:\KSATProjects\2021-10-ASM\settings\SPI\Lanto_HTTP.INI string eqpName = System.Text.RegularExpressions.Regex.IsMatch(path, "AOI") ? "AOI" : "SPI"; string _filename = Path.GetFileName(path); _flag = Net.SendData(socket, Encoding.Default.GetBytes("1000&" + eqpName + "&" + _filename), outTime); Console.WriteLine(_flag + " 文件发送 " + DateTime.Now.ToString("yyyy:MM:dd HH:mm:ss:ff")); try { if (Net.SendFile(socket, path, maxBufferLength, outTime) != 0) { if (Net.SendFile(socket, path, maxBufferLength, outTime) != 0) { res = "发送失败"; } else { res = "重发成功"; } } else { res = "发送成功"; } } catch (Exception ex) { res ="[ERR]" + ex.Message.ToString(); } return res; } } }