using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using VisionCCD;
namespace visionPro项目练习
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//设置清空日志按钮颜色,点击时变为绿色,松开时颜色恢复
button_清空日志.MouseUp += (sender, e) =>
{
button_清空日志.BackColor = Color.White;
};
button_清空日志.MouseDown += (sender, e) =>
{
button_清空日志.BackColor = Color.Green;
};
//当鼠标悬停在按钮上时,改变背景颜色
button_清空日志.MouseEnter += (sender, e) =>
{
button_清空日志.BackColor = Color.BlueViolet;
};
button_清空日志.MouseLeave += (sender, e) =>
{
button_清空日志.BackColor = Color.BlueViolet;
};
button_清空日志.MouseEnter += (sender, e) =>
{
button_清空日志.BackColor = Color.BlueViolet;
};
button_清空日志.MouseLeave += (sender, e) =>
{
button_清空日志.BackColor = Color.White;
};
//设置打开文件按钮颜色,点击时变为绿色,松开时颜色恢复
button_openFile.MouseEnter += (sender, e) =>
{
button_openFile.BackColor = Color.BlueViolet;
};
button_openFile.MouseLeave += (sender, e) =>
{
button_openFile.BackColor = Color.BlueViolet;
};
button_openFile.MouseEnter += (sender, e) =>
{
button_openFile.BackColor = Color.BlueViolet;
};
button_openFile.MouseLeave += (sender, e) =>
{
button_openFile.BackColor = Color.White;
};
//设置打开文件按钮颜色,点击时变为绿色,松开时颜色恢复
button_openFile.MouseUp += (sender, e) =>
{
button_openFile.BackColor = Color.White;
};
button_openFile.MouseDown += (sender, e) =>
{
button_openFile.BackColor = Color.Green;
};
//设置保存文件按钮颜色,点击时变为绿色,松开时颜色恢复
button_File.MouseEnter += (sender, e) =>
{
button_File.BackColor = Color.BlueViolet;
};
button_File.MouseLeave += (sender, e) =>
{
button_File.BackColor = Color.BlueViolet;
};
button_File.MouseEnter += (sender, e) =>
{
button_File.BackColor = Color.BlueViolet;
};
button_File.MouseLeave += (sender, e) =>
{
button_File.BackColor = Color.White;
};
//设置显示按钮颜色,点击时变为绿色,松开时颜色恢复
button_display.MouseUp += (sender, e) =>
{
button_display.BackColor = Color.White;
};
button_display.MouseDown += (sender, e) =>
{
button_display.BackColor = Color.Green;
};
button_display.MouseEnter += (sender, e) =>
{
button_display.BackColor = Color.BlueViolet;
};
button_display.MouseLeave += (sender, e) =>
{
button_display.BackColor = Color.BlueViolet;
};
button_display.MouseEnter += (sender, e) =>
{
button_display.BackColor = Color.BlueViolet;
};
button_display.MouseLeave += (sender, e) =>
{
button_display.BackColor = Color.White;
};
//设置控件按钮颜色,点击时变为绿色,松开时颜色恢复
button_控件.MouseUp += (sender, e) =>
{
button_控件.BackColor = Color.White;
};
button_控件.MouseDown += (sender, e) =>
{
button_控件.BackColor = Color.Green;
};
button_控件.MouseUp += (sender, e) =>
{
button_控件.BackColor = Color.White;
};
button_控件.MouseDown += (sender, e) =>
{
button_控件.BackColor = Color.Green;
};
//设置控件按钮颜色,点击时变为绿色,松开时颜色恢复
button_控件.MouseEnter += (sender, e) =>
{
button_控件.BackColor = Color.BlueViolet;
};
button_控件.MouseLeave += (sender, e) =>
{
button_控件.BackColor = Color.BlueViolet;
};
button_控件.MouseEnter += (sender, e) =>
{
button_控件.BackColor = Color.BlueViolet;
};
button_控件.MouseLeave += (sender, e) =>
{
button_控件.BackColor = Color.White;
};
//设置控件按钮颜色,点击时变为绿色,松开时颜色恢复
button_控件.MouseUp += (sender, e) =>
{
button_控件.BackColor = Color.White;
};
button_控件.MouseDown += (sender, e) =>
{
button_控件.BackColor = Color.Green;
};
//设置button_客户端按钮颜色,点击时变为绿色,松开时颜色恢复
button_客户端.MouseEnter += (sender, e) =>
{
button_客户端.BackColor = Color.BlueViolet;
};
button_客户端.MouseLeave += (sender, e) =>
{
button_客户端.BackColor = Color.BlueViolet;
};
button_客户端.MouseEnter += (sender, e) =>
{
button_客户端.BackColor = Color.BlueViolet;
};
button_客户端.MouseLeave += (sender, e) =>
{
button_客户端.BackColor = Color.White;
};
//设置button_客户端按钮颜色,点击时变为绿色,松开时颜色恢复
button_客户端.MouseUp += (sender, e) =>
{
button_客户端.BackColor = Color.White;
};
button_客户端.MouseDown += (sender, e) =>
{
button_客户端.BackColor = Color.Green;
};
}
private void Form1_Load(object sender, EventArgs e)
{
danlimoshi.Instance.SetToolBlock(cogToolBlockEditV21, RecordDisplay);
}
private void button1_Click(object sender, EventArgs e)
{
danlimoshi.Instance.SaveToolBlock();
}
private void button2_Click(object sender, EventArgs e)
{
danlimoshi.Instance.Run();
ClassFustion.SaveText("当前用户点击拍照" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\n", text: textBox1);
}
// 添加保存文件方法
private void button_File_Click(object sender, EventArgs e)
{
using (SaveFileDialog saveDialog = new SaveFileDialog())
{
saveDialog.Filter = "日志文件|*.log|文本文件|*.txt|所有文件|*.*";
saveDialog.Title = "保存日志文件";
saveDialog.DefaultExt = ".log";
// 设置初始值
string lastPath = ClassFustion.GetPersistedLogPath();
if (!string.IsNullOrEmpty(lastPath))
{
saveDialog.InitialDirectory = Path.GetDirectoryName(lastPath);
saveDialog.FileName = Path.GetFileName(lastPath);
}
if (saveDialog.ShowDialog() == DialogResult.OK)
{
// 导出日志
ClassFustion.ExportLog(textBox1.Text, saveDialog.FileName);
// 记录最新路径
ClassFustion.PersistLogPath(saveDialog.FileName);
// 记录操作日志
ClassFustion.SaveText($"日志已保存到: {saveDialog.FileName}", text: textBox1);
}
}
}
// 添加打开文件方法
private void button_openFile_Click(object sender, EventArgs e)
{
using (OpenFileDialog openDialog = new OpenFileDialog())
{
openDialog.Filter = "日志文件|*.log;*.txt|所有文件|*.*";
openDialog.Title = "打开日志文件";
// 设置初始目录
string lastPath = ClassFustion.GetPersistedLogPath();
if (!string.IsNullOrEmpty(lastPath))
{
openDialog.InitialDirectory = Path.GetDirectoryName(lastPath);
}
if (openDialog.ShowDialog() == DialogResult.OK)
{
// 加载日志
string logContent = ClassFustion.LoadLog(openDialog.FileName);
if (!string.IsNullOrEmpty(logContent))
{
textBox1.Text = logContent;
ClassFustion.SaveText($"已加载日志: {openDialog.FileName}", text: textBox1);
}
}
}
}
private void button_清空日志_Click(object sender, EventArgs e)
{
textBox1.Text = "";
}
private void button1_Click_1(object sender, EventArgs e)
{
Face face = new Face();
face.Show();
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using communication;
namespace VisionCCD
{
[Serializable]
/// <summary>
/// 通讯页面类
/// </summary>
public partial class Face : Form
{
#region 变量
Thread th = null;
SockServer servers;
#endregion
#region 单例模式
private static Face single = null;
/// <summary>
/// 通讯界面单例
/// </summary>
public static Face Single
{
get
{
if (single == null)
{
single = new Face();
}
return single;
}
}
#endregion
#region 设计窗体
/// <summary>
/// 该类被实例化第1就调用此方法
/// </summary>
public Face()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;//跨线程访问
}
/// <summary>
/// 该方法等.show()被调用之后,程序就会调用Form1_Load,为第2步
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Load(object sender, EventArgs e)
{
}
/// <summary>
/// 该方法等程序被关闭时,Form1_FormClosing被调用,为第“最后一步”
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
//System.Diagnostics.Process tt = System.Diagnostics.Process.GetProcessById(System.Diagnostics.Process.GetCurrentProcess().Id);
//tt.Kill();
this.Hide();
e.Cancel = true;
}
#endregion
#region TCP客户端
#region 客户端变量
#region 设置标定变量
private string tcp_Send;
/// <summary>
/// 标定发送表头
/// </summary>
public string Tcp_Send
{
get
{
return tcp_Send;
}
set
{
if (value != null && value.Length > 0)
{
tcp_Send = value;
}
}
}
private int tcp_SplitHead;
/// <summary>
/// 起始字符
/// </summary>
public int Tcp_SplitHead
{
get
{
return tcp_SplitHead;
}
set
{
if (value != null && value.ToString().Length > 0)
{
tcp_SplitHead = value;
}
}
}
private int tcp_SplitLengt;
/// <summary>
/// 字符长度
/// </summary>
public int Tcp_SplitLengt
{
get
{
return tcp_SplitLengt;
}
set
{
if (value != null && value.ToString().Length > 0)
{
tcp_SplitLengt = value;
}
}
}
private string tcp_SplitStr;
/// <summary>
/// 字符
/// </summary>
public string Tcp_SplitStr
{
get
{
return tcp_SplitStr;
}
set
{
if (value != null && value.Length > 0)
{
tcp_SplitStr = value;
}
}
}
private char[] tcp_Index;
/// <summary>
/// 截取数据
/// </summary>
public char[] Tcp_Index
{
get
{
return tcp_Index;
}
set
{
if (value != null && value.Length > 0)
{
tcp_Index = value;
}
}
}
#endregion
#region 设置定位变量
private string tcp_SendS;
public string Tcp_SendS
{
get
{
return tcp_SendS;
}
set
{
if (value != null && value.Length > 0)
{
tcp_SendS = value;
}
}
}
private int tcp_SplitHeadS;
public int Tcp_SplitHeadS
{
get
{
return tcp_SplitHeadS;
}
set
{
if (value != null && value.ToString().Length > 0)
{
tcp_SplitHeadS = value;
}
}
}
private int tcp_SplitLengtS;
public int Tcp_SplitLengtS
{
get
{
return tcp_SplitLengtS;
}
set
{
if (value != null && value.ToString().Length > 0)
{
tcp_SplitLengtS = value;
}
}
}
private string tcp_SplitStrS;
public string Tcp_SplitStrS
{
get
{
return tcp_SplitStrS;
}
set
{
if (value != null && value.Length > 0)
{
tcp_SplitStrS = value;
}
}
}
#endregion
#endregion
/// <summary>
/// 通讯接收消息
/// </summary>
/// <param name="value"></param>
private void XingHao(string value)
{
try
{
if (value.Length >= 0)
{
ClientDataShow.AppendText(value + "\r\n");
}
}
catch (Exception ex)
{
MessageBox.Show("接收信号失败:" + ex.Message);
}
}
#endregion
#region 客户端
//链接按钮
private void button4_Click(object sender, EventArgs e)
{
SockClient.Single.Connect(ClinetIP.Text,Convert.ToInt16(ClientPort.Text));
SockClient.Single.del -= XingHao;
SockClient.Single.del += XingHao;
}
//关闭按钮
private void button6_Click(object sender, EventArgs e)
{
SockClient.Single.Close();//关闭连接
this.Close();//关闭窗口
}
//发送按钮
private void button3_Click(object sender, EventArgs e)
{
SockClient.Single.Send(textBox5.Text);
MessageBox.Show("发送成功");
}
#endregion
//修改按钮
private void BT_DataSplit_Click(object sender, EventArgs e)
{
try
{
Tcp_Send = ClinetSendTex.Text;//标定发送表头
Tcp_SplitHead = Convert.ToInt16(CB_SplitHead.Text);//起始字符
Tcp_SplitLengt = Convert.ToInt16(CB_SplitLengt.Text);//字符长度
Tcp_SplitStr = TB_SplitStr.Text;//字符
char[] lo1 = Encoding.Default.GetChars(Encoding.Default.GetBytes(TB_Index1.Text));//截取数据_索引
char[] lo2 = Encoding.Default.GetChars(Encoding.Default.GetBytes(TB_Index2.Text));
char[] lo3 = Encoding.Default.GetChars(Encoding.Default.GetBytes(TB_Word_X1.Text));//截取数据_Word_X
char[] lo4 = Encoding.Default.GetChars(Encoding.Default.GetBytes(TB_Word_X2.Text));
char[] lo5 = Encoding.Default.GetChars(Encoding.Default.GetBytes(TB_Word_Y1.Text));//截取数据_Word_Y
char[] lo6 = Encoding.Default.GetChars(Encoding.Default.GetBytes(TB_Word_Y2.Text));
char[] JiLu = new char[6];
JiLu[0] = lo1[0]; JiLu[1] = lo2[0]; JiLu[2] = lo3[0]; JiLu[3] = lo4[0]; JiLu[4] = lo5[0]; JiLu[5] = lo6[0];
Tcp_Index = JiLu;//截取数据
Tcp_SplitHeadS = Convert.ToInt16(comboBox3.Text);
Tcp_SplitLengtS = Convert.ToInt16(comboBox2.Text);
Tcp_SplitStrS = textBox6.Text;
Tcp_SendS = textBox7.Text;
}
catch (Exception ex)
{
MessageBox.Show("交互设置异常:" + ex.Message);
}
}
#region TCP服务器
//服务器链接按钮
private void button1_Click(object sender, EventArgs e)
{
servers = new SockServer();
servers.CreateSever(IpAddres.Text,Convert.ToInt16(PortAddres.Text));
}
//关闭按钮
private void button2_Click(object sender, EventArgs e)
{
servers.Send(SendTex.Text);
}
//发送按钮
private void button5_Click(object sender, EventArgs e)
{
servers.Close();
}
#endregion
}
}
using Cognex.VisionPro;
using Cognex.VisionPro.CalibFix;
using Cognex.VisionPro.Caliper;
using Cognex.VisionPro.PMAlign;
using Cognex.VisionPro.ToolBlock;
using communication;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Documents;
using System.Windows.Forms;
namespace visionPro项目练习
{
public class danlimoshi
{
//定义一个单例模式
private static danlimoshi instance = null;
CogToolBlockEditV2 _toolBlock = null;
CogToolBlock Block = null;
int indexs;
double x;double y;
CogRecordDisplay cogRecordDisplay1;
string biaotou = null;
public static danlimoshi Instance
{
get
{
if (instance == null)
{
instance = new danlimoshi();
}
return instance;
}
}
public void SetToolBlock(CogToolBlockEditV2 toolBlock, CogRecordDisplay cogRecordDisplay1)
{
Block = CogSerializer.LoadObjectFromFile(Application.StartupPath + "\\File\\PAM.vpp") as CogToolBlock;
this._toolBlock = toolBlock;
this._toolBlock.Subject = null;
this._toolBlock.Subject = Block;
this.cogRecordDisplay1 = cogRecordDisplay1;
Block.Ran += Block_Ran;
SockClient.Single.del += GetTCPdate;
}
private void Block_Ran(object sender, EventArgs e)
{
cogRecordDisplay1.Image = (ICogImage)Block.Outputs[0].Value; // 获取输出图像
cogRecordDisplay1.Record = Block.CreateLastRunRecord(); // 获取运行记录
// 图像自适应
cogRecordDisplay1.Fit(false); // 不保持比例
CogPMAlignTool pmAlignTool = Block.Tools["CogPMAlignTool1"] as CogPMAlignTool;//获取圆检测工具
//判断圆是否被检测到
if (pmAlignTool.Results.Count > 0)
{
CreateLabel(0, 0, "模版匹配成功!");
CogFindCircleTool cfc = Block.Tools["CogFindCircleTool1"] as CogFindCircleTool;
if (cfc.Results!=null && cfc.Results.GetCircle()!=null)
{
//找圆成功
CreateLabel(0, 100, "找圆成功!");
if (biaotou == "Calib") {
Calib(indexs, cfc.Results.GetCircle().CenterX, cfc.Results.GetCircle().CenterY,x, y);
}
else if (biaotou == "CameraS1") {
string val = "CameraOK:" + cfc.Results.GetCircle().CenterX + "," + cfc.Results.GetCircle().CenterY + "#0$";
SockClient.Single.Send(val);
ClassFustion.SaveText("发送信号:"+val);
}
}
else
{
//找圆失败
CreateLabel(0, 100, "找圆失败!", false);
}
}
else
{
CreateLabel(0, 0, "圆检测失败!", false);
}
biaotou = null;//清空标志位
}
//获得通讯TCP
private void GetTCPdate(string vule) {
ClassFustion.SaveText("收到信号:"+vule);
if (vule.Substring(0,5) == "Calib")//判断是否为校准数据
{
biaotou = "Calib";
indexs =Convert.ToInt16( vule.Split(':')[1].Split(';')[0] );//获取圆心索引号
x = Convert.ToDouble(vule.Split(';')[1].Split(',')[0]);//获取圆心X坐标
y = Convert.ToInt16(vule.Split(',')[1].Split('#')[0]);//获取圆心Y坐标
Block.Run();//执行拍照
}
if (vule.Substring(0,8) == "CameraS1" ) { //判断是否为“定位表头”
biaotou = "CameraS1";
Run();//执行拍照
}
}
/// <summary>
/// 创建标签方法
/// </summary>
///
public void CreateLabel(double x, double y, string text, bool Color = true)
{
//创建标签
CogGraphicLabel label = new CogGraphicLabel();
//设置标签字体大小
label.Font = new System.Drawing.Font("Arial", 15);
if (Color)
{
//设置字体颜色
label.Color = CogColorConstants.Green;
}
else
{
label.Color = CogColorConstants.Red;
}
//设置对齐方式
label.Alignment = CogGraphicLabelAlignmentConstants.TopLeft;
//显示文字内容和位置
label.SetXYText(x, y, text);
//将标签显示在图形上
this.cogRecordDisplay1.InteractiveGraphics.Add(label, "CogImageConvertTool1.OutputImage", true);
}
//创建一个方法,将工具块保存到文件
public void SaveToolBlock()
{
//获取工具块内容
CogToolBlock vppToolBlock = this._toolBlock.Subject;
//保存文件
CogSerializer.SaveObjectToFile(vppToolBlock, Application.StartupPath + "\\File\\PAM.vpp");
}
//创建一个run方法,将图片显示在RecordDisplay上
public void Run()
{
//运行工具块
Block.Run();
}
//这里创建一个九点标定方法,对应的坐标进行标定
public void Calib(int index,double pixel_x,double pixel_y,double Robot_x, double Robot_y) {
//获取校准点到点工具
index -= 1;
CogCalibNPointToNPointTool calib = Block.Tools["CogCalibNPointToNPointTool1"] as CogCalibNPointToNPointTool;
//未校正XY坐标,数据传入接口
calib.Calibration.SetUncalibratedPoint(8-index, pixel_x, pixel_y);
//原始坐标,数据传入接口
calib.Calibration.SetRawCalibratedPoint(index, Robot_x, Robot_y);
if (index >= 8)
{
//标定完成标定
calib.Calibration.Calibrate();
calib.Run();
}
else
{
// index++;
SockClient.Single.Send("CalibOK"+indexs);
ClassFustion.SaveText("发送信号:" + "CalibOK" + indexs);
}
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace visionPro项目练习
{
//封装基本文件基本操作功能
public class ClassFustion
{
//定义一个全局变量
public static string path;
//定义一个全局变量来接收形参
static string InputsPaths = "";
//定义一个全局变量来接收形参
public static System.Windows.Forms.TextBox texts = null;
// 新增:持久化日志文件路径
private static string _persistedLogPath = "";
//定义一个方法,用来保存文本到文件和控件中
public static void SaveText(string value, string InputsPath = null, System.Windows.Forms.TextBox text = null)
{
// 正确处理InputsPath参数
if (!string.IsNullOrEmpty(InputsPath))
{
InputsPaths = InputsPath;
}
// 更新TextBox引用
if (text != null)
{
texts = text;
}
// 安全调用Invoke方法(关键修复)
if ( texts != null && texts.IsHandleCreated && !texts.IsDisposed)
{
texts.Invoke(new Action(() =>
{
texts.AppendText(value + "\r\n");
}));
}
else
{
// 可选:记录警告或改用其他日志方式
Console.WriteLine($"日志文本控件不可用: {value}");
}
// 原有文件日志记录代码保持不变...
string yearTime = Application.StartupPath + "//" + DateTime.Now.Year.ToString();
string MonthTime = yearTime + DateTime.Now.ToLongDateString() + "//";
string DayTime = MonthTime + DateTime.Now.ToLongDateString() + "//" + "日志" + "//";
if (!Directory.Exists(yearTime))//判断文件夹是否存在,不存在则创建
{
Directory.CreateDirectory(yearTime);
}
if (!Directory.Exists(MonthTime))//判断文件夹是否存在,不存在则创建
{
Directory.CreateDirectory(MonthTime);
}
if (!Directory.Exists(DayTime))//判断文件夹是否存在,不存在则创建
{
Directory.CreateDirectory(DayTime);
}
//写入文件
FileStream fs = new FileStream(DayTime + "/" + "日志.txt", FileMode.Append);
//定义写入流对象
StreamWriter streamWriter = new StreamWriter(fs, Encoding.Default);
//写入文件内容
streamWriter.WriteLine(value);
//关闭流对象
streamWriter.Close();
//关闭文件流对象
fs.Close();
}
// 新增:导出日志到指定文件
public static void ExportLog(string content, string filePath)
{
try
{
// 写入文件
File.WriteAllText(filePath, content, Encoding.UTF8);
}
catch (Exception ex)
{
MessageBox.Show($"日志导出失败: {ex.Message}", "错误",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// 新增:从文件加载日志
public static string LoadLog(string filePath)
{
try
{
// 读取文件
return File.ReadAllText(filePath, Encoding.UTF8);
}
catch (Exception ex)
{
MessageBox.Show($"日志加载失败: {ex.Message}", "错误",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return string.Empty;
}
}
// 修改:保存时设置持久化路径
public static void PersistLogPath(string filePath)
{
// 设置持久化日志路径
_persistedLogPath = filePath;
}
// 修改:获取持久化日志路径
public static string GetPersistedLogPath()
{
return _persistedLogPath;
}
//这里定义一个方法,用来选择要保存文件的文件夹
//在Form1中,拖一个按钮,点击事件中调用该方法,就可以选择文件夹了
public static void FolderBrowserDialog() {
using (FolderBrowserDialog fbd = new FolderBrowserDialog())
{
fbd.Description = "请选择 要保存文件的文件夹";
if (fbd.ShowDialog() == DialogResult.OK)
{
path = fbd.SelectedPath;//查看返回路径
}
}
}
//这里定义一个方法,用来打开文件,并且在Form1中,拖一个按钮,点击事件中
//调用该方法,就可以打开文件了,并且将文件中的日志显示在TextBox1中
public static void OpenText() {
System.Diagnostics.Process.Start(path);//打开文件
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Windows.Forms;
using static System.Collections.Specialized.BitVector32;
using System.Web.Services.Description;
namespace communication
{
/// <summary>
/// 以太网客户端
/// </summary>
///
public class SockClient
{
//定义一个委托
public delegate void Del(string vlue);
public Del del;
#region 单例模式
private static SockClient single = null;
/// <summary>
/// 通讯单例
/// </summary>
///
public static SockClient Single
{
get
{
if (single == null)
{
single = new SockClient();
}
return single;
}
}
#endregion
#region sock通讯
#region 变量
/// <summary>
/// 客户端
/// </summary>
Socket tcp;
public string value = "";
#endregion
/// <summary>
/// 链接通讯
/// </summary>
/// <param name="IP">ip地址</param>
/// <param name="port">端口号</param>
/// <param name="mothed">绑定方法</param>
public void Connect(string IP, int port)
{
if (tcp == null || !tcp.IsBound)
{
try
{
//定义一个套接字用于监听客户端发来的消息,包含三个参数(IP4寻址协议,流式连接,Tcp协议)
tcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//将IP地址和端口号绑定到网络节点point上,连接服务器
tcp.Connect(IPAddress.Parse(IP), port);
//创建线程接收数据
Thread th = new Thread(th_);
th.IsBackground = true;
th.Start();
}
catch (Exception)
{
MessageBox.Show("连接失败");
}
}
}
/// <summary>
/// 线程调用的方法,接收服务器消息
/// </summary>
private void th_()
{
//创建一个内存缓冲区,其大小为1024*1024字节 即1M。
byte[] Byte = new byte[1024 * 1024];
while (true)
{
Thread.Sleep(5);//线程安全一定加延时
try
{//接收到监听的Socket的数据
int num = tcp.Receive(Byte);
if (num == 0)//当服务器断开,num收到的字节数为0,可作为退出机制
{
tcp.Close();//退出自动关闭客户端
tcp.Dispose();
return;
}
//利用 Encoding.Default.GetString 获取客户端信息,注意是 字节 转化为 字符串
value = Encoding.Default.GetString(Byte, 0, num);
del.Invoke(value);
}
catch (Exception ex)
{
MessageBox.Show("接收信号异常:" + ex.Message);
}
}
}
/// <summary>
/// 发送数据至服务器
/// </summary>
public void Send(string value)
{
try
{
tcp.Send(Encoding.Default.GetBytes(value));
}
catch (Exception)
{
throw new Exception("发送信号异常");
}
}
/// <summary>
/// 关闭通讯
/// </summary>
public void Close()
{
tcp.Close();
tcp.Dispose();
tcp = null;
GC.Collect();
}
#endregion
}
//创建一个以太网服务器
public class SockServer
{
Socket server;
Socket newLink;
#region 创建服务器
public void CreateSever(string IP, int port)
{
//创建一个套接字用于监听客户端发来的消息,包含三个参数(IP4寻址协议,流式连接,Tcp协议)
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//创建一个IP地址和端口号,用于监听客户端的连接请求
IPEndPoint iPEnd = new IPEndPoint(IPAddress.Parse(IP), port);
server.Bind(iPEnd);//绑定IP地址和端口号
server.Listen(10);//设置最大连接数
Thread list = new Thread(Accept);//创建一个线程,用于监听客户端的连接请求
list.IsBackground = true;//设置为后台线程
list.Start();//开始监听客户端的连接请求
//创建线程接收数据
Thread th = new Thread(th_);
th.IsBackground = true;//设置为后台线程
th.Start();//开始接收数据
}
//创建一个监听客户端连接方法
private ManualResetEvent newLinkReady = new ManualResetEvent(false);
public void Accept()
{
while (true)
{
// 阻塞,直到有客户端连接
Socket clientSocket = server.Accept();
// 初始化 newLink
newLink = clientSocket;
// 通知接收数据的线程 newLink 已经准备好
newLinkReady.Set();
}
}
public void th_()
{
// 等待 newLink 准备好
newLinkReady.WaitOne();
// 创建一个内存缓冲区,其大小为1024*1024字节 即1M。
byte[] Byte = new byte[1024 * 1024];
while (true) // 循环接收客户端的消息
{
Thread.Sleep(5); // 线程安全一定加延时
// 接收客户端的消息,并将其存入Byte数组中
int num = newLink.Receive(Byte);
if (num == 0) // 当客户端断开,num收到的字节数为0,可作为退出机制
{
newLink.Close(); // 退出自动关闭客户端
return;
}
}
}
//创建一个发送消息的方法
public void Send(string vlue)
{
//将字符串转化为字节,发送给客户端
newLink.Send(Encoding.Default.GetBytes(vlue));
//发送回车换行,便于客户端接收
newLink.Send(Encoding.Default.GetBytes("\r\n"));
}
//创建一个关闭服务器的方法
public void Close()
{
server.Close();//关闭服务器
server.Dispose();//释放资源
}
#endregion
}
}
请帮我优化此程序,是优化程序不是大幅度修改程序,优化完之后,要能保证客户端要能和服务器上位机通讯的上,即能互相接收消息也能互相发消息,优化之后也要保证程序不会报错,要能保证日志显示在文本框上,并且给服务器上位机发消息要能接收到服务器上位机回馈的消息,就比如给上位机发送:触发标定信号
ccd--->对方:CalibOK0
对方--->ccd: Calib:0;X,Y#
然后服务器上位机回馈,比如发送:上相机 触发拍照信号
对方--->CCD :CameraS1:X,Y#R$
CCD--->对方 :CameraOK:X,Y#R$
***********多点拍照************
上相机 触发拍照信号
对方--->CCD :CameraS1:X,Y#R$
CCD--->对方 :Multipoint3
CCD--->对方 :CameraMultipoint#X1,Y1#X2,Y2...#XN,YN#
***********双相机************
上相机 触发拍照信号
对方--->CCD :CameraS1:X,Y#R$
CCD--->对方 :CameraOKS
下相机 触发拍照信号
对方--->CCD :CameraS2:X,Y#R$
CCD--->对方 :CameraOK:X,Y#R$
最新发布