深入探索Socket

       现在正在给东风汽车厂做一个项目,其实是在所有的检测设备与上游系统间加入一个中间处理系统,冲当一个调度者的角色,通讯手段使用Socket。与一般项目的不同点在于这是一个中间系统,我们无法在上下游系统中加入我们自己的代码,却要能了解全局的情况,从技术的角度看来是有所难度的。然而不幸的是,我需要来面对这个困难。

       伯克利的Socket想必是每个程序员都对它是不陌生,Socket把复杂的网络协议简单化,使得网络编程尽可能的简单,所以Socket的成功也使得伯克利分校名满天下。但是Socket真的像我们想像的那么简单么?

1.Buffer管理

       对于要实现高性能的Socket,首要问题是对数据接收和发送处理。一般网上和MSDN介绍的应用都是非常简单的,把数据转byte[]后进行发送。但在实际应用中接收和发送数据是非常频繁的,这样会导致大量的byte[]构建和消除;对于这种开销如果在秒处理几百或上千问题不大,但如果在上万的情况就比较明显了。因此要把性能提升上去就要涉及到Buffer Pool。缓冲池也没有什么复杂的地方,其实就是对一Queue进行操作,不过需要注要的一点,要保证各线程获取和释放Buffer时的安全性。

2.心跳扫描

      客户端Socket连接服务端Socket,当客户端突然断开连接时,这条连接在服务端就永远存在了,而且所有属性与正常连接一样。这样就无法通过Connected属性来关闭套接字。网络上解决办法就是使用心跳包来解决这种网络故障。这种方法的一个缺点在于服务端、客户端都需要编写代码才能实现。所以在这个系统中心跳包的解决方案就行不通了。所以我们必需另辟蹊径,我在网上查阅了许多资料后发现了如下图片:

tcpclose

在Server端我们可以看到,当连接建立时,其状态是ESTABLISHED,之客户端发送FIN告知服务端准备关闭连接,服务端收到后发送ACK,此时服务端的状态为CLOSE-WAIT,然后服务端发送FIN给客户端,服务端的连接状态改为LAST-ACK,等待客户端发送ACK,当客户发送了ACK后,服务端连接状态改为CLOSED。如果客户端突然断线时,你用netstat -n命令查看连接状态,你会发现服务端的连接状态跳到了CLOSE-WAIT,这个发现让我欣喜若狂,我可以利用它干掉套接字了。那么这时的问题就是如何在程序中调用netstat -n命令。没有想到的是,国内的网站居然查不到,最后在国外的网站上才查到了。代码如下: 

Process pro = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo("netstat");
startInfo.Arguments = "-n";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.CreateNoWindow = true;
pro.StartInfo = startInfo;
pro.Start();
StreamReader sr = pro.StandardOutput;
string info = sr.ReadToEnd();

    info里就是我们想要的东西。然后你通过筛选出你想要的内容,然后就可干掉Socket了。

To be continue……

posted @ 2011-10-20 17:16  晓炜  阅读(397)  评论(1编辑  收藏  举报