李天平的博客


天道酬勤
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

异步Socket通信总结

Posted on 2005-12-03 00:42  李天平  阅读(7744)  评论(9编辑  收藏  举报

前面已经贴了Socket的基本编程要点和步骤,这里继续贴一下关于异步Socket通信的代码。

服务端(异步)

using System.Net ;

using System.Net.Sockets ;

using System.IO ;

using System.Text ;

using System.Threading ;

 

 

         public static ManualResetEvent allDone = new ManualResetEvent(false);     

         private Thread th;

         private bool listenerRun = true ;

         Socket listener;

         private const int MAX_SOCKET=10;

         protected override void Dispose( bool disposing )

         {

              try

              {

                   listenerRun = false ;

                   th.Abort ( ) ;

                   th = null ;

                   listener.Close();

              }

              catch { }             

         }

         //得到本机IP地址

         //得到本机IP地址

         public static IPAddress GetServerIP()

         {

              IPHostEntry ieh=Dns.GetHostByName(Dns.GetHostName());

              return ieh.AddressList[0];

         }

         //侦听方法

         private void Listen()

         {

              try

              {

                   int nPort=int.Parse(this.txtLocalPort.Text);

                   IPAddress ServerIp=GetServerIP();

                   IPEndPoint iep=new IPEndPoint(ServerIp,nPort);

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

             

                   listener.Bind(iep);

                   listener.Listen(10);

                   statusBar1.Panels[0].Text ="端口:"+this.txtLocalPort.Text+"正在监听......";

 

 

                   while(listenerRun)

                   {                          

                       allDone.Reset();

                       listener.BeginAccept(new AsyncCallback(AcceptCallback),listener);

                       allDone.WaitOne();                  

                   }

              }

              catch (System.Security.SecurityException )

              {

                   MessageBox.Show ("防火墙安全错误!","错误",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);

              }

         }

 

 

         //异步回调函数

         public void AcceptCallback(IAsyncResult ar)

         {            

              Socket listener = (Socket)ar.AsyncState;

              Socket client=listener.EndAccept(ar) ;

              allDone.Set();

              StateObject state = new StateObject();

              state.workSocket = client;

 

 

              //远端信息

              EndPoint tempRemoteEP = client.RemoteEndPoint;

              IPEndPoint tempRemoteIP = ( IPEndPoint )tempRemoteEP ;

              string rempip=tempRemoteIP.Address.ToString();

              string remoport=tempRemoteIP.Port.ToString();

              IPHostEntry host = Dns.GetHostByAddress(tempRemoteIP.Address ) ;

              string HostName = host.HostName;

              statusBar1.Panels[1].Text ="接受["+HostName+"] "+rempip+":"+remoport+"远程计算机正确连接!" ;

              this.listboxRemohost.Items.Add("["+HostName+"] "+rempip+":"+remoport);

 

 

              client.BeginReceive( state.buffer,0, StateObject.BufferSize, 0,

                   new AsyncCallback(readCallback), state); 

                      

         }

         //异步接收回调函数

        

        

         public void readCallback(IAsyncResult ar)

         {

              StateObject state = (StateObject) ar.AsyncState;

              Socket handler = state.workSocket;            

              int bytesRead = handler.EndReceive(ar);           

              if (bytesRead > 0)

              {

                   string strmsg=Encoding.ASCII.GetString(state.buffer,0,bytesRead);

                   state.sb.Append(strmsg);

                   string content = state.sb.ToString();

                  

                   //远端信息

                   EndPoint tempRemoteEP = handler.RemoteEndPoint;

                   IPEndPoint tempRemoteIP = ( IPEndPoint )tempRemoteEP ;

                   string rempip=tempRemoteIP.Address.ToString();

                   string remoport=tempRemoteIP.Port.ToString();

                   IPHostEntry host = Dns.GetHostByAddress(tempRemoteIP.Address ) ;

                   string HostName = host.HostName;

 

 

                   statusBar1.Panels[1].Text ="正在接收["+HostName+"] "+rempip+":"+remoport+"的信息..." ;

                   string time = DateTime.Now.ToString ();

                   listboxRecv.Items.Add("("+time+") "+HostName+"");

                  listboxRecv.Items.Add(strmsg) ;

                      

                   if(content.IndexOf("\x99\x99")> -1)

                   {

                       statusBar1.Panels[1].Text ="信息接收完毕!" ;

                       //////////////////////////////////////////////////

                       //接收到完整的信息

//                     MessageBox.Show("接收到:"+content);

                       string msg=poweryd.CodeParse(content);

                       Send(handler,msg);//异步发送

 

 

//                     Send(content);//用单独的socket发送

                   }

                   else

                   {

                       handler.BeginReceive(state.buffer,0,StateObject.BufferSize, 0,

                            new AsyncCallback(readCallback), state);

                   }

              }

         }

         //异步发送

         private void Send(Socket handler, String data)

         {            

              byte[] byteData = Encoding.ASCII.GetBytes(data);            

              handler.BeginSend(byteData, 0, byteData.Length, 0,

                   new AsyncCallback(SendCallback), handler);

//            handler.Send(byteData);

         }

         #region  //用单独的socket发送

         private void Send(string data)

         {            

//            string ip=this.txtRemoIP.Text;

//            string port=this.txtRemoport.Text;

//            IPAddress serverIp=IPAddress.Parse(ip);           

//            int serverPort=Convert.ToInt32(port);

//            IPEndPoint iep=new IPEndPoint(serverIp,serverPort);             

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

//            socket.Connect(iep);            

//            byte[] byteMessage=Encoding.ASCII.GetBytes(data);

//            socket.Send(byteMessage);

//            socket.Shutdown(SocketShutdown.Both);

//            socket.Close();            

         }

         #endregion

         //异步发送回调函数

         //异步发送回调函数

         private static void SendCallback(IAsyncResult ar)

         {

              try

              {                 

                   Socket handler = (Socket) ar.AsyncState;               

                   int bytesSent = handler.EndSend(ar);

                   MessageBox.Show("发送成功!");

 

 

                   handler.Shutdown(SocketShutdown.Both);

                   handler.Close();

 

 

              }

              catch (Exception ex)

              {

                   MessageBox.Show(ex.ToString());

              }

         }

         private void btnListen_Click(object sender, System.EventArgs e)

         {

              th = new Thread (new ThreadStart(Listen));//Listen过程来初始化线程实例      

              th.Start();//启动此线程

              this.btnListen.Enabled=false;            

         }

         private void btnClosenet_Click(object sender, System.EventArgs e)

         {

              try

              {

                   listenerRun = false ;

                   th.Abort ( ) ;

                   th = null ;                

                   listener.Close();

                   statusBar1.Panels[0].Text= "与客户端断开连接!";

                   statusBar1.Panels[1].Text= "";

              }

              catch

              {

                   MessageBox.Show("连接尚未建立,断开无效!","警告");    

              }       

         }

         private void btnExit_Click(object sender, System.EventArgs e)

         {

              try

              {

                   listenerRun = false ;

                   th.Abort ( ) ;

                   th = null ;                

                   listener.Close();

                   statusBar1.Panels[0].Text= "与客户端断开连接!";

                   statusBar1.Panels[1].Text= "";

              }

              catch(Exception ex)

              {

                   MessageBox.Show(ex.Message);

              }

              finally

              {

                   Application.Exit();

              }

 

 

         }

 

 

     //异步传递的状态对象

     public class StateObject

     {

         public Socket workSocket = null;

         public const int BufferSize = 1024;

         public byte[] buffer = new byte[BufferSize];

         public StringBuilder sb = new StringBuilder();

     }

 

 

客户端(同步发送并接收):

using System.Net ;

using System.Net.Sockets ;

using System.IO ;

using System.Text ;

using System.Threading ;

 

 

         Socket socket;

         int numbyte=1024;//一次接收到的字节数

         private void btnConnect_Click(object sender, System.EventArgs e)

         {

              try

              {

                   string ip=this.txtRemoIP.Text;

                   string port=this.txtRemoport.Text;

 

 

                   IPAddress serverIp=IPAddress.Parse(ip);           

                   int serverPort=Convert.ToInt32(port);

                   IPEndPoint iep=new IPEndPoint(serverIp,serverPort); 

                   IPHostEntry host = Dns.GetHostByAddress(iep.Address ) ;

                   string HostName = host.HostName;

             

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

                   socket.Connect(iep);

 

 

                   IPEndPoint tempRemoteIP=( IPEndPoint )socket.LocalEndPoint;

                   statusBar1.Panels[0].Text ="端口:"+tempRemoteIP.Port.ToString()+"正在监听......";          

                   statusBar1.Panels[1].Text ="与远程计算机["+HostName+"] "+ip+":"+port+"建立连接!" ;

              }

              catch

              {

                   statusBar1.Panels[0].Text = "无法连接到目标计算机!";

              }

              #region

//            byteMessage=Encoding.ASCII.GetBytes(textBox1.Text+"99");

//            socket.Send(byteMessage);

//            byte[] bytes = new byte[1024];

//            socket.Receive(bytes);

//            string str=Encoding.Default.GetString(bytes);

//            MessageBox.Show("接收到:"+str);

//            socket.Shutdown(SocketShutdown.Both);

//            socket.Close();

              #endregion

        

         }

         private void btnSend_Click(object sender, System.EventArgs e)

         {

              try

              {

                   statusBar1.Panels[1].Text ="正在发送信息!" ;

                   string message=this.txtsend.Text;

                   SendInfo(message);                       

              }                 

              catch //异常处理

              {

                   statusBar1.Panels[0].Text = "无法发送信息到目标计算机!";

              }

         }

         private void SendInfo(string message)

         {

              #region

//            string ip=this.txtip.Text;

//            string port=this.txtport.Text;

//

//            IPAddress serverIp=IPAddress.Parse(ip);           

//            int serverPort=Convert.ToInt32(port);

//            IPEndPoint iep=new IPEndPoint(serverIp,serverPort); 

//            byte[] byteMessage; 

//

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

//            socket.Connect(iep);

              #endregion

 

 

              byte[] byteMessage=Encoding.ASCII.GetBytes(message+"\x99\x99");

              socket.Send(byteMessage);

 

 

              //远端信息

              EndPoint tempRemoteEP = socket.RemoteEndPoint;

              IPEndPoint tempRemoteIP = ( IPEndPoint )tempRemoteEP ;

              string rempip=tempRemoteIP.Address.ToString();

              string remoport=tempRemoteIP.Port.ToString();

              IPHostEntry host = Dns.GetHostByAddress(tempRemoteIP.Address ) ;

              string HostName = host.HostName;

 

 

              //发送信息

              string time1 = DateTime.Now.ToString();

              listboxsend.Items.Add ("("+ time1 +") "+ HostName +":");

              listboxsend.Items.Add (message ) ;  

 

 

              //发送完了,直接接收

              StringBuilder sb = new StringBuilder();

              while(true)

              {

                   statusBar1.Panels[1].Text ="正在等待接收信息..." ;

                   byte[] bytes = new byte[numbyte];

                   int recvbytes=socket.Receive(bytes);

                   string strmsg=Encoding.Default.GetString(bytes);

                  

                   string time2 = DateTime.Now.ToString();

                   listboxRecv.Items.Add("("+time2+") "+HostName+"");

                   listboxRecv.Items.Add (strmsg) ;

                  

                   sb.Append(strmsg);

                   if(sb.ToString().IndexOf("\x99\x99")>-1)

                   {

                       break;

                   }

              }

              statusBar1.Panels[1].Text ="接收信息完毕!" ;

              //////////////////////////////////////

              //代码解码

              CodeParse(sb.ToString());

              //////////////////////////////////////

              socket.Shutdown(SocketShutdown.Both);

              socket.Close();

         }