hi again, i asked before about the chat server thing, and on which language is better to do it... now my question is, to make a chat server, is it neccassry to read books that talks for example about C# or c++ network programming or something like that... and
if the answer is yes, can anyone recommend for me books that can help, C# or C++ books Kind Regards
Its quite simple to make a chat server. Here is a sample: (i think, it was from codeproject) Server Code: ----- using 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 list namespace ChatServer { /// /// Main class from which all objects are created /// class AppMain { // Attributes private ArrayList m_aryClients = new ArrayList(); // List of Client Connections /// /// Application
starts here. Create an instance of this class and use it /// as the main object. /// /// static void Main(string[] args) { AppMain app = new AppMain(); // Welcome and Start listening Console.WriteLine( "*** Chat Server Started {0} *** ", DateTime.Now.ToString(
"G" ) ); /* // // Method 1 // Socket client; const int nPortListen = 399; try { TcpListener listener = new TcpListener( nPortListen ); Console.WriteLine( "Listening as {0}", listener.LocalEndpoint ); listener.Start(); do { byte [] m_byBuff = new byte[127];
if( listener.Pending() ) { client = listener.AcceptSocket(); // 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.Send( byteDateLine, byteDateLine.Length, 0 ); } else { Thread.Sleep( 100 ); } } while( true ); // Don't use this. //Console.WriteLine ("OK that does it! Screw you guys I'm going home..." ); //listener.Stop(); } catch( Exception
ex ) { Console.WriteLine ( ex.Message ); } */ // // 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(); } /// /// Callback used when a client requests a connection. /// Accpet the connection, adding it to our list
and setup to /// accept more connections. /// /// public void OnConnectRequest( IAsyncResult ar ) { Socket listener = (Socket)ar.AsyncState; NewConnection( listener.EndAccept( ar ) ); listener.BeginAccept( new AsyncCallback( OnConnectRequest ), listener );
} /// /// 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 /// /// Connection to keep //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 ); } /// /// Get the new data and send it out to all other connections. /// Note: If not data was recieved the connection has probably
/// died. /// /// 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 ); } } /// /// Class holding information and buffers for the Client socket connection /// internal class SocketChatClient { private Socket m_sock; // Connection to the client private byte[] m_byBuff = new byte[50]; // Receive data buffer /// /// Constructor
/// /// client socket conneciton this object represents public SocketChatClient( Socket sock ) { m_sock = sock; } // Readonly access public Socket Sock { get{ return m_sock; } } /// /// Setup the callback for recieved data and loss of conneciton /// /// 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 ); } } /// /// Data has been recieved so we shall put it in an array and /// return it. /// /// /// Array of bytes containing the received data 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; } } } ----- 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; // Text encoders // Declare the delegate prototype to send
data back to the form delegate void AddMessage( string sNewMessage ); namespace ChatClient { /// /// This form connects to a Socket server and Streams data to and from it. /// Note: The following has been ommitted. /// 1) Send button need to be grayed when
conneciton is /// not active /// 2) Send button should gray when no text in the Message box. /// 3) Line feeds in the recieved data should be parsed into seperate /// lines in the recieved data list /// 4) Read startup setting from a app.config file /// 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; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; public FormMain() { // // Required for Windows Form Designer support // InitializeComponent(); // Add Message Event handler for Form decoupling from
input thread m_AddMessage = new AddMessage( OnAddMessage ); // // TODO: Add any constructor code after InitializeComponent call // } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components
!= null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// 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 /// /// The main entry point for the application. /// [STAThread] static void Main() { Application.Run(new FormMain());
} /// /// Connect button pressed. Attempt a connection to the server and /// setup Recieved data callback /// /// /// 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!" ); } } /// /// Get the new data
and send it out to all other connections. /// Note: If not data was recieved the connection has probably /// died. /// /// 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 ); } /// /// Setup the callback for recieved data and loss of conneciton /// 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!" ); } } /// /// Close the Socket connection bofore going home /// 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(); } } /// /// Send the Message in the Message area. Only do this if we are connected /// 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 ) { MessageBox.Show( this, ex.Message, "Send Message Failed!" ); } } } } ---- The chat server, is a console application, the
client is a winform.
None
0 Points
123 Posts
chat server again
Dec 11, 2003 05:52 AM|manasrahfantom|LINK
Member
15 Points
160 Posts
Re: chat server again
Dec 11, 2003 06:36 AM|cantfindbettername|LINK