惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
SegmentFault 最新的问题
J
Java Code Geeks
V
V2EX
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Hugging Face - Blog
Hugging Face - Blog
F
Fortinet All Blogs
aimingoo的专栏
aimingoo的专栏
B
Blog
A
About on SuperTechFans
有赞技术团队
有赞技术团队
月光博客
月光博客
Microsoft Azure Blog
Microsoft Azure Blog
阮一峰的网络日志
阮一峰的网络日志
腾讯CDC
美团技术团队
大猫的无限游戏
大猫的无限游戏
爱范儿
爱范儿
N
Netflix TechBlog - Medium
C
Check Point Blog
Recent Announcements
Recent Announcements
博客园 - Franky
博客园 - 叶小钗
T
Tailwind CSS Blog

博客园 - 清雷

湘江老厨聚餐 我的青春 今日感想 东莞一日游 HP MC/SG 双机安装心得 周末的狂想 汉字转拼音的例子 回忆大学 Asp.Net下的DataGrid的多层表头 设置窗体背景图片,并且让图片随着窗体的大小的调整而调整大小 VS无法调试智能设备程序的解决方案 VS.Net下的新的单元测试工具-TestDriven.NET 怀念我的大学(2) 显示主窗体前显示登陆窗口的完美解决方案 windows消息大全 在.NET 中使用WIN32 API的宝库 一个很好的C#题目 开发.NET CF 蓝牙的通信模块 怀念我的大学(1)
一个封装的异步Socket客户端
清雷 · 2005-09-09 · via 博客园 - 清雷

Posted on 2005-09-09 17:09  清雷  阅读(2499)  评论()    收藏  举报

   项目需要封装一个异步Socket客户端,现将代码写下来,请各位指点一下 :

using System;
using System.Collections;
using System.Configuration;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace Beijing.Traffic.Mobile.Net
{
    
/// <summary>
    
/// 智能手机端网络访问类
    
/// </summary>

    public class MobileClient
    
{
        
//服务器IP地址
        private string serverIP;
        
//服务器访问端口
        private string serverPort;
        
private Socket socket;
        
private byte [] buffer = new byte[256];
        
private StringBuilder receiveData = null;
        
private SocketEventArgs socketEventArgs = null

        
#region 事件
        
//连接完成事件
        public event EventHandler OnConnect;        
        
//接收完成事件 
        public event EventHandler OnReceivedFinshed;        
        
//发送数据成功
        public event EventHandler OnSendFinished;        
        
//产生异常时调用此事件
        public event EventHandler OnException;

        
#endregion
          

        
#region 构造函数

        
public MobileClient()
        
{    
            
this.serverIP = ConfigurationSettings.AppSettings["ServerIP"];
            
this.serverPort = ConfigurationSettings.AppSettings["ServerPort"];
            receiveData 
= new StringBuilder();            
        }

        
public MobileClient(string ip,string port)
        
{
            
this.serverIP = ip;
            
this.serverPort = port;
            receiveData 
= new StringBuilder();
            
        }
        
        
#endregion
    

        
private void UpdateEventMessage(string msg)
        
{
            
if( socketEventArgs == null)
            
{
                socketEventArgs 
= new SocketEventArgs();
                socketEventArgs.ServerIP 
= this.serverIP;
                socketEventArgs.ServerPort 
= this.serverPort;
            }

            socketEventArgs.Message 
= msg;

        }


        
/// <summary>
        
/// 处理异常的事件
        
/// </summary>
        
/// <param name="msg"></param>

        private void  HandlerException(string msg)
        
{
            
if(OnException != null)
            
{
                UpdateEventMessage(msg);                
                OnException(
this,socketEventArgs);

            }

            
else
            
{
                
throw new Exception("异常处理事件不能为空");
            }

        }


        
#region 连接远程服务器


        
/// <summary>
        
/// 异步连接远程服务器
        
/// </summary>
        
/// <returns></returns>

        public void Connect()
        
{
            
try
            
{
                
if( socket != null && socket.Connected )
                
{
                    socket.Shutdown( SocketShutdown.Both );
                    System.Threading.Thread.Sleep( 
10 );
                    socket.Close();
                }

                socket 
= new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );    

                IPEndPoint epServer 
= new IPEndPoint(IPAddress.Parse(serverIP),int.Parse(serverPort));
                
                socket.Blocking 
= false;                        
                socket.BeginConnect( epServer, 
new AsyncCallback(Connected),socket );
            }

            
catch(Exception ex)
            
{
                
this.Close();
                
this.HandlerException(ex.Message);
            }

        }


        
private void Connected( IAsyncResult ar )
        
{
            
try
            
{                
                Socket sock 
= (Socket)ar.AsyncState;            
                            
                
if( sock.Connected )
                
{
                    
if(OnConnect != null)
                    
{
                        
//连接成功事件                        
                        UpdateEventMessage("连接远程服务器成功");
                        OnConnect(
this,socketEventArgs);
                    }

                }

                
else
                
{                    
                    
//连接失败事件                            
                    this.HandlerException("连接远程服务器失败");
                    
                }

            }

            
catch(Exception ex)
            
{
                
this.Close();
                
this.HandlerException(ex.Message);
            }

        }
        
        
#endregion


        
#region 异步发送数据

        
public void Send(string msg)
        
{        
            
byte[] msgBytes = Encoding.ASCII.GetBytes(msg);
            Send(msgBytes);

        }


        
public void Send(byte [] msgBytes)
        
{
            
try
            
{
                
ifthis.socket == null || !this.socket.Connected )
                
{
                    
throw new Exception("远程服务器没有连接,请先连接");
                }

                
else
                
{
                    AsyncCallback sendData 
= new AsyncCallback(SendCallback);
                    
this.socket.BeginSend(msgBytes,0,msgBytes.Length,SocketFlags.None,sendData,socket);
                }

            }

            
catch(Exception ex)
            
{
                
this.Close();
                
this.HandlerException(ex.Message);
            }


        }



        
private  void SendCallback(IAsyncResult ar) 
        
{
            
try 
            
{                
                Socket client 
= (Socket) ar.AsyncState;                
                
int bytesSent = client.EndSend(ar);

                
if( bytesSent > 0)
                
{
                    
ifthis.OnSendFinished != null)
                    
{                        
                        UpdateEventMessage(
"发送数据成功");
                        OnSendFinished(
this,socketEventArgs);
                    }

                }

                
else
                
{                                
                    
this.HandlerException("发送数据失败");                
                }

                
            }
 
            
catch (Exception ex) 
            
{
                
this.Close();
                
this.HandlerException(ex.Message);
            }

        }



        
#endregion


        
#region 异步接受数据

        
public void Receive()
        
{
            
try
            
{
                
ifthis.socket == null || !this.socket.Connected )
                
{
                    
throw new Exception("远程服务器没有连接,请先连接");
                }

                
else
                
{
                    AsyncCallback recieveData 
= new AsyncCallback( OnReceiveData );
                    socket.BeginReceive( buffer, 
0, buffer.Length, SocketFlags.None, recieveData, socket );
                }

            }

            
catch( Exception ex )
            
{
                
this.Close();
                
this.HandlerException(ex.Message);
            }

        }



        
private void OnReceiveData(IAsyncResult ar)
        
{
            Socket sock 
= (Socket)ar.AsyncState;
            
try
            
{
                
int nBytesRec = sock.EndReceive( ar );
                
if( nBytesRec > 0 )
                
{
                    
//接受数据并保存
                    string sRecieved = Encoding.ASCII.GetString(buffer, 0, nBytesRec );
                    receiveData.Append(sRecieved);
                    Receive();
                }

                
else
                
{                    
                    sock.Shutdown( SocketShutdown.Both );
                    sock.Close();
                    
if(receiveData.Length != 0)
                    
{
                        
if(OnReceivedFinshed != null)
                        
{                        
                            UpdateEventMessage(
"接受数据成功");
                            OnReceivedFinshed(
this,socketEventArgs);
                        }

                    }

                    
else
                    
{                                                
                        
this.HandlerException("接受数据为空");                    
                    }

                }

            }

            
catch( Exception ex )
            
{
                
this.Close();
                
this.HandlerException(ex.Message);
            }

        }



        
#endregion


        
#region 接收到的数据
        
/// <summary>
        
/// 接收到的数据
        
/// </summary>

        public string ReceivedData
        
{
            
get
            
{
                
lock(this)
                
{
                    
return this.receiveData.ToString();
                }

            }

        }


        
#endregion


        
#region 关闭socket

        
public void Close()
        
{
            
try
            
{
                
if( socket != null && socket.Connected )
                
{
                    socket.Shutdown( SocketShutdown.Both );
                    System.Threading.Thread.Sleep( 
10 );
                    socket.Close();
                }

            }

            
catch(Exception ex)
            
{
                
this.HandlerException(ex.Message);
            }

        }


        
#endregion



    }

}

业务类在对此包装的socket进行访问时,由于是三个线程之间进行通讯,这个线程无法捕捉另一个线程产生的异常,所以通过信号量来通知是否有异常的产生: