AutoCAD.net支持后台线程-Socket通讯
最近因为公司项目的需求,CAD作为服务端在服务器中常驻运行,等待客户端远程发送执行任务的指令,最终确认用Socket-tcp通讯,CAD需要实时监听客户端发送的消息,这时就需要开启线程执行Socket的监听任务。
这样问题就来了,CADAPI不支持多线程,您只能从主线程调用API函数,如果您处于不同的线程,则必须将调用集中到主线程上。
最后查了半天的资料发现,最简单的实现方式,是建立在主线程system.windows.forms.control对象并调用它的启动功能,做最后处理invoke()功能。
下面分别是客户端和服务端的demo
1 class Program 2 { 3 private static byte[] result = new byte[1024]; 4 static void Main(string[] args) 5 { 6 //设定服务器IP地址 7 IPAddress ip = IPAddress.Parse("10.19.10.237"); 8 //IPAddress ip = IPAddress.Parse("127.0.0.1"); 9 Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 10 try 11 { 12 clientSocket.Connect(new IPEndPoint(ip, 8885)); //配置服务器IP与端口 13 Console.WriteLine("连接服务器成功"); 14 } 15 catch 16 { 17 Console.WriteLine("连接服务器失败,请按回车键退出!"); 18 return; 19 } 20 //通过clientSocket接收数据 21 int receiveLength = clientSocket.Receive(result); 22 Console.WriteLine("接收服务器消息:{0}", Encoding.UTF8.GetString(result, 0, receiveLength)); 23 //通过 clientSocket 发送数据 24 for (int i = 0; i < 13; i++) 25 { 26 try 27 { 28 Thread.Sleep(1000); //等待1秒钟 29 string sendMessage = "C:\\Users\\Administrator\\Desktop\\原始CAD文件\\14412-kujiale.dxf"; 30 clientSocket.Send(Encoding.UTF8.GetBytes(sendMessage)); 31 Console.WriteLine("向服务器发送消息:{0}" + sendMessage); 32 receiveLength = clientSocket.Receive(result); 33 Console.WriteLine("接收服务器消息:{0}", Encoding.UTF8.GetString(result, 0, receiveLength)); 34 } 35 catch 36 { 37 clientSocket.Shutdown(SocketShutdown.Both); 38 clientSocket.Close(); 39 break; 40 } 41 } 42 clientSocket.Shutdown(SocketShutdown.Both); 43 clientSocket.Close(); 44 Console.WriteLine("发送完毕,按回车键退出"); 45 Console.ReadLine(); 46 } 47 }
1 public class SocketServer 2 { 3 //通过winform控件进行后台处理,CADAPI不支持多线程 4 static Control syncCtrl; 5 //承载接收数据 6 private static byte[] result = new byte[1024]; 7 //端口 8 private static int myProt = 8885; 9 10 private static Socket serverSocket; 11 12 delegate void FinishedProcessingDelegate(); 13 public static void InitSocket() 14 { 15 //创建控件 16 syncCtrl = new Control(); 17 syncCtrl.CreateControl(); 18 //创建通讯对象 19 serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 20 //绑定IP地址:端口 21 serverSocket.Bind(new IPEndPoint(IPAddress.Any, myProt)); 22 //设定最多10个排队连接请求 23 serverSocket.Listen(10); 24 //通过Clientsoket发送数据 25 Thread myThread = new Thread(ListenClientConnect); 26 myThread.Start(); 27 } 28 /// <summary> 29 /// 监听客户端连接 30 /// </summary> 31 private static void ListenClientConnect() 32 { 33 while (true) 34 { 35 Socket clientSocket = serverSocket.Accept(); 36 try 37 { 38 39 clientSocket.Send(Encoding.UTF8.GetBytes("我是牛魔王")); 40 Thread receiveThread = new Thread(ReceiveMessage); 41 receiveThread.Start(clientSocket); 42 } 43 catch (Exception) 44 { 45 46 clientSocket.Shutdown(SocketShutdown.Both); 47 clientSocket.Close(); 48 } 49 50 } 51 } 52 53 /// <summary> 54 /// 接收消息 55 /// </summary> 56 /// <param name="clientSocket"></param> 57 private static void ReceiveMessage(object clientSocket) 58 { 59 Socket myClientSocket = (Socket)clientSocket; 60 while (true) 61 { 62 try 63 { 64 //通过clientSocket接收数据 65 int receiveNumber = myClientSocket.Receive(result); 66 if (receiveNumber>0) 67 { 68 //获取文件名称 69 string filePath = Encoding.UTF8.GetString(result, 0, receiveNumber); 70 //判断文件是否存在 71 if (FileOperate.FileExists(filePath)) 72 { 73 FileStandardization.filePathByJava = filePath; 74 if (syncCtrl.InvokeRequired) 75 { 76 //开始执行CAD数据处理的任务 77 syncCtrl.Invoke(new FinishedProcessingDelegate(FileStandardization.TransMianByJava)); 78 } 79 myClientSocket.Send(Encoding.UTF8.GetBytes("我是牛魔王:处理结果是" + FileStandardization.resultJava)); 80 FileOperate.Log(SystemData.logPath, "我是牛魔王,文件处理完成:" + filePath); 81 } 82 else 83 { 84 myClientSocket.Send(Encoding.UTF8.GetBytes("我是牛魔王:文件不存在")); 85 } 86 } 87 else 88 { 89 FileOperate.Log(SystemData.logPath, "没有收到数据了"); 90 myClientSocket.Shutdown(SocketShutdown.Both); 91 myClientSocket.Close(); 92 break; 93 } 94 95 96 } 97 catch (Exception ex) 98 { 99 FileOperate.Log(SystemData.logPath,"文件处理异常:"+ex.Message); 100 myClientSocket.Shutdown(SocketShutdown.Both); 101 myClientSocket.Close(); 102 break; 103 } 104 } 105 } 106 107 }