如题,要简单一点的。
我自已写了一个,老是出现I/O冲突之类的。
我的应用环境是这样的,大概有40个客户端。和服务之间通信。
传输的数据量大概在0-2M之间,相当频繁。当然更大的数据也有(100M以上),不过很少。
传输的时候对可靠性要求非常高。
请问这个C/S该怎么设计?

解决方案 »

  1.   

    http://topic.csdn.net/u/20090520/11/9d9ba552-95b7-4bba-be09-04b15285cb6e.html
      

  2.   

    http://www.cnblogs.com/Silverlight_Team/archive/2009/03/13/1411136.html
    http://www.cnblogs.com/WCFGROUP/archive/2009/05/22/1304512.html
      

  3.   

    //Socket基本编程
    //服务端: 
    using System.Net; 
    using System.Net.Sockets; 
    using System.Text; 
    using System.Threading; 
    Thread mythread ; 
    Socket socket; // 清理所有正在使用的资源。 
    protected override void Dispose( bool disposing ) 

     try 
     {    
      socket.Close();//释放资源 
      mythread.Abort ( ) ;//中止线程 
     } 
     catch{ } 
     if( disposing ) 
     { 
      if (components != null)
      { 
       components.Dispose(); 
      } 
     } 
     base.Dispose( disposing ); 
    } public static IPAddress GetServerIP() 

     IPHostEntry ieh=Dns.GetHostByName(Dns.GetHostName()); 
     return ieh.AddressList[0]; 
    } private void BeginListen() 

     IPAddress ServerIp=GetServerIP(); 
     IPEndPoint iep=new IPEndPoint(ServerIp,8000); 
     socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); 
     byte[] byteMessage=new byte[100]; 
     this.label1.Text=iep.ToString(); 
     socket.Bind(iep); 
     // do 
     while(true) 
     { 
      try 
      { 
       socket.Listen(5); 
       Socket newSocket=socket.Accept(); 
       newSocket.Receive(byteMessage); 
       string sTime = DateTime.Now.ToShortTimeString ( ) ; 
       string msg=sTime+":"+"Message from:"; 
       msg+=newSocket.RemoteEndPoint.ToString()+Encoding.Default.GetString(byteMessage); 
       this.listBox1.Items.Add(msg); 
     } 
      catch(SocketException ex) 
      { 
       this.label1.Text+=ex.ToString(); 
      } 
     } // while(byteMessage!=null); 
    } //开始监听 
    private void button1_Click(object sender, System.EventArgs e) 

     try 
     { 
      mythread = new Thread(new ThreadStart(BeginListen)); 
      mythread.Start(); 
     } 
     catch(System.Exception er) 
     { 
      MessageBox.Show(er.Message,"完成",MessageBoxButtons.OK,MessageBoxIcon.Stop); 
     } 
    } //客户端: 
    using System.Net; 
    using System.Net.Sockets; 
    using System.Text; private void button1_Click(object sender, System.EventArgs e) 

     BeginSend(); 
    }private void BeginSend() 

     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 socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); 
     socket.Connect(iep); 
     byteMessage=Encoding.ASCII.GetBytes(textBox1.Text); 
     socket.Send(byteMessage); 
     socket.Shutdown(SocketShutdown.Both); 
     socket.Close(); 
    } //基于TCP协议的发送和接收端 
    //TCP协议的接收端 
    using System.Net.Sockets ; //使用到TcpListen类 
    using System.Threading ; //使用到线程 
    using System.IO ; //使用到StreamReader类 int port = 8000; //定义侦听端口号 
    private Thread thThreadRead; //创建线程,用以侦听端口号,接收信息 
    private TcpListener tlTcpListen; //侦听端口号 
    private bool blistener = true; //设定标示位,判断侦听状态 
    private NetworkStream nsStream; //创建接收的基本数据流 
    private StreamReader srRead; 
    private System.Windows.Forms.StatusBar statusBar1; 
    private System.Windows.Forms.Button button1; 
    private System.Windows.Forms.ListBox listBox1; //从网络基础数据流中读取数据 
    private TcpClient tcClient ; private void Listen ( ) 

     try 
     { 
      tlTcpListen = new TcpListener ( port ) ; //以8000端口号来初始化TcpListener实例 
      tlTcpListen.Start ( ) ; //开始监听 
      statusBar1.Text = "正在监听" ; 
      tcClient = tlTcpListen.AcceptTcpClient ( ) ; //通过TCP连接请求 
      nsStream = tcClient.GetStream ( ) ; //获取用以发送、接收数据的网络基础数据流 
      srRead=new StreamReader(nsStream);//以得到的网络基础数据流来初始化StreamReader实例 
      statusBar1.Text = "已经连接!"; 
      while( blistener ) //循环侦听 
      { 
       string sMessage = srRead.ReadLine();//从网络基础数据流中读取一行数据 
       if ( sMessage == "STOP" ) //判断是否为断开TCP连接控制码 
       { 
        tlTcpListen.Stop(); //关闭侦听 
        nsStream.Close(); //释放资源 
        srRead.Close(); 
        statusBar1.Text = "连接已经关闭!" ; 
        thThreadRead.Abort(); //中止线程 
        return; 
       } 
       string sTime = DateTime.Now.ToShortTimeString ( ) ; //获取接收数据时的时间 
       listBox1.Items.Add ( sTime + " " + sMessage ) ; 
      } 
     } 
     catch ( System.Security.SecurityException ) 
     { 
      MessageBox.Show ( "侦听失败!" , "错误" ) ; 
     } 
    } //开始监听 
    private void button1_Click(object sender, System.EventArgs e) 

     thThreadRead = new Thread ( new ThreadStart ( Listen ) ); 
     thThreadRead.Start();//启动线程 
     button1.Enabled=false; 
    } // 清理所有正在使用的资源。 
    protected override void Dispose( bool disposing ) 

     try 
     { 
      tlTcpListen.Stop(); //关闭侦听 
      nsStream.Close(); 
      srRead.Close();//释放资源 
      thThreadRead.Abort();//中止线程 
     } 
     catch{} 
     if( disposing ) 
     { 
      if (components != null) 
      { 
       components.Dispose(); 
      } 
     } 
     base.Dispose( disposing ); 
    } //TCP协议的发送端 
    using System.Net.Sockets; //使用到TcpListen类 
    using System.Threading; //使用到线程 
    using System.IO; //使用到StreamWriter类 
    using System.Net; //使用IPAddress类、IPHostEntry类等 private StreamWriter swWriter; //用以向网络基础数据流传送数据  
    private NetworkStream nsStream; //创建发送数据的网络基础数据流  
    private TcpClient tcpClient; 
    private System.Windows.Forms.Button button1; 
    private System.Windows.Forms.TextBox textBox1; 
    private System.Windows.Forms.Button button2; 
    private System.Windows.Forms.TextBox textBox2; 
    private System.Windows.Forms.StatusBar statusBar1; 
    private System.Windows.Forms.Label label1; 
    private System.Windows.Forms.Label label2; //通过它实现向远程主机提出TCP连接申请  
    private bool tcpConnect = false; //定义标识符,用以表示TCP连接是否建立 //连接  
    private void button1_Click(object sender, System.EventArgs e) 

     IPAddress ipRemote ; 
     try 
     { 
      ipRemote = IPAddress.Parse ( textBox1.Text ) ; 
     } 
     catch //判断给定的IP地址的合法性 
     { 
      MessageBox.Show ( "输入的IP地址不合法!" , "错误提示!" ) ; 
      return ; 
     } 
     IPHostEntry ipHost ; 
     try 
     { 
      ipHost = Dns.Resolve ( textBox1.Text ) ;  
     } 
     catch //判断IP地址对应主机是否在线 
     { 
      MessageBox.Show ("远程主机不在线!" , "错误提示!" ) ; 
      return ; 
     } 
     string sHostName = ipHost.HostName ; 
     try 
     { 
      TcpClient tcpClient = new TcpClient(sHostName,8000);//对远程主机的8000端口提出TCP连接申请 
      nsStream = tcpClient.GetStream();//通过申请,并获取传送数据的网络基础数据流   
      swWriter = new StreamWriter(nsStream);//使用获取的网络基础数据流来初始化StreamWriter实例 
      button1.Enabled = false ; 
      button2.Enabled = true ; 
      tcpConnect = true ; 
      statusBar1.Text = "已经连接!" ; 
     } 
     catch 
     { 
      MessageBox.Show ( "无法和远程主机8000端口建立连接!" , "错误提示!" ) ; 
      return ; 
     } 
    } //发送 
    private void button2_Click(object sender, System.EventArgs e) 

     if (textBox2.Text !="") 
     { 
      swWriter.WriteLine(textBox2.Text);//刷新当前数据流中的数据 
      swWriter.Flush(); 
     }
     else 
     { 
      MessageBox.Show("发送信息不能为空!","错误提示!"); 
     } 
    } // 清理所有正在使用的资源。 
    protected override void Dispose( bool disposing ) 

     if ( tcpConnect ) 
     { 
      swWriter.WriteLine ( "STOP" ) ; //发送控制码   
      swWriter.Flush (); //刷新当前数据流中的数据   
      nsStream.Close (); //清除资源 
      swWriter.Close (); 
     } 
     if( disposing ) 
     { 
      if (components != null) 
      { 
       components.Dispose(); 
      } 
     } 
     base.Dispose( disposing ); 

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/cfhacker007/archive/2008/07/04/2611762.aspx
      

  4.   

    我要的是异步,多线程tpc socket例子。
    同步多线程,异步我都做过。
    我第一次学的时候就是看的你这个例子.
      

  5.   

    MSDN里面的好东西都是En文的。难读。
    里面也只是一些具体函数的应用。
      

  6.   

    应该是多线程Socket的例子,和异步有何关系呢?
      

  7.   

    再问异步tcp socket有必要使用多线程吗?
      

  8.   

    监听类
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;namespace ProCTN.WebIM.SocketLibrary.Library
    {
        public class ListenSocket
        {
            private AcceptEventHandler onAccept = null;        public ListenSocket(string IP, int Port)
            {
                mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            
                try
                {
                    IPEndPoint ipe = new IPEndPoint(Dns.GetHostAddresses(IP)[0], Port);
                    mSocket.Bind(ipe);
                }
                catch{}
            }        /// <summary>
            /// 监听
            /// </summary>
            public void Listen(int backlog)
            {
                if (mSocket == null)
                    throw new ArgumentNullException("连接不存在");
                mSocket.Listen(backlog);
                mSocket.BeginAccept(new AsyncCallback(AcceptCallBack), null);
            }
            /// <summary>
            /// 监听
            /// </summary>
            /// <param name="ar"></param>
            private void AcceptCallBack(IAsyncResult ar)
            {
                Socket handler = mSocket.EndAccept(ar);
                handler.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 1000);
                ClientSocket NewSocket = new ClientSocket(handler,String.Empty);            
                //激发事件
                if (onAccept != null)
                    onAccept(NewSocket);
                //重新监听
                mSocket.BeginAccept(new AsyncCallback(AcceptCallBack), null);
            }        private Socket mSocket;
            /// <summary>
            /// 获取、设置连接对象
            /// </summary>
            public Socket LinkObject
            {
                get
                {
                    return mSocket;
                }
                set
                {
                    mSocket = value;
                }
            }
            /// <summary>
            /// 接受连接的事件
            /// </summary>
            public event AcceptEventHandler OnAccept
            {
                add
                {
                    onAccept += value;
                }
                remove
                {
                    onAccept -= value;
                }
            }
        }
    }
      

  9.   

    Client类using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;namespace ProCTN.WebIM.SocketLibrary.Library
    {
        public class ClientSocket
        {
            private StreamDataAcceptHandler onStreamData = null;
            private StringDataAcceptHandler onStringData = null;
            private AsySocketEventHandler onSended = null;
            private AsySocketEventHandler onSendTo = null;
            private AsySocketClosedEventHandler onClosed = null;        public ClientSocket(Socket linkObject,string userID)
            {
                mSocket = linkObject;
                ID = userID;
            }        /// <summary>
            /// 开始接受数据
            /// </summary>
            public void BeginAcceptData()
            {
                if (mSocket == null)
                    throw new ArgumentNullException("连接对象为空");
                StateObject state = new StateObject();
                state.workSocket = mSocket;
                mSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
            }
            /// <summary>
            /// 接收
            /// </summary>
            /// <param name="ar"></param>
            private void ReceiveCallback(IAsyncResult ar)
            {
                try
                {
                    StateObject state = ar.AsyncState as StateObject;
                    Socket s = state.workSocket;
                    //读取数据
                    int bytesRead = mSocket.EndReceive(ar);
                    if (bytesRead > 0)
                    {
                        state.sb.Append(UTF8Encoding.UTF8.GetString(state.buffer, 0, bytesRead));
                        string sb = state.sb.ToString();
                        if (sb.IndexOf("<policy-file-request/>") > -1)
                        {
                            //WEB Socket 安全沙箱
                            s.BeginSend(bytebuffer, 0, bytebuffer.Length, SocketFlags.None, new AsyncCallback(CloseSocket), s);
                        }
                        else
                        {
                            if (sb.Substring(sb.Length - 1, 1) == EndChar)
                            {
                                //接收完成
                                //激发事件
                                if (onStreamData != null)
                                    onStreamData(ID, UTF8Encoding.UTF8.GetBytes(sb));
                                if (onStringData != null)
                                    onStringData(ID, sb,this);
                                state = new StateObject();
                                state.workSocket = mSocket;
                            }
                            mSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
                        }
                    }
                    else
                    {
                        //Web Socket 刷新
                        if (onClosed != null)
                            onClosed(ID, String.Empty,this);
                    }
                }
                catch (SocketException se)
                {
                    if (onClosed != null)
                        onClosed(ID, se.Message, this);
                }
            }
            /// <summary>
            /// 安全沙箱注销Socket
            /// </summary>
            /// <param name="ar"></param>
            private void CloseSocket(IAsyncResult ar)
            {
                if (ar.IsCompleted)
                {
                    Socket workingsock = ar.AsyncState as Socket;
                    workingsock.Shutdown(SocketShutdown.Send);
                    workingsock.Close();
                }
            }        #region TCP        /// <summary>
            /// 发送二进制数据
            /// </summary>
            /// <param name="SendData"></param>
            public void ASend(byte[] SendData)
            {
                if (mSocket == null)
                    throw new ArgumentNullException("连接不存在");
                if (SendData == null)
                    return;
                mSocket.BeginSend(SendData, 0, SendData.Length, 0, new AsyncCallback(SendCallBack), mSocket);
            }
            /// <summary>
            /// 发送文本数据
            /// </summary>
            /// <param name="SendData"></param>
            public void ASend(string SendData)
            {
                if (SendData.Length == 0)
                    return;
                this.ASend(UTF8Encoding.UTF8.GetBytes(SendData));
            }
            /// <summary>
            /// 发送CallBack方法
            /// </summary>
            /// <param name="ar"></param>
            private void SendCallBack(IAsyncResult ar)
            {
                try
                {
                    mSocket.EndSend(ar);
                    //触发事件
                    if (onSended != null)
                        onSended(ID, "OK");
                }
                catch (SocketException se)
                {
                    if (onClosed != null)
                        onClosed(ID, se.Message,this);
                }
            }
            #endregion        #region UDP
            /// <summary>
            /// UDP发送二进制数据
            /// </summary>
            /// <param name="SendData"></param>
            /// <param name="EndPoint">目标端点</param>
            public void ASendTo(byte[] SendData, IPEndPoint EndPoint)
            {
                if (mSocket == null)
                    throw new ArgumentNullException("连接不存在");
                if (SendData == null)
                    return;
                mSocket.BeginSendTo(SendData, 0, SendData.Length, 0, EndPoint, new AsyncCallback(SendToCallBack), null);
            }
            /// <summary>
            /// UDP发送文本数据
            /// </summary>
            /// <param name="SendData"></param>
            /// <param name="EndPoint"></param>
            public void ASendTo(string SendData, IPEndPoint EndPoint)
            {
                if (SendData.Length == 0)
                    return;
                ASendTo(UTF8Encoding.UTF8.GetBytes(SendData), EndPoint);
            }        /// <summary>
            /// UDP 发送CallBack方法
            /// </summary>
            /// <param name="ar"></param>
            private void SendToCallBack(IAsyncResult ar)
            {
                try
                {
                    mSocket.EndSendTo(ar);                
                    if (onSendTo != null)
                        onSendTo(ID, "OK");
                }
                catch (SocketException se)
                {
                    if (onClosed != null)
                        onClosed(ID, se.Message,this);
                }
            }        #endregion        #region 事件
            /// <summary>
            /// 连接关闭的事件
            /// </summary>
            public event AsySocketClosedEventHandler OnClosed
            {
                add
                {
                    onClosed += value;
                }
                remove
                {
                    onClosed -= value;
                }
            }
            /// <summary>
            /// 接收二进制数据事件
            /// </summary>
            public event StreamDataAcceptHandler OnStreamDataAccept
            {
                add
                {
                    this.onStreamData += value;
                }
                remove
                {
                    this.onStreamData -= value;
                }
            }
            /// <summary>
            /// 接收文本数据事件
            /// </summary>
            public event StringDataAcceptHandler OnStringDataAccept
            {
                add
                {
                    onStringData += value;
                }
                remove
                {
                    onStringData -= value;
                }
            }
            /// <summary>
            /// 发送成功事件
            /// </summary>
            public event AsySocketEventHandler OnSended
            {
                add
                {
                    onSended += value;
                }
                remove
                {
                    onSended -= value;
                }
            }
            /// <summary>
            /// UTP发送成功事件
            /// </summary>
            public event AsySocketEventHandler OnSendTo
            {
                add
                {
                    onSendTo += value;
                }
                remove
                {
                    onSendTo -= value;
                }
            }
            #endregion        #region 公共属性
            private byte[] _bytebuffer;
            public byte[] bytebuffer
            {
                get
                {
                    return _bytebuffer;
                }
                set
                {
                    _bytebuffer = value;
                }
            }
            /// <summary>
            /// 消息的中止判断符
            /// </summary>
            public static string EndChar
            {
                get
                {
                    return ";";
                }
            }
            private string _ID;
            /// <summary>
            /// 用户ID
            /// </summary>
            public string ID
            {
                get
                {
                    return _ID;
                }
                set
                {
                    _ID = value;
                }
            }        private Socket mSocket;
            /// <summary>
            /// 获取、设置连接对象
            /// </summary>
            public Socket LinkObject
            {
                get
                {
                    return mSocket;
                }
                set
                {
                    mSocket = value;
                }
            }
            #endregion
        }
    }
      

  10.   

    最近刚写的,希望能帮上你的忙.
    服务器端:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;using System.Threading;
    using System.Net;
    using System.Net.Sockets;
    namespace AsyncTCPChatTool_Server
    {
        public partial class Form1 : Form
        {
            byte[] receiveBytes = new byte[1024];//用于存储接收到的数据
            delegate void AddString_del(string str);
            AddString_del addDel;//该代理用于向接收窗体添加数据
            delegate void DeleteString_del();
            DeleteString_del deleteDel;//该代理用于为发送窗体清除已经发送过的数据
            Socket handler;//成功链接的客户端套接字
            int maxConnectionNum = 10;//最大链接数
           
            public Form1()
            {
                InitializeComponent();
                addDel = new AddString_del(Add_String);
                deleteDel = new DeleteString_del(Delete_String);
            }        private void Form1_Load(object sender, EventArgs e)
            {
                Thread listenThread = new Thread(new ThreadStart(Listen));//监听线程启动
                listenThread .Start();
            }
           
            //开始监听
            private void Listen()
            {
                //获取IP地址,创建网络端点
                string HostName = Dns.GetHostName();
                IPAddress[] ipHostInfo = Dns.GetHostAddresses(HostName);            //网络端点
                IPEndPoint localEndPoint = new IPEndPoint(ipHostInfo[0], 82);            //创建监听套接字(服务端套接字)
                Socket listener = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);            //处理用户连接请求
                try
                {
                    listener.Bind(localEndPoint);   //绑定网络端口
                    listener.Listen(maxConnectionNum);//开始监听
                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);     
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }        //接受请求回调函数,并在该回调函数中调用接收数据
            public void AcceptCallback(IAsyncResult ar)
            {
                try
                {
                    Socket listener = (Socket)ar.AsyncState;//将返回的状态转换成为套接字(服务端套接字)
                    handler = listener.EndAccept(ar);//异步处理连接请求,创建新的客户端套接字处理远程通信
                    //开始异步接收数据
                    handler.BeginReceive(receiveBytes, 0, 1024, 0, 
                        new AsyncCallback(ReceiveCallback), handler);                          
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    handler.Shutdown(SocketShutdown.Receive);  
                }           
            }        private void Add_String(string str)//向接收窗体添加消息的方法
            {
                txtOutput.Text += str + "\r\n";
                //使对话窗口的滚动条一直停留在最下方
                this.txtOutput.SelectionStart = this.txtOutput.Text.Length;
                this.txtOutput.ScrollToCaret(); 
            }        private void Delete_String()//为发送窗体清除已经发送过的数据的方法
            {
                txtInput.Text = "";
            }
            //接收数据回调函数
            public void ReceiveCallback(IAsyncResult ar)
            {
                try
                {
                    string receiveMessage;//接收到的数据
                    Socket reader = (Socket)ar.AsyncState;//将传递过来的接收状态转换成为socket实例
                    int receiveNum = reader.EndReceive(ar);//结束挂起的接收操作,返回已读取的字节数
                    receiveMessage = "客户端" + "(" + handler.RemoteEndPoint.ToString() + "):" + "\r\n" 
                        + Encoding.UTF8.GetString(receiveBytes, 0, receiveNum);
                    txtOutput.Invoke(addDel, receiveMessage);
                    if (ar.IsCompleted)
                        //接收完毕,将异步接收重新挂起
                        handler.BeginReceive(receiveBytes, 0, 1024, 0, 
                            new AsyncCallback(ReceiveCallback), handler);
                }
                catch (SocketException sep)
                {
                    MessageBox.Show(sep .Message);
                    handler.Shutdown(SocketShutdown.Receive);             
                }    
            }        private void Send(String data)
            {    
                try
                {
                    byte[] sendBytes = System.Text.Encoding.UTF8 .GetBytes (data);//将字符串转换成字节序列
                    //开始向远端设备发送数据
                    handler.BeginSend(sendBytes, 0, sendBytes.Length,0,
                        new AsyncCallback(SendCallback), handler);
                }
                catch (SocketException sep)
                {
                    MessageBox.Show(sep.Message);
                    handler.Shutdown(SocketShutdown.Send);
                }
            }        //发送方法的回调函数
            private  void SendCallback(IAsyncResult ar)
            {
                try
                {
                    string sendMessage;//发送的数据
                    //从传递的状态中获取套接字,创建一个客户端套接字
                    Socket sender = (Socket)ar.AsyncState;                 
                    //结束异步数据传输操作,返回传输的字节数
                    int sendNum = sender.EndSend(ar);
                    sendMessage = "服务器:" + "\r\n" + txtInput .Text .Trim ();
                    txtOutput.Invoke(addDel, sendMessage);
                    txtInput.Invoke(deleteDel);
                }
                catch (SocketException sep)
                {
                    MessageBox.Show(sep.Message);
                    handler.Shutdown(SocketShutdown.Send);
                }
            }        private void btnSend_Click(object sender, EventArgs e)
            {
                if (txtInput.Text.Trim() != "")
                {
                    this.Send(txtInput.Text.Trim());//去掉发送数据首、尾的空字符,如回车、空格等
                }
                else
                {
                    MessageBox.Show("发送内容不能为空");
                }
            }        private void Form1_KeyDown(object sender, KeyEventArgs e)
            {
                if (e.Control && e.KeyCode == Keys.Enter)
                {
                    btnSend_Click(null, null);
                    //使发送窗口的光标一直停留在最上端
                    this.txtInput .SelectionStart = 0;
                    this.txtInput.ScrollToCaret(); 
                }
            }     
        }
    }
      

  11.   

    客户端:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;using System.Threading;
    using System.Net;
    using System.Net.Sockets;namespace AsyncTCPChatTool_Client
    {
        public partial class Form1 : Form
        {        byte[] receiveBytes = new byte[1024];//用于存储接收到的数据
            delegate void AddString_del(string str);
            AddString_del addDel;//该代理用于向接收窗体添加数据
            delegate void DeleteString_del();
            DeleteString_del deleteDel;//该代理用于为发送窗体清除已经发送过的数据
            Socket client;//客户端链接到服务器的套接字        public Form1()
            {
                InitializeComponent();
                addDel = new AddString_del(Add_String);
                deleteDel = new DeleteString_del(Delete_String);        
            }        private void Add_String(string str)//向接收窗体添加消息的方法
            {
                txtOutput.Text += str + "\r\n";
                //使对话窗口的滚动条一直停留在最下方
                this.txtOutput.SelectionStart = this.txtOutput.Text.Length;
                this.txtOutput.ScrollToCaret(); 
            }
            private void Delete_String()//为发送窗体清除已经发送过的数据的方法
            {
                txtInput.Text = "";
            }
            private void Form1_Load(object sender, EventArgs e)
            {
                Thread connectionThread = new Thread(new ThreadStart(Connect));//启动连接线程
                connectionThread.Start();
            }        public void Connect()
            {
                try
                {
                    //建立连接socket
                    Socket connectSocket = 
                        new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
                    //开始异步连接
                    connectSocket.BeginConnect(IPAddress.Parse("172.16.94.134"),82,
                        new AsyncCallback(ConnectCallback),connectSocket);                     
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }        private void ConnectCallback(IAsyncResult ar)
            {
                try
                {
                    //从传递的状态中获取套接字,创建一个客户端套接字
                    Socket myClient = (Socket)ar.AsyncState;
                    client = myClient;                //完成挂起的连接操作
                    client.EndConnect(ar);
                    //如果确实连接成功
                    if (client.RemoteEndPoint.ToString() != "RemoteEndPoint = “client.RemoteEndPoint”引发了“System.Net.Sockets.SocketException”类型的异常")
                    {
                        txtOutput.Invoke(addDel, "链接成功");
                        client.BeginReceive(receiveBytes, 0, 1024, 0,
                            new AsyncCallback(ReceiveCallback), client);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }        private void ReceiveCallback(IAsyncResult ar)
            {
                try
                {
                    string receiveMessage;//接收到的数据
                    Socket reader = (Socket)ar.AsyncState;
                    int receiveNum = reader.EndReceive(ar);
                    receiveMessage = "服务器:" + "\r\n"
                        + Encoding.UTF8.GetString(receiveBytes, 0, receiveNum);
                    txtOutput.Invoke(addDel, receiveMessage);
                    if (ar.IsCompleted)
                        //接收完成,将接收重新挂起
                        client.BeginReceive(receiveBytes, 0, 1024, 
                            SocketFlags.None, new AsyncCallback(ReceiveCallback), client);
                }
                catch (SocketException sep)
                {
                    MessageBox.Show(sep.Message);
                    client.Shutdown(SocketShutdown.Receive);
                }        }        private void btnSend_Click(object sender, EventArgs e)
            {
                if (txtInput.Text.Trim() != "")
                {
                    this.Send(txtInput.Text.Trim ());
                }
                else
                {
                    MessageBox.Show("发送内容不能为空");
                }
            }
            private void Send(string data)
            {
                try
                {
                    byte[] sendBytes = System.Text.Encoding.UTF8.GetBytes(data);
                    client.BeginSend(sendBytes, 0, sendBytes.Length, 0, 
                        new AsyncCallback(SendCallback), client);
                }
                catch (SocketException sep)
                {
                    MessageBox.Show(sep.Message);
                    client.Shutdown(SocketShutdown.Send);
                }
            }
            private void SendCallback(IAsyncResult ar)
            {
               
                try
                {
                    Socket sender = (Socket)ar.AsyncState;
                    string sendMessage;//发送的数据
                    int sendNum = sender.EndSend(ar);
                    sendMessage = "客户端" + "(" + client.LocalEndPoint.ToString() + "):" 
                        +"\r\n"+ txtInput.Text.Trim ();
                    txtOutput.Invoke(addDel, sendMessage);
                    txtInput.Invoke(deleteDel);
                }
                catch (SocketException sep)
                {
                    MessageBox.Show(sep.Message);
                    client.Shutdown(SocketShutdown.Send);
                }
            }        private void Form1_KeyDown(object sender, KeyEventArgs e)
            {
                if (e.Control && e.KeyCode == Keys.Enter)
                {
                    btnSend_Click(null, null);
                    this.txtInput.SelectionStart = 0;
                    this.txtInput.ScrollToCaret();
                }
            }
        }
    }
      

  12.   

    补充说明:
    这个程序服务器只支持连接一个客户端,但是要改成能支持多个客户端的连接很简单,加一个clientSocket[]就可以处理了.
    另外,这个还不支持上传文件,但是要改进也很容易.希望帮得上你的忙.
      

  13.   

    to:pjw216
    谢谢你提供的代码。
    我的程序服务端中,接和收的数据量有时候很大。一般是0-2M,时不时也有4-5M的数据要收发,也还有更大的(几十M),不过很少。
    而且客户端有时请求很频繁。不知道一般的异步能不能满足。
    而且传输的可靠性要求比较高的。
      

  14.   

    Socket异步就是多线程实现的,如果Socket异步+多线程,感觉就是放屁+脱库