C#,Socket TCP编程,客户端向服务器端发送连接之后,服务器端回了信息,建立连接之后,服务器端还要发送数据给客户端,客户端要写什么样的代码来接收服务器端的数据.这些数据是服务器端不定时发送回的.

解决方案 »

  1.   


    一. Serverusing System;
    using System.Threading; // Sleeping
    using System.Net; // Used to local machine info
    using System.Net.Sockets; // Socket namespace
    using System.Collections; // Access to the Array listnamespace ChatServer
    {
    /// <summary>
    /// Main class from which all objects are created
    /// </summary>
    class AppMain
    {
    // Attributes
    private ArrayList m_aryClients = new ArrayList(); // List of Client Connections
    /// <summary>
    /// Application starts here. Create an instance of this class and use it
    /// as the main object.
    /// </summary>
    /// <param name="args"></param>
    static void Main(string[] args)
    {
    AppMain app = new AppMain();
    // Welcome and Start listening
    Console.WriteLine( "*** Chat Server Started {0} *** ", DateTime.Now.ToString( "G" ) ); //
    // Method 2 
    //
    const int nPortListen = 399;
    // Determine the IPAddress of this machine
    IPAddress [] aryLocalAddr = null;
    String strHostName = "";
    try
    {
    // NOTE: DNS lookups are nice and all but quite time consuming.
    strHostName = Dns.GetHostName();
    IPHostEntry ipEntry = Dns.GetHostByName( strHostName );
    aryLocalAddr = ipEntry.AddressList;
    }
    catch( Exception ex )
    {
    Console.WriteLine ("Error trying to get local address {0} ", ex.Message );
    }

    // Verify we got an IP address. Tell the user if we did
    if( aryLocalAddr == null || aryLocalAddr.Length < 1 )
    {
    Console.WriteLine( "Unable to get local address" );
    return;
    }
    Console.WriteLine( "Listening on : [{0}] {1}:{2}", strHostName, aryLocalAddr[0], nPortListen ); // Create the listener socket in this machines IP address
    Socket listener = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
    listener.Bind( new IPEndPoint( aryLocalAddr[0], 399 ) );
    //listener.Bind( new IPEndPoint( IPAddress.Loopback, 399 ) ); // For use with localhost 127.0.0.1
    listener.Listen( 10 ); // Setup a callback to be notified of connection requests
    listener.BeginAccept( new AsyncCallback( app.OnConnectRequest ), listener ); Console.WriteLine ("Press Enter to exit" );
    Console.ReadLine();
    Console.WriteLine ("OK that does it! Screw you guys I'm going home..." ); // Clean up before we go home
    listener.Close();
    GC.Collect();
    GC.WaitForPendingFinalizers();
    }
    /// <summary>
    /// Callback used when a client requests a connection. 
    /// Accpet the connection, adding it to our list and setup to 
    /// accept more connections.
    /// </summary>
    /// <param name="ar"></param>
    public void OnConnectRequest( IAsyncResult ar )
    {
    Socket listener = (Socket)ar.AsyncState;
    NewConnection( listener.EndAccept( ar ) );
    listener.BeginAccept( new AsyncCallback( OnConnectRequest ), listener );
    } /// <summary>
    /// Add the given connection to our list of clients
    /// Note we have a new friend
    /// Send a welcome to the new client
    /// Setup a callback to recieve data
    /// </summary>
    /// <param name="sockClient">Connection to keep</param>
    //public void NewConnection( TcpListener listener )
    public void NewConnection( Socket sockClient )
    {
    // Program blocks on Accept() until a client connects.
    //SocketChatClient client = new SocketChatClient( listener.AcceptSocket() );
    SocketChatClient client = new SocketChatClient( sockClient );
    m_aryClients.Add( client );
    Console.WriteLine( "Client {0}, joined", client.Sock.RemoteEndPoint );
     
    // Get current date and time.
    DateTime now = DateTime.Now;
    String strDateLine = "Welcome " + now.ToString("G") + "\n\r"; // Convert to byte array and send.
    Byte[] byteDateLine = System.Text.Encoding.ASCII.GetBytes( strDateLine.ToCharArray() );
    client.Sock.Send( byteDateLine, byteDateLine.Length, 0 ); client.SetupRecieveCallback( this );
    } /// <summary>
    /// Get the new data and send it out to all other connections. 
    /// Note: If not data was recieved the connection has probably 
    /// died.
    /// </summary>
    /// <param name="ar"></param>
    public void OnRecievedData( IAsyncResult ar )
    {
    SocketChatClient client = (SocketChatClient)ar.AsyncState;
    byte [] aryRet = client.GetRecievedData( ar ); // If no data was recieved then the connection is probably dead
    if( aryRet.Length < 1 )
    {
    Console.WriteLine( "Client {0}, disconnected", client.Sock.RemoteEndPoint );
    client.Sock.Close();
    m_aryClients.Remove( client );      
    return;
    } // Send the recieved data to all clients (including sender for echo)
    foreach( SocketChatClient clientSend in m_aryClients )
    {
    try
    {
    clientSend.Sock.Send( aryRet );
    }
    catch
    {
    // If the send fails the close the connection
    Console.WriteLine( "Send to client {0} failed", client.Sock.RemoteEndPoint );
    clientSend.Sock.Close();
    m_aryClients.Remove( client );
    return;
    }
    }
    client.SetupRecieveCallback( this );
    }
    } /// <summary>
    /// Class holding information and buffers for the Client socket connection
    /// </summary>
    internal class SocketChatClient
    {
    private Socket m_sock; // Connection to the client
    private byte[] m_byBuff = new byte[50]; // Receive data buffer
    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="sock">client socket conneciton this object represents</param>
    public SocketChatClient( Socket sock )
    {
    m_sock = sock;
    } // Readonly access
    public Socket Sock
    {
    get{ return m_sock; }
    } /// <summary>
    /// Setup the callback for recieved data and loss of conneciton
    /// </summary>
    /// <param name="app"></param>
    public void SetupRecieveCallback( AppMain app )
    {
    try
    {
    AsyncCallback recieveData = new AsyncCallback(app.OnRecievedData);
    m_sock.BeginReceive( m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData, this );
    }
    catch( Exception ex )
    {
    Console.WriteLine( "Recieve callback setup failed! {0}", ex.Message );
    }
    } /// <summary>
    /// Data has been recieved so we shall put it in an array and
    /// return it.
    /// </summary>
    /// <param name="ar"></param>
    /// <returns>Array of bytes containing the received data</returns>
    public byte [] GetRecievedData( IAsyncResult ar )
    {
                int nBytesRec = 0;
    try
    {
    nBytesRec = m_sock.EndReceive( ar );
    }
    catch{}
    byte [] byReturn = new byte[nBytesRec];
    Array.Copy( m_byBuff, byReturn, nBytesRec );

    /*
    // Check for any remaining data and display it
    // This will improve performance for large packets 
    // but adds nothing to readability and is not essential
    int nToBeRead = m_sock.Available;
    if( nToBeRead > 0 )
    {
    byte [] byData = new byte[nToBeRead];
    m_sock.Receive( byData );
    // Append byData to byReturn here
    }
    */
    return byReturn;
    }
    }
    }
      

  2.   

    二.client
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;
    using System.Net; // Endpoint
    using System.Net.Sockets; // Socket namespace
    using System.Text; delegate void AddMessage( string sNewMessage );
    namespace ChatClient
    {
    public class FormMain : System.Windows.Forms.Form
    {
    // My Attributes
    private Socket m_sock; // Server connection
    private byte [] m_byBuff = new byte[256]; // Recieved data buffer
    private event AddMessage m_AddMessage; // Add Message Event handler for Form // Wizard generated code
    private System.Windows.Forms.Button m_btnConnect;
    private System.Windows.Forms.TextBox m_tbServerAddress;
    private System.Windows.Forms.ListBox m_lbRecievedData;
    private System.Windows.Forms.TextBox m_tbMessage;
    private System.Windows.Forms.Button m_btnSend;
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.Container components = null; public FormMain()
    { InitializeComponent();
    m_AddMessage = new AddMessage( OnAddMessage );
    } protected override void Dispose( bool disposing )
    {
    if( disposing )
    {
    if (components != null) 
    {
    components.Dispose();
    }
    }
    base.Dispose( disposing );
    } #region Windows Form Designer generated code
    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
    this.m_tbServerAddress = new System.Windows.Forms.TextBox();
    this.m_tbMessage = new System.Windows.Forms.TextBox();
    this.m_btnConnect = new System.Windows.Forms.Button();
    this.m_lbRecievedData = new System.Windows.Forms.ListBox();
    this.m_btnSend = new System.Windows.Forms.Button();
    this.SuspendLayout();
    // 
    // m_tbServerAddress
    // 
    this.m_tbServerAddress.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
    | System.Windows.Forms.AnchorStyles.Right);
    this.m_tbServerAddress.Location = new System.Drawing.Point(8, 8);
    this.m_tbServerAddress.Name = "m_tbServerAddress";
    this.m_tbServerAddress.Size = new System.Drawing.Size(204, 20);
    this.m_tbServerAddress.TabIndex = 1;
    this.m_tbServerAddress.Text = "192.168.0.8";
    // 
    // m_tbMessage
    // 
    this.m_tbMessage.Anchor = ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
    | System.Windows.Forms.AnchorStyles.Right);
    this.m_tbMessage.Location = new System.Drawing.Point(8, 37);
    this.m_tbMessage.Name = "m_tbMessage";
    this.m_tbMessage.Size = new System.Drawing.Size(205, 20);
    this.m_tbMessage.TabIndex = 3;
    this.m_tbMessage.Text = "";
    // 
    // m_btnConnect
    // 
    this.m_btnConnect.Anchor = (System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right);
    this.m_btnConnect.Location = new System.Drawing.Point(228, 8);
    this.m_btnConnect.Name = "m_btnConnect";
    this.m_btnConnect.TabIndex = 0;
    this.m_btnConnect.Text = "Connect";
    this.m_btnConnect.Click += new System.EventHandler(this.m_btnConnect_Click);
    // 
    // m_lbRecievedData
    // 
    this.m_lbRecievedData.Anchor = (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
    | System.Windows.Forms.AnchorStyles.Left) 
    | System.Windows.Forms.AnchorStyles.Right);
    this.m_lbRecievedData.IntegralHeight = false;
    this.m_lbRecievedData.Location = new System.Drawing.Point(0, 66);
    this.m_lbRecievedData.Name = "m_lbRecievedData";
    this.m_lbRecievedData.Size = new System.Drawing.Size(311, 220);
    this.m_lbRecievedData.TabIndex = 2;
    // 
    // m_btnSend
    // 
    this.m_btnSend.Anchor = (System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right);
    this.m_btnSend.Location = new System.Drawing.Point(228, 36);
    this.m_btnSend.Name = "m_btnSend";
    this.m_btnSend.TabIndex = 4;
    this.m_btnSend.Text = "Send";
    this.m_btnSend.Click += new System.EventHandler(this.m_btnSend_Click);
    // 
    // FormMain
    // 
    this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
    this.ClientSize = new System.Drawing.Size(312, 287);
    this.Controls.AddRange(new System.Windows.Forms.Control[] {
      this.m_btnSend,
      this.m_tbMessage,
      this.m_lbRecievedData,
      this.m_tbServerAddress,
      this.m_btnConnect});
    this.Name = "FormMain";
    this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
    this.Text = "Form1";
    this.Closing += new System.ComponentModel.CancelEventHandler(this.FormMain_Closing);
    this.ResumeLayout(false); }
    #endregion /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main() 
    {
    Application.Run(new FormMain());
    } /// <summary>
    /// Connect button pressed. Attempt a connection to the server and 
    /// setup Recieved data callback
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void m_btnConnect_Click(object sender, System.EventArgs e)
    {
    Cursor cursor = Cursor.Current;
    Cursor.Current = Cursors.WaitCursor;
    try
    {
    // Close the socket if it is still open
    if( m_sock != null && m_sock.Connected )
    {
    m_sock.Shutdown( SocketShutdown.Both );
    System.Threading.Thread.Sleep( 10 );
    m_sock.Close();
    } // Create the socket object
    m_sock = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); // Define the Server address and port
    IPEndPoint epServer = new IPEndPoint(  IPAddress.Parse( m_tbServerAddress.Text ), 399 ); // Connect to the server blocking method and setup callback for recieved data
    // m_sock.Connect( epServer );
    // SetupRecieveCallback( m_sock );

    // Connect to server non-Blocking method
    m_sock.Blocking = false;
    AsyncCallback onconnect = new AsyncCallback( OnConnect );
    m_sock.BeginConnect( epServer, onconnect, m_sock );
    }
    catch( Exception ex )
    {
    MessageBox.Show( this, ex.Message, "Server Connect failed!" );
    }
    Cursor.Current = cursor;
    } public void OnConnect( IAsyncResult ar )
    {
    // Socket was the passed in object
    Socket sock = (Socket)ar.AsyncState; // Check if we were sucessfull
    try
    {
    //sock.EndConnect( ar );
    if( sock.Connected )
    SetupRecieveCallback( sock );
    else
    MessageBox.Show( this, "Unable to connect to remote machine", "Connect Failed!" );
    }
    catch( Exception ex )
    {
    MessageBox.Show( this, ex.Message, "Unusual error during Connect!" );
    }
    } /// <summary>
    /// Get the new data and send it out to all other connections. 
    /// Note: If not data was recieved the connection has probably 
    /// died.
    /// </summary>
    /// <param name="ar"></param>
    public void OnRecievedData( IAsyncResult ar )
    {
    // Socket was the passed in object
    Socket sock = (Socket)ar.AsyncState; // Check if we got any data
    try
    {
    int nBytesRec = sock.EndReceive( ar );
    if( nBytesRec > 0 )
    {
    // Wrote the data to the List
    string sRecieved = Encoding.ASCII.GetString( m_byBuff, 0, nBytesRec ); // WARNING : The following line is NOT thread safe. Invoke is
    // m_lbRecievedData.Items.Add( sRecieved );
    Invoke( m_AddMessage, new string [] { sRecieved } ); // If the connection is still usable restablish the callback
    SetupRecieveCallback( sock );
    }
    else
    {
    // If no data was recieved then the connection is probably dead
    Console.WriteLine( "Client {0}, disconnected", sock.RemoteEndPoint );
    sock.Shutdown( SocketShutdown.Both );
    sock.Close();
    }
    }
    catch( Exception ex )
    {
    MessageBox.Show( this, ex.Message, "Unusual error druing Recieve!" );
    }
    } public void OnAddMessage( string sMessage )
    {
    m_lbRecievedData.Items.Add( sMessage );
    }

    /// <summary>
    /// Setup the callback for recieved data and loss of conneciton
    /// </summary>
    public void SetupRecieveCallback( Socket sock )
    {
    try
    {
    AsyncCallback recieveData = new AsyncCallback( OnRecievedData );
    sock.BeginReceive( m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData, sock );
    }
    catch( Exception ex )
    {
    MessageBox.Show( this, ex.Message, "Setup Recieve Callback failed!" );
    }
    } /// <summary>
    /// Close the Socket connection bofore going home
    /// </summary>
    private void FormMain_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
    if( m_sock != null && m_sock.Connected )
    {
    m_sock.Shutdown( SocketShutdown.Both );
    m_sock.Close();
    }
    } /// <summary>
    /// Send the Message in the Message area. Only do this if we are connected
    /// </summary>
    private void m_btnSend_Click(object sender, System.EventArgs e)
    {
    // Check we are connected
    if( m_sock == null || !m_sock.Connected )
    {
    MessageBox.Show( this, "Must be connected to Send a message" );
    return;
    } // Read the message from the text box and send it
    try
    {
    // Convert to byte array and send.
    Byte[] byteDateLine = Encoding.ASCII.GetBytes( m_tbMessage.Text.ToCharArray() );
    m_sock.Send( byteDateLine, byteDateLine.Length, 0 );
    }
    catch( Exception ex )
    {
    }
    }
    }
    }