异步Socket通信总结

本文介绍了一个使用 C# 实现的 Socket 异步通信示例,包括服务端的异步监听、接收及发送数据流程,以及客户端的同步发送与接收实现。详细展示了如何通过 Socket 进行网络通信,并处理远端主机的信息。

 

服务端(异步)

using System.Net ;
using System.Net.Sockets ;
using System.IO ;
using System.Text ;
using System.Threading ;
 
 
        publicstatic ManualResetEvent allDone = new ManualResetEvent(false);     
        private Thread th;
        privatebool listenerRun = true ;
        Socket listener;
        privateconstint MAX_SOCKET=10;
        protectedoverridevoid Dispose( bool disposing )
        {
            try
            {
                listenerRun = false ;
                th.Abort ( ) ;
                th = null ;
                listener.Close();
            }
            catch { }             
        }
         //得到本机IP地址
         //得到本机IP地址
        publicstatic IPAddress GetServerIP()
        {
            IPHostEntry ieh=Dns.GetHostByName(Dns.GetHostName());
            return ieh.AddressList[0];
        }
        //侦听方法
        privatevoid 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);
            }
        }
 
 
        //异步回调函数
        publicvoid 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);
                     
        }
        //异步接收回调函数
        
        
        publicvoid 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);
                }
            }
        }
        //异步发送
        privatevoid 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发送
        privatevoid 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
         //异步发送回调函数
         //异步发送回调函数
        privatestaticvoid 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());
            }
        }
        privatevoid btnListen_Click(object sender, System.EventArgs e)
        {
            th = new Thread (new ThreadStart(Listen));//Listen过程来初始化线程实例        
            th.Start();//启动此线程
            this.btnListen.Enabled=false;         
        }
        privatevoid 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("连接尚未建立,断开无效!","警告");    
            }        
        }
        privatevoid 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();
            }
 
 
        }
 
 
    //异步传递的状态对象
    publicclass StateObject
    {
        public Socket workSocket = null;
        publicconstint BufferSize = 1024;
        publicbyte[] buffer = newbyte[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;//一次接收到的字节数
        privatevoid 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
         
        }
        privatevoid btnSend_Click(object sender, System.EventArgs e)
        {
            try
            {
                statusBar1.Panels[1].Text ="正在发送信息!" ;
                string message=this.txtsend.Text;
                SendInfo(message);                    
            }              
            catch//异常处理
            {
                statusBar1.Panels[0].Text = "无法发送信息到目标计算机!";
            }
        }
        privatevoid 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 = newbyte[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();
        }
         
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值