异步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地址
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();
}
Contributors: FHL