异步Socket

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Net.Sockets;
using  System.Threading;
using  System.Net;

namespace  AsyncSocket
{
    
public enum SocketState
    
{
        ssConnected,
        ssDisconnected,
        ssUnknown
    }


    
public interface ISocket
    
{
        
int SocketID get;set;}
        
int Connect(string host, int port, object tag);
        
int Disconnect(int socketID);
        
int SendMessage(int socketID, byte[] buffer);
    }


    
public abstract class TSocket : ISocket
    
{
        
public abstract int SocketID get;set;}

        
public virtual int Connect(string host, int port, object tag) return -1; }

        
public virtual int Disconnect(int socketID) return -1; }

        
public virtual int SendMessage(int socketID, byte[] buffer) return -1; }
    }


    
public class SocketVendor : TSocket
    
{
        
public event ConnectionEventHandler OnSocketConnected;
        
public event ConnectionEventHandler OnSocketDisconneted;
        
public event SocketReceivedEventHandler OnSocketReceived;

        
protected ManualResetEvent stopEvent;
        
protected AutoResetEvent dataReady;

        
protected Queue<byte[]> transmitQ;
        
protected Queue<byte[]> receivedQ;

        
protected ReaderWriterLock transmitLock;

        
protected Socket socket;

        
protected SocketState socketState = SocketState.ssUnknown;
        
public SocketState State get return socketState; } }

        
public bool Connected get return socket == null ? false : socket.Connected; } }

        
private static int currentSessionID;
        
protected int socketID;
        
public override int SocketID
        
{
            
get return socketID; }
            
set { socketID = value; }
        }


        
protected int timeout;
        
public int Timeout get return timeout; } }

        
public SocketVendor(int timeout)
        
{
            
this.timeout = timeout;

            stopEvent 
= new ManualResetEvent(false);
            dataReady 
= new AutoResetEvent(false);

            transmitQ 
= new Queue<byte[]>();
            receivedQ 
= new Queue<byte[]>();

            transmitLock 
= new ReaderWriterLock();

            currentSessionID
++;
            socketID 
= currentSessionID;
        }


        
public override int Connect(string host, int port, object tag)
        
{
            
if (Connected) return -1;

            stopEvent.Reset();

            IPHostEntry hostEntry 
= Dns.GetHostEntry(host);
            
if (hostEntry != null)
            
{
                IPEndPoint remoteEP 
= new IPEndPoint(hostEntry.AddressList[0], port);

                socket 
= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                
try
                
{
                    socket.Connect(remoteEP);
                    socketState 
= SocketState.ssConnected;
                    
if (OnSocketConnected != null)
                    
{
                        ConnectionEventArgs e 
= new ConnectionEventArgs(SocketID, Connected, State);
                        OnSocketConnected(
this, e);
                    }

                }

                
catch (Exception exx)
                
{
                    socketState 
= SocketState.ssDisconnected;
                    System.Diagnostics.Trace.WriteLine(
"============Exception Occured while doing the Socket Connection============ " + exx.Message);
                    
if (OnSocketConnected != null)
                    
{
                        ConnectionEventArgs e 
= new ConnectionEventArgs(SocketID, Connected, State);
                        OnSocketConnected(
this, e);
                    }


                    
return -1;
                }


                ThreadPool.QueueUserWorkItem(
new WaitCallback(ReceiveEntryPoint));
                ThreadPool.QueueUserWorkItem(
new WaitCallback(SendEntryPoint));

                
return SocketID;
            }

            
else
            
{
                
return -1;
            }

        }


        
public override int Disconnect(int socketID)
        
{
            
if (Connected)
            
{
                socketState 
= SocketState.ssDisconnected;
                stopEvent.Set();
                
if (socket != null)
                
{
                    socket.Disconnect(
false);
                }


                
if (OnSocketDisconneted != null)
                
{
                    ConnectionEventArgs e 
= new ConnectionEventArgs(socketID, Connected, State);
                    OnSocketDisconneted(
this, e);
                }


                
return socketID;
            }

            
else
            
{
                
return -1;
            }

        }


        
public override int SendMessage(int socketID, byte[] buffer)
        
{
            transmitLock.AcquireWriterLock(
-1);
            
try
            
{
                transmitQ.Enqueue(buffer);
            }

            
catch (Exception e)
            
{
                System.Diagnostics.Trace.WriteLine(
"============Exception Occured while doing the Socekt Send Message============ " + e.Message);
                
return -1;
            }

            
finally
            
{
                transmitLock.ReleaseWriterLock();
            }


            dataReady.Set();
            
return socketID;
        }


        
public int SendMessage(int socketID, string msg)
        
{
            
byte[] buffer = Encoding.Default.GetBytes(msg);
            
return SendMessage(socketID, buffer);
        }


        
private void ReceiveEntryPoint(object state)
        
{
            
try
            
{
                
while (true)
                
{
                    WaitHandle[] handles 
= new WaitHandle[1];
                    handles[
0= stopEvent;

                    
if (socket != null && Connected)
                    
{
                        
try
                        
{
                            SocketStateObject sso 
= new SocketStateObject(socket);
                            IAsyncResult iar 
= socket.BeginReceive(sso.Buffer, 0, SocketStateObject.BUFFER_SIZE, 0new AsyncCallback(AsyncReceiveCallback), sso);

                            
//if StopEvent Signaled, break
                            if (WaitHandle.WaitAny(handles) == 0break;
                        }

                        
catch { }
                    }

                }

            }

            
catch (Exception e)
            
{
                System.Diagnostics.Trace.WriteLine(
"============Exception Occured while doing the Receive Message from Socket============ " + e.Message);
            }

        }


        
private void AsyncReceiveCallback(IAsyncResult iar)
        
{
            SocketStateObject sso 
= (SocketStateObject)iar.AsyncState;
            Socket s 
= sso.WorkSocket;

            
try
            
{
                
if (s == null || !s.Connected) return;
                
int read = s.EndReceive(iar);
                
if (read > 0)
                
{
                    
try
                    
{
                        
if (OnSocketReceived != null)
                        
{
                            SocketReceivedEventArgs e 
= new SocketReceivedEventArgs(socketID, s.Connected, State, sso.Buffer);
                            OnSocketReceived(
this, e);
                        }

                    }

                    
catch (Exception exx)
                    
{
                        System.Diagnostics.Trace.WriteLine(
"============Exception Occured while Receive Callback Asynchronous============ " + exx.Message);
                    }


                    s.BeginReceive(sso.Buffer, 
0, SocketStateObject.BUFFER_SIZE, 0new AsyncCallback(AsyncReceiveCallback), sso);
                }

                
//else
                
//{
                
//    if (OnSocketDisconneted != null)
                
//    {
                
//        socketState = SocketState.ssDisconnected;
                
//        ConnectionEventArgs e = new ConnectionEventArgs(socketID, s.Connected, State);
                
//        OnSocketDisconneted(this, e);
                
//    }
                
//}
            }

            
catch (Exception exx)
            
{
                System.Diagnostics.Trace.WriteLine(
"============Exception Occured while Receive Callback Asynchronous============ " + exx.Message);
                
if (OnSocketDisconneted != null)
                
{
                    socketState 
= SocketState.ssDisconnected;
                    ConnectionEventArgs e 
= new ConnectionEventArgs(socketID, s.Connected, State);
                    OnSocketDisconneted(
this, e);
                }

            }

        }


        
private void SendEntryPoint(object state)
        
{
            
try
            
{
                Queue
<byte[]> workQ = new Queue<byte[]>();

                
while (true)
                
{
                    WaitHandle[] handles 
= new WaitHandle[2];
                    handles[
0= stopEvent;
                    handles[
1= dataReady;

                    
//if StopEvent Signaled, break
                    if (WaitHandle.WaitAny(handles) == 0break;
                    
else if (socket != null && Connected)
                    
{
                        transmitLock.AcquireWriterLock(
-1);
                        
try
                        
{
                            workQ.Clear();
                            
foreach (byte[] bytes in transmitQ) workQ.Enqueue(bytes);
                            transmitQ.Clear();
                        }

                        
catch { }
                        
finally
                        
{
                            transmitLock.ReleaseWriterLock();
                        }


                        
foreach (byte[] bytes in workQ)
                        
{
                            SocketStateObject sso 
= new SocketStateObject(socket);
                            socket.BeginSend(bytes, 
0, bytes.Length, SocketFlags.None, new AsyncCallback(AsyncSendCallback), sso);
                        }

                    }

                }

            }

            
catch (Exception e)
            
{
                System.Diagnostics.Trace.WriteLine(
"============Exception Occured while doing the Send Message============ " + e.Message);
            }

        }


        
private void AsyncSendCallback(IAsyncResult iar)
        
{
            SocketStateObject sso 
= (SocketStateObject)iar.AsyncState;
            Socket s 
= sso.WorkSocket;

            
try
            
{
                
if (s == null || !s.Connected) return;
                s.EndSend(iar);
            }

            
catch (Exception e)
            
{
                System.Diagnostics.Trace.WriteLine(
"============Exception Occured while Handling Send Callback Asynchronous============ " + e.Message);
            }

        }

    }


    
public class SocketStateObject
    
{
        
protected Socket workSocket;
        
protected StringBuilder items;
        
protected byte[] buffer;
        
protected bool completed;

        
public const int BUFFER_SIZE = 1024;

        
public SocketStateObject(Socket socket)
        
{
            workSocket 
= socket;
            buffer 
= new byte[BUFFER_SIZE];
            completed 
= false;
        }

        
/// <summary>
        
/// Gets the current Socket
        
/// </summary>

        public Socket WorkSocket get return workSocket; } }
        
/// <summary>
        
/// Gets or Sets the return message
        
/// </summary>

        public StringBuilder Items get return items; } set { items = value; } }
        
/// <summary>
        
/// Gets or Sets the return buffer
        
/// </summary>

        public byte[] Buffer get return buffer; } set { buffer = value; } }
        
/// <summary>
        
/// Gets or Sets the flag to indicate whether the current socket has completed or not
        
/// </summary>

        public bool Completed get return completed; } set { completed = value; } }
    }


    
public class ConnectionEventArgs : EventArgs
    
{
        
protected int socketID;
        
public int SocketID get return socketID; } }

        
protected bool connected;
        
public bool Connected get return connected; } }

        
protected SocketState socketState;
        
public SocketState State get return socketState; } }

        
public ConnectionEventArgs(int socketID, bool connected, SocketState socketState)
        
{
            
this.socketID = socketID;
            
this.connected = connected;
            
this.socketState = socketState;
        }

    }


    
public class SocketReceivedEventArgs : ConnectionEventArgs
    
{
        
protected byte[] buffer;
        
public byte[] Buffer get return buffer; } }

        
public SocketReceivedEventArgs(int socketID, bool connected, SocketState socketState, byte[] buffer)
            : 
base(socketID, connected, socketState)
        
{
            
this.buffer = buffer;
        }

    }


    
public delegate void ConnectionEventHandler(object sender, ConnectionEventArgs e);
    
public delegate void SocketReceivedEventHandler(object sender,SocketReceivedEventArgs e);
}

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值