转载一个很经典的--C# Socket TCP和UDP报文及端口测试工具的开发(提供源码)

转载地址:http://www.ltmonitor.com/blog/?p=285

因为自己经常做Socket开发,经常要调试各种协议,如TCP、UDP和SIP等协议,还要维护多个服务器端和客户端的通信、报文数据等,网上的TCP和UDP测试工具都是功能简单,用的不爽,特别是二进制报文的发送支持上还有压力测试上功能都不够,所以一直都想自己写一个。

Socket测试工具Socket测试工具 已下载 1178 次   Socket测试工具源码Socket测试工具源码 已下载 1286 次   

年底不忙了,终于写了一个,提供给大家使用,源码可以随便使用和修改,欢迎多提意见,让这个工具更易用,方便Socket编程开发人员。主要的亮点功能如下:

1.建立Socket测试服务器端和测试客户端,并向其他端发送或接受报文数据,支持自动发送和自动应答,支持UDP和TCP;

2.录入的IP地址和端口等参数数据进行本地XML序列化,下次自动打开。(这个是我需要的,不用每次都录入各种IP地址端口了);

3.接受或发送的报文数据,可以直接保存在日志文件当中,便于离线分析。

4.服务器端,可以查看接入的各个连接信息;

5.支持AscII和16进制的数据发送和接收显示,这样就支持了二进制的报文数据测试,只需要从生产环境中获取到报文,以16进制的字符串形式拷贝到工具中即可由工具转换成字节数组发送出。

6.可以用于编程开发,带有全套UI界面和socket源码、日志,稍加修改就直接用于自己的产品当中,省去了很多繁琐的工作,如界面监控、日志跟踪等操作。

7.可以建立多个客户端对同一服务器进行压力测试,在服务器端可以跟踪多个连接,并可跟踪每个连接的信息,可以终止某个连接,也可单独对某一个连接进行数据应答。

由于界面要同时支持TCP和UDP的数据通信,所以编写了两个接口IServer和IClient,便于屏蔽底层协议不同,造成发送和接收行为的不同,同时也将界面和通信剥离分开。

复制代码
public interface IServer
    {
        //初始化
        void Init(string serverIp, int port);
        //从服务器端给某个连接发送数据
        void Send(string connId, byte[] data, int length);
        //监听
        int Listen();
        //得到当前的连接
        List<IConnection> GetConnectionList();
        //Socket事件
        event ReceivedHandler OnDataReceived;
        event SocketErrorHandler OnSocketError;

        void Close();
    }
复制代码

 

为了保存参数数据,所以构造了一个SocketInfo类,对应客户端和服务器端,然后将这个集合序列化到XML文件中。每次打开程序后自动反序列化,读取数据,并生成界面。

序列化的代码如下:

复制代码
[Serializable]
    public class SocketInfo
    {
        public string Name { get; set; }
        //Server端或客户端类型
        public string Type { get; set; }
        //16进制格式或AscII
        public string Format { get; set; }

        public string ServerIp { get; set; }

        public int Port { get; set; }
        //TCP或UDP
        public string Protocol { get; set; }
        //报文数据
        public string Data {get;set;}
        //是否自动发送或接收数据
        public Boolean IsAuto {get;set;}

        public SocketInfo()
        {
            Format = "AscII";
            Protocol = "Tcp";
            Port = 8890;
            ServerIp = "127.0.0.1";
            Data = "请录入测试数据";
        }
    }
复制代码

 

复制代码
public class MySerializer
    {      

        public static void Serialize<T>(T value, string xmlFileName)
        {
            if (value == null)
            {
                return;
            }

            XmlSerializer serializer = new XmlSerializer(typeof(T));
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = new UnicodeEncoding(false, false);
            settings.Indent = false;
            settings.OmitXmlDeclaration = false;
            FileStream fs = new FileStream(xmlFileName, FileMode
                .OpenOrCreate);

            serializer.Serialize(fs, value);
            fs.Close();
        }

        public static T Deserialize<T>(string xmlFileName)
        {
            if (string.IsNullOrEmpty(xmlFileName))
            {
                return default(T);
            }

            XmlSerializer serializer = new XmlSerializer(typeof(T));
            //XmlSerializer serializer = new XmlSerializer(typeof(ArrayList));
            XmlReaderSettings settings = new XmlReaderSettings();
            //settings.

            FileStream fs = null;
            try
            {
                fs = new FileStream(xmlFileName, FileMode.Open);

                // Deserialize the content of the XML file to a Contact array 
                // utilizing XMLReader
                XmlReader reader = new XmlTextReader(fs);
                T contacts = (T)serializer.Deserialize(reader);

                return contacts;
            }
            catch (FileNotFoundException)
            {
                // Do nothing if the file does not exists
            }
            finally
            {
                if (fs != null) fs.Close();
            }

            return default(T);
        }
    }
复制代码

 

客户端的报文和服务器端的报文数据存放在Client.log和Server.log两个文件当中.主要是借助了Log4net的配置实现的. 这样做非常省事,通过log4net配置可以为每一个类配置一个独立的日志,达到了记录并跟踪数据的目的,避免自己再写文件的IO操作,以下是为Server类和Client类配置了Client.log和Server.log两个独立日志文件,方便跟踪。

复制代码
<log4net>
        <root>
            <level value="ALL" />
            <appender-ref ref="RollingFileAppender" />
        </root>
        <appender name="ClientLogFileAppender" type="log4net.Appender.RollingFileAppender">
            <param name="File" value="client.log"/>
            <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
            <appendToFile value="true" />
            <rollingStyle value="Size" />
            <maxSizeRollBackups value="3" />
            <maximumFileSize value="2MB" />
            <staticLogFileName value="true" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="记录时间:%date 日志:%message%newline" />
            </layout>
        </appender>

        <logger name="SocketTool.ClientForm">
            <level value="DEBUG" />
            <appender-ref ref="ClientLogFileAppender" />
        </logger>

        <appender name="ServerLogFileAppender" type="log4net.Appender.RollingFileAppender">
            <param name="File" value="server.log"/>
            <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
            <appendToFile value="true" />
            <rollingStyle value="Size" />
            <maxSizeRollBackups value="3" />
            <maximumFileSize value="2MB" />
            <staticLogFileName value="true" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="记录时间:%date 日志:%message%newline" />
            </layout>
        </appender>

        <logger name="SocketTool.ServerForm">
            <level value="DEBUG" />
            <appender-ref ref="ServerLogFileAppender" />
        </logger>
       
    </log4net>
复制代码
标签: Socket

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
好的,我来为您解答关于C#网络编程中Socket Tcp的异步循环接收客户端连接和信息的问题。 在Socket Tcp编程中,异步循环接收客户端连接和信息是一种常见的编程模式,可以有效地提高程序的并发性能和可靠性。下面是一个简单的实现方式: 首先,我们需要创建一个TcpListener对象,并绑定监听的IP地址和端口号: ```csharp TcpListener listener = new TcpListener(IPAddress.Any, 8888); listener.Start(); ``` 然后,我们可以使用异步方式接收客户端的连接请求: ```csharp listener.BeginAcceptTcpClient(new AsyncCallback(AcceptCallback), listener); ``` 其中,AcceptCallback是一个回调函数,用于处理客户端连接的请求,可以在该函数中创建一个新的TcpClient对象,并使用异步方式接收客户端发送的数据。 在AcceptCallback函数中,我们可以使用异步方式接收客户端发送的数据: ```csharp TcpClient client = listener.EndAcceptTcpClient(ar); NetworkStream stream = client.GetStream(); byte[] buffer = new byte[4096]; stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(ReadCallback), buffer); ``` 其中,ReadCallback是一个回调函数,用于处理客户端发送的数据,可以在该函数中解析并处理客户端发送的数据。 最后,在ReadCallback函数中,我们可以使用异步方式持续接收客户端发送的数据: ```csharp stream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(ReadCallback), buffer); ``` 以上就是使用异步循环接收客户端连接和信息的基本实现方式。需要注意的是,在实现过程中,我们需要考虑多线程安全和异常处理等问题,以确保程序的稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值