Socket 编程经验谈

在刚刚完成的项目中遇到了些问题,化了很长的时间处理,都没有效果,但“有心栽花花不开,无心插柳柳成荫”,特总结下经验,同时谢谢提供无私帮助的redbb,lxcc,saucer等。

一个通讯的项目,一个winform托盘,一个windows service.
winform启动service,同时返回windows service的数据。
windows service负责与两台服务器通讯,并做逻辑处理。

问题一:线程
调试windows service可运行,不是调试状态就不运行
protected override void OnStart(string[] args)
{
Process CommProcess = Process.GetCurrentProcess();
CommProcess.PriorityClass=ProcessPriorityClass.RealTime;
XCOM_instance.clsXCOMComm_Start();
VIP_instance = new clsVIPComm();
}

其中
public void clsXCOMComm_Start()
{
thread_heart.Start();
thread_receive.Start();
thread_send.Start();
}
构照函数
public clsVIPComm()
{
Msg_Length = TCP_Msg_Length;
Initial.setds();
VIPComm_Start();
}

public void VIPComm_Start()
{
thread_send.Start();
thread_receive.Start();
}
线程几乎相同,就简单举个例子
Thread thread_receive = new Thread(new ThreadStart(TCPAsyncComm.receive));
public static void receive()
{
try
{
if (!sClient.Connected)
{
sClient.BeginConnect(new IPEndPoint(IPAddress.Parse("192.16.10.1"), 5001),new AsyncCallback(ConnectCallback),sClient);
socketEvent.WaitOne();
}
sClient.BeginReceive(buffer,0,buffer.Length,0,new AsyncCallback(ReceiveCallback),sClient);
socketEvent.WaitOne();
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
socketEvent.Set();
return;
}
}
分析:在receive处添加了断点,不明白为什么调试可以到达断点,而不加调试就到不了,显示的信息是线程中断。调试windows service是麻烦的事情,看以前的Console程序是可以运行的,又把windows service换到了winform,线程中断了,难道Console和winform结果还不一样吗?

解决:
protected override void OnStart(string[] args)
{
Process CommProcess = Process.GetCurrentProcess();
CommProcess.PriorityClass=ProcessPriorityClass.RealTime;
XCOM_instance.clsXCOMComm_Start();
VIP_instance = new clsVIPComm();
Console.ReadLine(); //就是这里
}
线程中断的原因就是上面那里,其实总觉得在windows service中Console和winform的东西都没有显示啊,应该没有什么用,却不知道问题就在这里啊!调了两个小时。

问题二:丢包
因为是和一个PLC(可编程逻辑控制器)通讯,在我看过的socket例子中,send函数中都要加上Thread.Sleep(100);因为不停一下,那相邻发送的两个信息就会合到一个包里,我做过测试,如果这个Sleep小于50,就会出现这种情况,那个PLC不知道怎么做的,通讯板发出的信号好像没有延迟,一次发8-10个,我收到的时候总会或多或少的丢失,约3%(特地做了个监控程序)。
分析:因为与之通讯的不是服务器或PC,没有办法调整参数,接收方面已经做异步委托处理了
public static void ReceiveCallback(IAsyncResult ar)
{
try
{
Socket sClient = (Socket)ar.AsyncState;
int bytesRead = sClient.EndReceive(ar);//,i=0;
if (bytesRead>0)
{
DelegateReceive delegatereceive = new DelegateReceive();
delegatereceive.receiveBytes = buffer;
Thread delegatereceivethread = new Thread(new ThreadStart(delegatereceive.DecodeMethod));
delegatereceivethread.Start();
sClient.BeginReceive(buffer,0,buffer.Length,0,new AsyncCallback(ReceiveCallback),sClient);
}
else
{
Debug.WriteLine("=======Finished==========");
socketEvent.Set();
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
socketEvent.Set();
}
}
不可能再优化了,此段程序耽误了大量时间,约2周。

解决:突一日,想起还没有做Release版,于是把Debug版换到R版,奇怪的现象出现了,数据没有丢失了,唉!这简单的一换,可......由此可见,R版效率比D版高,差点逼得我加CPU了。

问题三:响应
项目需要ms级反映,速度相当快,比如10ms送10个包,1s就是1000个包,windows service接收到后还要显示到外面托盘的winform上,两个应用程序域可以用remoting实现,我用的是UDP,道理是一样的,显示是通过datagrid实现的,在datagrid中加一列value,有一个ComboBox,选择哪个信号就显示哪个信号的值。程序几乎无法运行,只能运行几秒种,CPU利用率出奇的高,不用winform,直接在service中启动服务,CPU利用率5%。
分析:看样子是winform中的datagrid显示导致了CPU利用率的升高
解决:优化winform中的显示,只显示很少的东西,双击看细节,结果在100ms的时候利用率不超过20%,10ms太快了,CPU 80%,本实现了需求,看来把东西做到后台优势是很明显的,另外就是太频繁的显示不要做到winform上,windows可视化是好,但对资源的消耗也非常大。

抛砖引玉了。
---------------------------------------------------------------

分真多

流口水了
---------------------------------------------------------------

GZ,今天没回家。
---------------------------------------------------------------

牛!
---------------------------------------------------------------

学习
---------------------------------------------------------------

學習中...
---------------------------------------------------------------

牛xxx

学习一下,刚接触socket !
---------------------------------------------------------------

收~~!
---------------------------------------------------------------

存!
---------------------------------------------------------------

太惭愧了!没帮上什么!
---------------------------------------------------------------

正好我也关注.项目需要. 哎.
---------------------------------------------------------------

收藏学习,感谢:_)
---------------------------------------------------------------

学习先
---------------------------------------------------------------

有些经验值得借鉴,不过太多的异步处理会导致程序跑的更慢。因为异步处理总是使用系统线程池。
---------------------------------------------------------------

学习学习
---------------------------------------------------------------

好东西,经验之谈!!值得收藏!!
---------------------------------------------------------------

牛人,我喜欢
---------------------------------------------------------------

收藏了好好看
---------------------------------------------------------------

....只能说学习了
---------------------------------------------------------------

学习中
---------------------------------------------------------------

需要,学习,mark.
---------------------------------------------------------------

收藏
---------------------------------------------------------------

好东西,学习,再学习
up
---------------------------------------------------------------

真正的高手,收藏,我真要开发一个socket服务端,用windows service可以吗?希望楼主解释一下
---------------------------------------------------------------

学习.
---------------------------------------------------------------

接分。

---------------------------------------------------------------

好,收藏,


---------------------------------------------------------------

好,收藏
---------------------------------------------------------------

加入收藏了。

谢谢你的经验:)
---------------------------------------------------------------

强人啊
---------------------------------------------------------------

好,互相学习
---------------------------------------------------------------

学习
---------------------------------------------------------------

SOCKET太复杂了,学习中,顶,
---------------------------------------------------------------

收藏:)
---------------------------------------------------------------

厉害
---------------------------------------------------------------

up
---------------------------------------------------------------

希望楼主告知怎样在线程中通信,谢谢。我要向ui线程发送消息,以显示进度,该如何办?参数怎么传?
---------------------------------------------------------------

好文章,感谢楼主了。

顺便接点分!
---------------------------------------------------------------

学习
---------------------------------------------------------------

学习
---------------------------------------------------------------

学习,谢谢
---------------------------------------------------------------

mark
---------------------------------------------------------------

好想楼主再多说点,可以多学点
------------------------------------------------------------

Published At
Categories with Web编程
Tagged with
comments powered by Disqus