C#另类重写

这个我不知道起个什么名字好。只是在写TcpClient的时候想重写了TcpClient   Client属性的Send方法,实际上就是Socket的Send方法了。因为我要以字符串交互数据,这个byte[]转换太麻烦了。

比如发送接收,在没有有重写的时候,发送和接受台麻烦了。

TcpClient client = listener.AcceptTcpClient();
                    
string buff = "成功建立连接\r\n";
byte[] b = System.Text.Encoding.Default.GetBytes(buff);
client.Client.Send(b);


NetworkStream myNetworkStream 
= client.GetStream();
 
byte[] bytes = new byte[1024];
int bytesRead = myNetworkStream.Read(bytes, 0, bytes.Length);
string getstr = Encoding.Default.GetString(bytes, 0, bytesRead);


如果定义一个类 MyTcpClient 继承自 TcpClient ,但是listener.AcceptTcpClient();的类型是TcpClient ,无法转换为MyTcpClient 。

MyTcpClient  client = (MyTcpClient )listener.AcceptTcpClient();是不可以的。

那么,如果我直接定义MyTcpClient  有Send方法
  /// <summary>
  /// 下发服务端信息
  /// </summary>
  /// <param name="msg"></param>
  public void Send(string msg)
  {
   byte[] b = System.Text.Encoding.Default.GetBytes(msg);
   Tcp.Client.Send(b);
  }
在这里是无法使用了。


另类一点的方法是聚合一下。
具体代码就是
    /// <summary>
    
/// 该类型为TcpClient
    
/// 值为new TcpListener().AcceptTcpClient()
    
/// </summary>
    public class MyTcpClient
    {
        TcpClient Tcp { 
getset; }
        NetworkStream myNetworkStream;

        
public bool Connected { get { return Tcp.Connected; } }

        
/// <summary>
        
/// 下发服务端信息
        
/// </summary>
        
/// <param name="msg"></param>
        public void Send(string msg)
        {
            
byte[] b = System.Text.Encoding.Default.GetBytes(msg);
            Tcp.Client.Send(b);
        }

        
public void Close()
        {
            myNetworkStream.Close();
            Tcp.Close();
        }

        
/// <summary>
        
/// 接收客户端数据
        
/// </summary>
        
/// <returns></returns>
        public string Received()
        {
            
byte[] bytes = new byte[1024];
            
int bytesRead = myNetworkStream.Read(bytes, 0, bytes.Length);
            
string getstr = Encoding.Default.GetString(bytes, 0, bytesRead);
            
return getstr;
        }

        MyTcpClient(TcpClient tcp)
        {
            Tcp 
= tcp;
            myNetworkStream 
= Tcp.GetStream();
        }

        
/// <summary>
        
/// 重载等于
        
/// </summary>
        
/// <param name="tcp"></param>
        
/// <returns></returns>
        public static implicit operator MyTcpClient(TcpClient tcp)
        {
            
return new MyTcpClient(tcp);
        }
    }

这样用MyTcpClient 替换掉TcpClient 是不是很另类,呵呵

使用的时候
            TcpListener listener = null;
            listener 
= new TcpListener(8009);
            listener.Start();


            
while (true)
            {
                MyTcpClient client 
= listener.AcceptTcpClient();
                client.Send(DateTime.Now.ToString() 
+ "成功建立连接\r\n");
                Console.Write(client.Received());

                client.Close();
            }
            listener.Stop();
这就简单太多了  : p

posted on 2007-12-14 14:06 BirdsHover 阅读(1882) 评论(11)  编辑 收藏 所属分类: Thinking about develop

评论

#1楼  2007-12-14 14:28 木野狐(Neil Chen)      

byte[] 本来是通用的通讯格式,这个继承把 Encoding 默认耦合了进去感觉完全没有必要。其实写一个 Helper 类就可以了,这样也能满足 DRY.

client.Send(SomeHelper.StringToBytes("skdfklsdf"));   回复  引用  查看    

#2楼  2007-12-14 16:23 Icebird      

如果是VS2008,扩展方法就可以很容易装饰一个类,使得其更容易使用   回复  引用  查看    

#3楼  2007-12-14 16:42 STS [未注册用户]

@木野狐(Neil Chen)
实际上直接用System.Text.Encoding.UTF8.GetBytes(string)就OK了.

---
但实际上不让DotNet的类库自动生成byte[],然后不断地抛弃, 并不是好方法.
在传统的编程方案中,buffer应该是预先分配好的. 而不是不断分配和不断抛弃.
所以最好的方法还是为一个请求分配一个buffer,使用GetBytes的另外一个重载的方法:
public virtual int GetBytes(string s, int charIndex, int charCount, byte[] bytes, int byteIndex);
例如:
int bufferlen=System.Text.Encoding.UTF8.GetBytes(message, 0, message.Length, buffer, 0);

这里需要注意buffer的容量和message的长度.
如果是存在message非常长的情况, 还需要把message分割多次,
循环地传递charIndex和charCount进去,然后发送.

  回复  引用  查看    

#4楼  2007-12-14 16:42 Anders06      

这个这个。。。LZ想用一种Encoding统一江湖?   回复  引用  查看    

#5楼  2007-12-14 16:43 STS [未注册用户]

哦. 打多了一个'不'

改成>> 但实际上让DotNet的类库自动生成byte[],然后不断地抛弃, 并不是好方法.
  回复  引用  查看    

#6楼 [楼主] 2007-12-14 16:45 BirdsHover      

@Icebird
扩展方法不错,看了下,刚注意到.net 3.x有个扩展方法,呵呵   回复  引用  查看    

#7楼 [楼主] 2007-12-14 16:46 BirdsHover      

@STS
汗,确实没注意buffer的问题   回复  引用  查看    

#8楼 [楼主] 2007-12-14 16:47 BirdsHover      

@Anders06
Encoding.Default实际是操作系统默认编码,中文操作系统一般是gb2312   回复  引用  查看    

#9楼  2007-12-14 19:48 Silent Void      

OO中有句话咋说的来的,优先使用聚合,而不是继承...   回复  引用  查看    

#10楼  2007-12-15 09:26 双鱼座      

汗...这是最简单的包装类(Wrapper),与帮助类(Helper)并行,与聚合无干,更谈不上另类。   回复  引用  查看    

#11楼  2007-12-15 11:32 re: C#另类重写 [未注册用户]

re: C#另类重写   回复  引用  查看    

导航

公告

网名: yurow birdshover
       PTX 无术 夕阳轨迹 等
本名: 谢平
籍贯: 江苏溧阳
位置: 上海
职业: C# & 打字
联系方式: 19999351(QQ)
 MSN.gif
silvelight 处理中文麻烦,wpf要装framework 3.5,都是麻烦的东西,还是先用flash吧 ==# 7-3 22:31
<2007年12月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

统计

与我联系

常用链接

留言簿(7)

我管理的小组

我参与的团队

我的标签

随笔分类(73)

文章分类(16)

收藏夹(1)

关注的博客

搜索

积分与排名

最新评论