using DevExpress.Utils.Drawing.Helpers; using NPOI.SS.Formula.Functions; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Web.Services.Description; using System.Web.UI.WebControls.WebParts; using System.Windows.Forms; using UAS_MES_NEW.DataOperate; using UAS_MES_NEW.Entity; using UAS_MES_NEW.PublicMethod; namespace UAS_MES_NEW.Make { public partial class Make_WirelessThroughput : Form { public Make_WirelessThroughput() { InitializeComponent(); } StringBuilder SQL = new StringBuilder(); DataTable dt; DataHelper dh; private void Make_WirelessThroughput_Load(object sender, EventArgs e) { dh = SystemInf.dh; try { string hostName = Dns.GetHostName(); IPHostEntry hostEntry = Dns.GetHostEntry(hostName); foreach (IPAddress ip in hostEntry.AddressList) { if (ip.AddressFamily == AddressFamily.InterNetwork) { IPList.Text = ip.ToString(); } } } catch (Exception ex) { ShowMsg(0, $"获取iperf服务器地址失败,{ex.Message}"); } } private void SN_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode != Keys.Enter) return; if (IsCheckSet()) return; string sn = SN.Text.Trim(); if (IPList.Text.IndexOf(':') > 0) IPList.Text = IPList.Text.Replace(":", ":"); else IPList.Text = IPList.Text.Trim(); if (SN.Text.IndexOf(';') > 0) SN.Text = sn.Replace(";", ";"); else SN.Text = sn; UpdateSN("L", SN.Text.Trim()); ShowMsg(1, $"开始测试"); int iSPort = Convert.ToInt32(IPList.Text.Trim().Split(':')[1]); var tester = new CameraIperfTester( timeOut: TestTime.Text.Trim(), cameraIp: ProductList.Text.Trim(), cameraPort: 23, username: Account.Text.Trim(), password: ProductList.Text.Trim(), iperfServerIp: IPList.Text.Trim().Split(':')[0], iperfServerPort: iSPort ); string Msg = tester.TelnetConnect(); if (Msg.Substring(0, 2) != "OK") { ShowMsg(0, $"Telnet登录失败,{Msg}"); return; } ShowMsg(1, $"Telnet登录成功"); string parentPath = Path.GetDirectoryName(ExePath.Text.Trim()); string logsPath = Path.Combine(parentPath, "iperf_logs"); if (!Directory.Exists(logsPath)) { Directory.CreateDirectory(logsPath); } //string[] comList = new string[] { // "killall iperf3_mstar", // "cp /mnt/tf/usb1_1/iperf3_mstar/var/tmp/ -f", // "chmod a+x /var/tmp/iperf3_mstar", // $"/var/tmp/iperf3_mstar -s -p {iSPort} -i 1 &" //}; string[] comList = new string[] { $"iperf3 -s -p {iSPort} -i 1&" }; Msg = tester.StartIperfTest(SN.Text.Trim(), ExePath.Text.Trim(), logsPath, comList); if (Msg.Substring(0, 2) != "OK") { ShowMsg(0, $"iperf3启动失败,{Msg}"); return; } string upRate = Msg.Split('|')[0]; string downRate = Msg.Split('|')[1]; ShowMsg(1, $"OK,上行速率: {upRate},下行速率: {downRate}"); ResMax.Text = upRate; ResMin.Text = downRate; CheckPassStation(SN.Text, upRate, downRate, "PASS"); } private void CheckPassStation(string sn, string upRate, string downRate, string testRes) { string oWO, oWOId, oErrMsg = ""; if (LogicHandler.CheckStepSNAndMacode(workOrder.Text, User.UserSourceCode, sn, User.UserCode, out oWO, out oWOId, out oErrMsg)) { if (LogicHandler.SetStepResult(oWO, User.UserSourceCode, sn, "无线吞吐量", "OK", User.UserCode, out oErrMsg)) { List param = new List() { }; string outMsg = ""; param.Add(oWO); param.Add(sn); param.Add(User.UserSourceCode); param.Add(testRes); param.Add(""); param.Add(""); param.Add("WirelessThroughput"); param.Add(""); param.Add(outMsg); string[] paramList = param.ToArray(); dh.CallProcedure("cs_insert_testrejects", ref paramList); if (paramList[8].Substring(0, 2) == "OK") { ShowMsg(1, $"序列号{sn}采集成功:测试结果为{testRes}"); LogicHandler.DoCommandLog(Tag.ToString(), User.UserCode, oWO, User.UserLineCode, User.UserSourceCode, "无线吞吐量", "无线吞吐量过站成功", sn, ""); } } else { ShowMsg(0, $"序列号{sn},处理过站NG:{oErrMsg}"); } } else { ShowMsg(0, $"序列号{sn},过站核对NG:{oErrMsg}"); } } private bool IsCheckSet() { if (string.IsNullOrEmpty(IPList.Text)) { ShowMsg(0, "请选择本地iperf 服务IP地址"); return true; } if (string.IsNullOrEmpty(ProductList.Text)) { ShowMsg(0, "请选择产品固定IP地址"); return true; } if (string.IsNullOrEmpty(Account.Text)) { ShowMsg(0, "请输入Telnet登录账号"); return true; } if (string.IsNullOrEmpty(Password.Text)) { ShowMsg(0, "请输入Telnet登录密码"); return true; } if (string.IsNullOrEmpty(ExePath.Text)) { ShowMsg(0, "请输入启动iperf3文件"); return true; } if (!File.Exists(ExePath.Text)) { Console.WriteLine("iperf3启动文件不存在"); } if (string.IsNullOrEmpty(TestTime.Text)) { ShowMsg(0, "请输入测试时长"); return true; } //if (Locat1.Checked == false || Locat2.Checked == false || Locat3.Checked == false) //{ // ShowMsg(0, "请选择固件位置"); // return true; //} //if (Radio1.Checked == false || Radio1.Checked == false ) //{ // ShowMsg(0, "请选择测试类型"); // return true; //} return false; } private void UpdateSN(string type, string sn) { if (type == "C") { serialNumber.Text = ""; workOrder.Text = ""; productCode.Text = ""; productName.Text = ""; } else if (type == "L") { SQL.Clear(); SQL.Append($@"SELECT ms_sncode,ma_code,pr_code,pr_spec FROM makeserial,make,product WHERE ms_sncode = '{sn}' AND ms_makecode = ma_code AND ms_prodcode = pr_code"); dt = (DataTable)dh.ExecuteSql(SQL.ToString(), "select"); if (dt.Rows.Count > 0) { serialNumber.Text = dt.Rows[0]["ms_sncode"].ToString(); workOrder.Text = dt.Rows[0]["ma_code"].ToString(); productCode.Text = dt.Rows[0]["pr_code"].ToString(); productName.Text = dt.Rows[0]["pr_spec"].ToString(); } else { UpdateSN("C", sn); } } } public class CameraIperfTester { int timeOut; string cameraIp; int cameraPort; string username; string password; string iperfServerIp; int iperfServerPort; private TcpClient _telnetClient; private NetworkStream _telnetStream; public CameraIperfTester(string timeOut, string cameraIp, int cameraPort, string username, string password, string iperfServerIp, int iperfServerPort) { this.timeOut = Convert.ToInt32(timeOut) * 1000; this.cameraIp = cameraIp; this.cameraPort = cameraPort; this.username = username; this.password = password; this.iperfServerIp = iperfServerIp; this.iperfServerPort = iperfServerPort; } public string StartIperfTest(string SN, string iperfPath,string logDirectory, string[] CList) { if (_telnetStream == null) return "NG,未建立连接"; try { foreach (var comItem in CList) { WriteStream(_telnetStream, comItem); ReadStream(_telnetStream); } Thread.Sleep(1000); // 等服务端启动 string upLog = Path.Combine(logDirectory, $"{SN}_up.log"); string downLog = Path.Combine(logDirectory, $"{SN}_down.log"); RunIperfClient($"-c {cameraIp} -p {iperfServerPort} -t 10 -w 1M -i 1 -P 8 -R", iperfPath, upLog); RunIperfClient($"-c {cameraIp} -p {iperfServerPort} -t 10 -w 1M -i 1 -P 8", iperfPath, downLog); string upRate = ParseIperfBitrate(upLog); string downRate = ParseIperfBitrate(downLog); return $"OK,{upRate}|{downRate}"; } catch (Exception ex) { return $"NG,{ex.Message}"; } } public string TelnetConnect() { try { _telnetClient = new TcpClient(); IAsyncResult connectResult = _telnetClient.BeginConnect(cameraIp, cameraPort, null, null); bool connected = connectResult.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(timeOut)); if (!connected) { _telnetClient.Close(); return "NG,连接超时"; } try { _telnetClient.EndConnect(connectResult); } catch (SocketException ex) { return $"NG,连接失败: {ex.Message}"; } _telnetStream = _telnetClient.GetStream(); _telnetStream.ReadTimeout = 3000; // 3S读取超时 StringBuilder fullResponse = new StringBuilder(); string welcomeResponse = ReadStream(_telnetStream); fullResponse.Append(welcomeResponse); WriteStream(_telnetStream, username); string usernameResponse = ReadStream(_telnetStream); fullResponse.Append(usernameResponse); WriteStream(_telnetStream, password); string loginResponse = ReadStream(_telnetStream); fullResponse.Append(loginResponse); return $"OK,{fullResponse.ToString()}"; } catch (Exception ex) { return $"NG,{ex.Message}"; } } private void RunIperfClient(string args, string path, string logPath) { var psi = new ProcessStartInfo { FileName = path, Arguments = args, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true }; using (var process = Process.Start(psi)) { string output = process.StandardOutput.ReadToEnd(); string error = process.StandardError.ReadToEnd(); process.WaitForExit(5000); // 最多等 15 秒 File.WriteAllText(logPath, output + Environment.NewLine + error); } } private string ParseIperfBitrate(string logPath) { if (!File.Exists(logPath)) return "0.0"; var lines = File.ReadAllLines(logPath); List logItem = new List { }; foreach (var line in lines) { if (line.Trim().StartsWith("[SUM]")) { logItem.Add(line); } } if(logItem.Count > 0 && logItem[logItem.Count].Contains("receiver")) { var matches = Regex.Matches(logItem[logItem.Count], @"(\d+\.?\d*)\s+(?:MBytes|Mbits/sec)"); if (matches.Count >= 2) { double value1 = double.Parse(matches[0].Groups[1].Value); double value2 = double.Parse(matches[1].Groups[1].Value); return value2.ToString(); } } return "0.0"; } private void WriteStream(NetworkStream stream, string text) { byte[] data = Encoding.ASCII.GetBytes(text + "\r\n"); stream.Write(data, 0, data.Length); stream.Flush(); } private string ReadStream(NetworkStream stream) { StringBuilder sb = new StringBuilder(); byte[] buffer = new byte[1024]; int totalBytesRead = 0; int currentBytesRead = 0; DateTime lastReadTime = DateTime.UtcNow; TimeSpan idleTimeout = TimeSpan.FromMilliseconds(800); // 空闲超时 try { do { currentBytesRead = stream.Read(buffer, 0, buffer.Length); if (currentBytesRead > 0) { sb.Append(Encoding.ASCII.GetString(buffer, 0, currentBytesRead)); totalBytesRead += currentBytesRead; lastReadTime = DateTime.UtcNow; } } while ((DateTime.UtcNow - lastReadTime) < idleTimeout); } catch (IOException ioEx) { } catch (ObjectDisposedException) { throw; } catch (SocketException sockEx) { throw new IOException($"NG,网络错误: {sockEx.Message}", sockEx); } return sb.ToString(); } } private void ShowMsg(int type, string msg) { msg = msg.Replace("\r", "").Replace("\n", ""); string msgTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); string showMsg = $"{msgTime}: {msg}\n"; if (type == 0) { OperatResult.AppendText(showMsg, Color.Red); } else if (type == 1) { OperatResult.AppendText(showMsg, Color.Green); } } private void Radio1_Click(object sender, EventArgs e) { if (Radio1.Checked) { Radio2.Checked = false; } } private void Radio2_Click(object sender, EventArgs e) { if (Radio2.Checked) { Radio1.Checked = false; } } private void Locat1_Click(object sender, EventArgs e) { if (Locat1.Checked) { Locat2.Checked = false; Locat3.Checked = false; } } private void Locat2_Click(object sender, EventArgs e) { if (Locat2.Checked) { Locat1.Checked = false; Locat3.Checked = false; } } private void Locat3_Click(object sender, EventArgs e) { if (Locat3.Checked) { Locat1.Checked = false; Locat2.Checked = false; } } private void Account_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode != Keys.Enter) return; Password.Focus(); Password.SelectAll(); } private void Password_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode != Keys.Enter) return; TestTime.Focus(); TestTime.SelectAll(); } private void ExePath_Click(object sender, EventArgs e) { using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.Title = "选择iperf3启动文件"; openFileDialog.Filter = "可执行文件 (*.exe)|*.exe|所有文件 (*.*)|*.*"; openFileDialog.FilterIndex = 1; openFileDialog.RestoreDirectory = true; // 设置初始目录(可选) if (!string.IsNullOrEmpty(ExePath.Text) && System.IO.File.Exists(ExePath.Text)) { openFileDialog.InitialDirectory = System.IO.Path.GetDirectoryName(ExePath.Text); } else { openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); } if (openFileDialog.ShowDialog() == DialogResult.OK) { ExePath.Text = openFileDialog.FileName; ShowMsg(1, $"已成功选择iperf3启动文件"); } } } private void Clear_Click(object sender, EventArgs e) { OperatResult.Clear(); } } }