网络聊天工具Socket编程心得

首先要了解TCP协议通信的流程:
1。服务器端首先创建服务器套接字
2。服务器套接字监听一个端口,等待客户端的请求
3。客户端创建一个客户端套接字
4。客户端向服务器发送请求
5。服务器确认与客户端的连接
6。客户端和服务器利用建立的连接进行通信
7。通信完毕后,客户端和服务器关闭各自的连接


Socket编程基础:
一。利用Socket建立服务器程序
1。创建一个服务器套接字,用IP地址和端口初始化服务器
IPAddress ipAddress  =  IPAddress.Parse( " 127.0.0.1 " );
TcpListener listener 
=   new  TcpListener(ipAddress,  1234 );

2。监听服务器端口
listener.Start();

3。确认与客户端的连接
Socket socket  =  listener.AcceptSocket();

4。取得客户端传送过来的信息
// 将传送过来的信息存入字节数组中
byte [] buffer  =   new   byte [ 1024 ];
socket.Receive(buffer);

5。处理客户端的请求并回应客户端
string  message  =   " hello " ;
byte [] outbytes  =  System.Text.Encoding.ASCII.GetBytes(message.ToCharArray());
socket.Send(outbytes, message.Length, 
0 );

6。断开客户端的连接,释放客户端连接
socket.Close();

7。关闭服务器,释放服务器连接
listener.Close();


二。利用Socket建立客户端程序
1。创建客户端套接字

TcpClient tcpClient  =   new  TcpClient();

2。连接服务器
tcpClient.Connect(IPAddress.Parse( " 127.0.0.1 " ),  1234 );

3。得到与服务器通信的流通道
NetworkStream stream  =  tcpClient.GetStream();

4。向服务器发送数据
string  cmd  =   " dot.gif " ;
byte [] outbytes  =  System.Text.Encoding.ASCII.GetBytes(cmd.ToCharArray());
stream.Write(outbytes, 
0 , outbytes.Length);

5。接收从服务器发回的数据
byte [] buffer  =   new   byte [ 1024 ];
int  len  =  stream.Read(buffer,  0 , buffer.Length);
string  msg  =  System.Text.Encoding.ASCII.GetString(buffer,  0 , len);

6。断开连接
tcpClient.Close();



服务器端窗体ChatServer.cs:
using  System;
using  System.Drawing;
using  System.Collections;
using  System.ComponentModel;
using  System.Windows.Forms;
using  System.Data;
using  System.Net;
using  System.Net.Sockets;
using  System.Threading;

namespace  ChatServer
{
    
///   <summary>
    
///  Form1 的摘要说明。
    
///   </summary>
     public   class  ChatServerForm : System.Windows.Forms.Form
    {
        
///   <summary>
        
///  必需的设计器变量。
        
///   </summary>
         private  System.ComponentModel.Container components  =   null ;
        
//  The port
         static   int  port  =   1234 ;
        
private  TcpListener listener;
        
private  Socket tmpSocket;
        
//  The maximal clients the server can hold
         static   int  MaxNum  =   100 ;
        
private  System.Windows.Forms.Label label1;
        
private  System.Windows.Forms.Label label2;
        
private  System.Windows.Forms.TextBox txtHost;
        
private  System.Windows.Forms.TextBox txtPort;
        
private  System.Windows.Forms.Button btnStart;
        
private  System.Windows.Forms.Button btnExit;
        
private  System.Windows.Forms.Label label3;
        
private  System.Windows.Forms.ComboBox cmbCurUserList;
        
private  System.Windows.Forms.ListBox lstInfo;
        
//  The array clients is to save the online clients
         static  ArrayList clients  =   new  ArrayList();

        
public  ChatServerForm()
        {
            
//
            
//  Windows 窗体设计器支持所必需的
            
//
            InitializeComponent();

            
//
            
//  TODO: 在 InitializeComponent 调用后添加任何构造函数代码
            
//
        }

        
///   <summary>
        
///  清理所有正在使用的资源。
        
///   </summary>
         protected   override   void  Dispose(  bool  disposing )
        {
            
if ( disposing )
            {
                
if  (components  !=   null
                {
                    components.Dispose();
                }
            }
            
base .Dispose( disposing );
        }

        
#region  Windows 窗体设计器生成的代码
        
///   <summary>
        
///  设计器支持所需的方法 - 不要使用代码编辑器修改
        
///  此方法的内容。
        
///   </summary>
         private   void  InitializeComponent()
        {
            
this .label1  =   new  System.Windows.Forms.Label();
            
this .label2  =   new  System.Windows.Forms.Label();
            
this .txtHost  =   new  System.Windows.Forms.TextBox();
            
this .txtPort  =   new  System.Windows.Forms.TextBox();
            
this .btnStart  =   new  System.Windows.Forms.Button();
            
this .btnExit  =   new  System.Windows.Forms.Button();
            
this .label3  =   new  System.Windows.Forms.Label();
            
this .cmbCurUserList  =   new  System.Windows.Forms.ComboBox();
            
this .lstInfo  =   new  System.Windows.Forms.ListBox();
            
this .SuspendLayout();
            
//  
            
//  label1
            
//  
             this .label1.AutoSize  =   true ;
            
this .label1.Location  =   new  System.Drawing.Point( 32 32 );
            
this .label1.Name  =   " label1 " ;
            
this .label1.Size  =   new  System.Drawing.Size( 54 17 );
            
this .label1.TabIndex  =   0 ;
            
this .label1.Text  =   " 主机号: " ;
            
//  
            
//  label2
            
//  
             this .label2.AutoSize  =   true ;
            
this .label2.Location  =   new  System.Drawing.Point( 32 72 );
            
this .label2.Name  =   " label2 " ;
            
this .label2.Size  =   new  System.Drawing.Size( 54 17 );
            
this .label2.TabIndex  =   1 ;
            
this .label2.Text  =   " 端口号: " ;
            
//  
            
//  txtHost
            
//  
             this .txtHost.Location  =   new  System.Drawing.Point( 96 24 );
            
this .txtHost.Name  =   " txtHost " ;
            
this .txtHost.Size  =   new  System.Drawing.Size( 128 21 );
            
this .txtHost.TabIndex  =   2 ;
            
this .txtHost.Text  =   "" ;
            
//  
            
//  txtPort
            
//  
             this .txtPort.Location  =   new  System.Drawing.Point( 96 64 );
            
this .txtPort.Name  =   " txtPort " ;
            
this .txtPort.Size  =   new  System.Drawing.Size( 128 21 );
            
this .txtPort.TabIndex  =   3 ;
            
this .txtPort.Text  =   "" ;
            
//  
            
//  btnStart
            
//  
             this .btnStart.Location  =   new  System.Drawing.Point( 256 24 );
            
this .btnStart.Name  =   " btnStart " ;
            
this .btnStart.TabIndex  =   4 ;
            
this .btnStart.Text  =   " 启动 " ;
            
this .btnStart.Click  +=   new  System.EventHandler( this .btnStart_Click);
            
//  
            
//  btnExit
            
//  
             this .btnExit.Location  =   new  System.Drawing.Point( 256 64 );
            
this .btnExit.Name  =   " btnExit " ;
            
this .btnExit.TabIndex  =   5 ;
            
this .btnExit.Text  =   " 退出 " ;
            
this .btnExit.Click  +=   new  System.EventHandler( this .btnExit_Click);
            
//  
            
//  label3
            
//  
             this .label3.AutoSize  =   true ;
            
this .label3.Location  =   new  System.Drawing.Point( 24 112 );
            
this .label3.Name  =   " label3 " ;
            
this .label3.Size  =   new  System.Drawing.Size( 91 17 );
            
this .label3.TabIndex  =   6 ;
            
this .label3.Text  =   " 当前在线用户: " ;
            
//  
            
//  cmbCurUserList
            
//  
             this .cmbCurUserList.Location  =   new  System.Drawing.Point( 120 112 );
            
this .cmbCurUserList.Name  =   " cmbCurUserList " ;
            
this .cmbCurUserList.Size  =   new  System.Drawing.Size( 136 20 );
            
this .cmbCurUserList.TabIndex  =   7 ;
            
//  
            
//  lstInfo
            
//  
             this .lstInfo.ItemHeight  =   12 ;
            
this .lstInfo.Location  =   new  System.Drawing.Point( 0 144 );
            
this .lstInfo.Name  =   " lstInfo " ;
            
this .lstInfo.Size  =   new  System.Drawing.Size( 344 160 );
            
this .lstInfo.TabIndex  =   8 ;
            
//  
            
//  ChatServerForm
            
//  
             this .AutoScaleBaseSize  =   new  System.Drawing.Size( 6 14 );
            
this .ClientSize  =   new  System.Drawing.Size( 344 301 );
            
this .Controls.Add( this .lstInfo);
            
this .Controls.Add( this .cmbCurUserList);
            
this .Controls.Add( this .label3);
            
this .Controls.Add( this .btnExit);
            
this .Controls.Add( this .btnStart);
            
this .Controls.Add( this .txtPort);
            
this .Controls.Add( this .txtHost);
            
this .Controls.Add( this .label2);
            
this .Controls.Add( this .label1);
            
this .Name  =   " ChatServerForm " ;
            
this .Text  =   " Form1 " ;
            
this .Load  +=   new  System.EventHandler( this .Form1_Load);
            
this .ResumeLayout( false );

        }
        
#endregion

        
///   <summary>
        
///  应用程序的主入口点。
        
///   </summary>
        [STAThread]
        
static   void  Main() 
        {
            Application.Run(
new  ChatServerForm());
        }

        
private   void  Form1_Load( object  sender, System.EventArgs e)
        {
            
this .txtPort.ReadOnly  =   true ;
            
this .txtPort.Text  =  port.ToString();
            
this .txtHost.Text  =   " 127.0.0.1 " ;
        }

        
private   void  btnStart_Click( object  sender, System.EventArgs e)
        {
            
try
            {
                IPAddress ip 
=  IPAddress.Parse( this .txtHost.Text);
                listener 
=   new  TcpListener(ip, port);     // 创建服务器套字
                listener.Start();     // 开始监听服务器端口
                lstInfo.Items.Add( " 服务器已经启动,正在监听 "   +  txtHost.Text  +   " : "   +  txtPort.Text);

                
// 启动一个新的线程,执行方法StartListen,以便在一个独立的进程中执行确认于客户端连接的操作.
                Thread thread  =   new  Thread( new  ThreadStart( this .StartListen));
                thread.Start();
                btnStart.Enabled 
=   false ;
            }
            
catch (Exception ex)
            {
                lstInfo.Items.Add(ex.Message);
            }
        }

        
private   void  StartListen()
        {
            
while ( true )
            {
                
try
                {
                    
// 当接受到一个客户端请求时,确认与客户端的连接
                    Socket socket  =  listener.AcceptSocket();

                    
// 用tmpSocket保存发出请求的客户端实例
                    tmpSocket  =  socket;

                    
if  (clients.Count  >=  MaxNum)
                    {
                        tmpSocket.Close();
                    }
                    
else
                    {
                        
// 启动一个新的线程,执行方法this.ServiceClient,处理用户相应的要求
                        Thread clientService  =   new  Thread( new  ThreadStart( this .ServiceClient));
                        clientService.Start();
                    }
                }
                
catch (Exception ex)
                {
                    lstInfo.Items.Add(ex.Message);
                }
            }
        }

        
private   void  ServiceClient()
        {
            
// 定义一个数组,用于接收从客户端发送过来的数据,每次所能接收的数据包的最大长度为1024字节
             byte [] buffer  =   new   byte [ 1024 ];
            Socket clientSocket 
=  tmpSocket;
            
bool  keepConnect  =   true ;

            
// 用循环不断地与客户端进行交互,直到客户端发出Exit命令,将keepConnect设置为false
            
// 退出循环,关闭连接,中止当前线程
             while (keepConnect)
            {
                
// 接收数据并存入buffer数组中
                clientSocket.Receive(buffer);
                
// 将字符数组转化为字符串
                 string  clientCommand  =  System.Text.Encoding.ASCII.GetString(buffer);
                
string [] tokens  =  clientCommand.Split( ' | ' );
                
// tokens[0]中保存了命令标识符(CONN或CHAT或PRIV或EXIT)
                 if  (tokens[ 0 ==   " CONN " )     //  CONN|用户名|
                {
                    Client _client 
=   new  Client(tokens[ 1 ], clientSocket);
                    clients.Add(_client);
                    lstInfo.Items.Add(tokens[
1 +   "  has joined " );
                    
// 将刚连接的用户名加入到当前在线用户列表中
                     this .cmbCurUserList.Items.Add(tokens[ 1 ]);
                    
// 对每一个在线用户发送JOIN和LIST信息命令,以此来更新客户端的在线用户列表
                     for ( int  i = 0 ; i < clients.Count; i ++ )
                    {
                        Client client 
=  (Client)clients[i];
                        
// 向客户端发送JOIN命令,以此来提示有新的客户进入聊天室
                        SendToClient(client,  " JOIN| "   +  tokens[ 1 +   " | " );
                        Thread.Sleep(
100 );
                        
string  msgUsers  =   " LIST| "   +  GetUserList();
                        
// 向客户端发送LIST命令,以此来更新客户端的当前在线用户列表
                        SendToClient(client, msgUsers);
                    }
                }
                
if  (tokens[ 0 ==   " CHAT " )     //  CHAT|用户名:内容|
                {
                    
// 向所有当前在线用户转发此信息
                     for  ( int  i = 0 ; i < clients.Count; i ++ )
                    {
                        Client client 
=  (Client)clients[i];
                        
// 将"发送者的用户名:发送内容"转发给用户
                        SendToClient(client, tokens[ 1 ]);
                    }
                }
                
if  (tokens[ 0 ==   " PRIV " )     //  PRIV|发送者用户名|接受者用户名|发送内容
                {
                    
string  sender  =  tokens[ 1 ];
                    
string  receiver  =  tokens[ 2 ];
                    
string  content  =  tokens[ 3 ];

                    
string  message  =  sender  +   " send to  "   +  receiver  +   " "   +  content;

                    
// 仅把信息转发给发送者和接收者
                     for  ( int  i = 0 ; i < clients.Count; i ++ )
                    {
                        Client client 
=  (Client)clients[i];
                        
if  (client.Name  ==  tokens[ 2 ])
                        {
                            
this .SendToClient(client, message);
                        }
                        
if  (client.Name  ==  tokens[ 1 ])
                        {
                            
this .SendToClient(client, message);
                        }
                    }
                }
                
if  (tokens[ 0 ==   " EXIT " )     //  EXIT|用户名
                {
                    
for  ( int  i = 0 ; i < clients.Count; i ++ )
                    {
                        Client client 
=  (Client)clients[i];
                        
string  message  =  tokens[ 1 +   "  has gone! " ;
                        
this .SendToClient(client, message);
                        
if  (client.Name  ==  tokens[ 1 ])
                        {
                            
// 将该用户从对应的Client对象从clients数组中删除
                            clients.RemoveAt(i);
                            
// 将该用户名从当前在线用户列表中删除
                             this .cmbCurUserList.Items.Remove(client.Name);
                            
// 向客户端发送QUIT命令,以此来关闭客户端程序
                            message  =   " QUIT| " ;
                            
this .SendToClient(client, message);
                        }
                    }
                    
for  ( int  i = 0 ;i < clients.Count;i ++ )
                    {
                        Client client 
=  (Client)clients[i];
                        
string  message  =   " LIST| "   +  GetUserList();
                        
this .SendToClient(client, message);
                    }
                    
this .lstInfo.Items.Add(tokens[ 1 +   "  has gone! " );
                    
// 断开与该用户的连接
                    clientSocket.Close();
                    keepConnect 
=   false ;
                }

            }
        }

        
// 实现向客户端发送命令请求的功能
         private   void  SendToClient(Client client,  string  msg)
        {
            System.Byte[] message 
=  System.Text.Encoding.ASCII.GetBytes(msg.ToCharArray());
            client.ClientSocket.Send(message, message.Length, 
0 );
        }

        
// 以 username1|username2|username3|dot.gif 的形式返回当前在线用户名列表
         private   string  GetUserList()
        {
            
string  list  =   "" ;
            
for  ( int  i = 0 ; i < clients.Count; i ++ )
            {
                Client client 
=  (Client)clients[i];
                list 
+=  client.Name  +   " | " ;
            }
            
return  list;
        }

        
private   void  btnExit_Click( object  sender, System.EventArgs e)
        {
            
this .Close();
            Application.ExitThread();
            Application.Exit();
        }

        
// 定义一个Client类,每个当前在线用户都对应这它的一个实例,它包含了当前在线用户名和该用户
        
// 与服务器连接的Socket对象,
         public   class  Client
        {
            
string  name;
            Socket clSocket;
            
            
public  Client( string  _name, Socket _socket)
            {
                name 
=  _name;
                clSocket 
=  _socket;
            }

            
public   string  Name
            {
                
get
                {
                    
return  name;
                }
                
set
                {
                    name 
=  value;
                }
            }
            
public  Socket ClientSocket
            {
                
get  
                {
                    
return  clSocket;
                }
                
set
                {
                    clSocket 
=  value;
                }
            }
        }
    }
}



客户端主窗体:ChatClient.cs:
using  System;
using  System.Drawing;
using  System.Collections;
using  System.ComponentModel;
using  System.Windows.Forms;
using  System.Net;
using  System.Net.Sockets;
using  System.Threading;

namespace  ChatClient
{
    
///   <summary>
    
///  ChatClientForm 的摘要说明。
    
///   </summary>
     public   class  ChatClientForm : System.Windows.Forms.Form
    {
        
private  System.Windows.Forms.Label label1;
        
private  System.Windows.Forms.TextBox txtAlias;
        
private  System.Windows.Forms.ListBox lstContent;
        
private  System.Windows.Forms.Label label2;
        
private  System.Windows.Forms.ListBox lstUsers;
        
private  System.Windows.Forms.CheckBox chkPrivate;
        
private  System.Windows.Forms.TextBox txtSend;
        
private  System.Windows.Forms.Button btnSend;
        
private  System.Windows.Forms.Button btnExit;
        
///   <summary>
        
///  必需的设计器变量。
        
///   </summary>
         private  System.ComponentModel.Container components  =   null ;

        
private  TcpClient tcpClient;     // 与服务器的连接
         private  NetworkStream stream;     // 与服务器数据交互的流通道
         private   string  userAlias;         // 用户名
         private   bool  isPrivate  =   false ;     // 是否为私聊

        [STAThread]
        
static   void  Main() 
        {
            Application.Run(
new  ChatClientForm());
        }

        
public  ChatClientForm()
        {
            
//
            
//  Windows 窗体设计器支持所必需的
            
//
            InitializeComponent();

            
//
            
//  TODO: 在 InitializeComponent 调用后添加任何构造函数代码
            
//
        }

        
///   <summary>
        
///  清理所有正在使用的资源。
        
///   </summary>
         protected   override   void  Dispose(  bool  disposing )
        {
            
if ( disposing )
            {
                
if (components  !=   null )
                {
                    components.Dispose();
                }
            }
            
base .Dispose( disposing );
        }

        
#region  Windows 窗体设计器生成的代码
        
///   <summary>
        
///  设计器支持所需的方法 - 不要使用代码编辑器修改
        
///  此方法的内容。
        
///   </summary>
         private   void  InitializeComponent()
        {
            
this .label1  =   new  System.Windows.Forms.Label();
            
this .txtAlias  =   new  System.Windows.Forms.TextBox();
            
this .lstContent  =   new  System.Windows.Forms.ListBox();
            
this .label2  =   new  System.Windows.Forms.Label();
            
this .lstUsers  =   new  System.Windows.Forms.ListBox();
            
this .chkPrivate  =   new  System.Windows.Forms.CheckBox();
            
this .txtSend  =   new  System.Windows.Forms.TextBox();
            
this .btnSend  =   new  System.Windows.Forms.Button();
            
this .btnExit  =   new  System.Windows.Forms.Button();
            
this .SuspendLayout();
            
//  
            
//  label1
            
//  
             this .label1.AutoSize  =   true ;
            
this .label1.Location  =   new  System.Drawing.Point( 104 16 );
            
this .label1.Name  =   " label1 " ;
            
this .label1.Size  =   new  System.Drawing.Size( 42 17 );
            
this .label1.TabIndex  =   0 ;
            
this .label1.Text  =   " 昵称: " ;
            
//  
            
//  txtAlias
            
//  
             this .txtAlias.Location  =   new  System.Drawing.Point( 208 8 );
            
this .txtAlias.Name  =   " txtAlias " ;
            
this .txtAlias.ReadOnly  =   true ;
            
this .txtAlias.TabIndex  =   1 ;
            
this .txtAlias.Text  =   "" ;
            
//  
            
//  lstContent
            
//  
             this .lstContent.ItemHeight  =   12 ;
            
this .lstContent.Location  =   new  System.Drawing.Point( 0 40 );
            
this .lstContent.Name  =   " lstContent " ;
            
this .lstContent.Size  =   new  System.Drawing.Size( 432 172 );
            
this .lstContent.TabIndex  =   2 ;
            
//  
            
//  label2
            
//  
             this .label2.AutoSize  =   true ;
            
this .label2.Location  =   new  System.Drawing.Point( 0 224 );
            
this .label2.Name  =   " label2 " ;
            
this .label2.Size  =   new  System.Drawing.Size( 116 17 );
            
this .label2.TabIndex  =   3 ;
            
this .label2.Text  =   " 当前在线用户列表: " ;
            
//  
            
//  lstUsers
            
//  
             this .lstUsers.ItemHeight  =   12 ;
            
this .lstUsers.Location  =   new  System.Drawing.Point( 0 240 );
            
this .lstUsers.Name  =   " lstUsers " ;
            
this .lstUsers.Size  =   new  System.Drawing.Size( 120 100 );
            
this .lstUsers.TabIndex  =   4 ;
            
//  
            
//  chkPrivate
            
//  
             this .chkPrivate.Location  =   new  System.Drawing.Point( 136 240 );
            
this .chkPrivate.Name  =   " chkPrivate " ;
            
this .chkPrivate.TabIndex  =   5 ;
            
this .chkPrivate.Text  =   " 悄悄话 " ;
            
this .chkPrivate.CheckedChanged  +=   new  System.EventHandler( this .chkPrivate_CheckedChanged);
            
//  
            
//  txtSend
            
//  
             this .txtSend.Location  =   new  System.Drawing.Point( 136 272 );
            
this .txtSend.Name  =   " txtSend " ;
            
this .txtSend.Size  =   new  System.Drawing.Size( 288 21 );
            
this .txtSend.TabIndex  =   6 ;
            
this .txtSend.Text  =   "" ;
            
//  
            
//  btnSend
            
//  
             this .btnSend.Location  =   new  System.Drawing.Point( 136 312 );
            
this .btnSend.Name  =   " btnSend " ;
            
this .btnSend.TabIndex  =   7 ;
            
this .btnSend.Text  =   " 发送 " ;
            
this .btnSend.Click  +=   new  System.EventHandler( this .btnSend_Click);
            
//  
            
//  btnExit
            
//  
             this .btnExit.Location  =   new  System.Drawing.Point( 344 312 );
            
this .btnExit.Name  =   " btnExit " ;
            
this .btnExit.TabIndex  =   8 ;
            
this .btnExit.Text  =   " 离开 " ;
            
this .btnExit.Click  +=   new  System.EventHandler( this .btnExit_Click);
            
//  
            
//  ChatClientForm
            
//  
             this .AutoScaleBaseSize  =   new  System.Drawing.Size( 6 14 );
            
this .ClientSize  =   new  System.Drawing.Size( 432 349 );
            
this .Controls.Add( this .btnExit);
            
this .Controls.Add( this .btnSend);
            
this .Controls.Add( this .txtSend);
            
this .Controls.Add( this .chkPrivate);
            
this .Controls.Add( this .lstUsers);
            
this .Controls.Add( this .label2);
            
this .Controls.Add( this .lstContent);
            
this .Controls.Add( this .txtAlias);
            
this .Controls.Add( this .label1);
            
this .Name  =   " ChatClientForm " ;
            
this .Text  =   " ChatClientForm " ;
            
this .Load  +=   new  System.EventHandler( this .ChatClientForm_Load);
            
this .ResumeLayout( false );

        }
        
#endregion

        
private   void  ChatClientForm_Load( object  sender, System.EventArgs e)
        {
            
try
            {
                Login dlgLogin 
=   new  Login();
                DialogResult result 
=  dlgLogin.ShowDialog();
                
if  (result  ==  DialogResult.OK)
                {
                    
this .userAlias  =  dlgLogin.Alias;
                    
this .txtAlias.Text  =  userAlias;

                    
this .tcpClient  =  dlgLogin.tcpClient;
                    stream 
=  tcpClient.GetStream();
                    dlgLogin.Close();
                }
                
else
                {
                    lstUsers.Enabled 
=   false ;
                    txtSend.ReadOnly 
=   true ;
                    btnSend.Enabled 
=   false ;
                    dlgLogin.Close();
                }

                
// 启动一个新的进程,执行方法this.ServerResponse,以便来响应从服务器发回的信息
                Thread thread  =   new  Thread( new  ThreadStart( this .ServerResponse));
                thread.Start();

                
string  cmd  =   " CONN| "   +   this .userAlias  +   " | " ;
                
byte [] outbytes  =  System.Text.Encoding.ASCII.GetBytes(cmd.ToCharArray());

                
// 利用NetworkStream的Write方法传送
                stream.Write(outbytes,  0 , outbytes.Length);
            }
            
catch  (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        
private   void  ServerResponse()
        {
            
byte [] buffer  =   new   byte [ 1024 ];
            
string  msg;
            
int  len;
            
try
            {
                
if  ( ! stream.CanRead)
                {
                    
return ;
                }

                
while  ( true )
                {
                    len 
=  stream.Read(buffer,  0 , buffer.Length);
                    msg 
=  System.Text.Encoding.ASCII.GetString(buffer,  0 , len);
                    msg.Trim();
                    
string [] tokens  =  msg.Split( ' | ' );

                    
if  (tokens[ 0 ==   " LIST " )     // LIST|用户名1|用户名2|dot.gif
                    {
                        lstUsers.Items.Clear();
                        
for  ( int  i = 0 ; i < tokens.Length - 1 ; i ++ )
                        {
                            lstUsers.Items.Add(tokens[i].Trim());
                        }
                    }

                    
if  (tokens[ 0 ==   " JOIN " )     //  JOIN|刚刚登录的用户名
                    {
                        
this .lstContent.Items.Add(tokens[ 1 +   "  has enter the chatroom! " );
                    }

                    
if  (tokens[ 0 ==   " QUIT " )
                    {
                        
break ;
                    }

                    
if  (tokens[ 0 ] != " LIST "   &&  tokens[ 0 ] != " JOIN "   &&  tokens[ 0 ] != " QUIT " )
                    {
                        lstContent.Items.Add(msg);
                    }
                }
                tcpClient.Close();    
// 关闭连接
                 this .Close();         // 关闭客户端程序
            }
            
catch  (Exception ex)
            {
                lstContent.Items.Add(ex.Message);
            }
        }

        
private   void  chkPrivate_CheckedChanged( object  sender, System.EventArgs e)
        {
            
if  ( this .chkPrivate.Checked)
            {
                
this .isPrivate  =   true ;
            }
            
else
            {
                
this .isPrivate  =   false ;
            }
        }

        
private   void  btnSend_Click( object  sender, System.EventArgs e)
        {
            
try
            {
                
if  ( ! this .isPrivate)
                {
                    
string  message  =   " CHAT| "   +   this .userAlias  +   " : "   +   this .txtSend.Text  +   " | " ;
                    
this .txtSend.Text  =   "" ;
                    
this .txtSend.Focus();
                    
byte [] outbytes  =  System.Text.Encoding.ASCII.GetBytes(message.ToCharArray());
                    stream.Write(outbytes, 
0 , outbytes.Length);
                }
                
else
                {
                    
if  (lstUsers.SelectedIndex  ==   - 1 )
                    {
                        MessageBox.Show(
" 请在列表中选择一个用户 " " 提示信息 " , MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        
return ;
                    }
                    
string  receiver  =   this .lstUsers.SelectedItem.ToString();
                    
string  message  =   " PRIV| "   +   this .userAlias  +   " | "   +  receiver  +   " | "   +   this .txtSend.Text  +   " | " ;
                    
this .txtSend.Text  =   "" ;
                    
this .txtSend.Focus();
                    
byte [] outbytes  =  System.Text.Encoding.ASCII.GetBytes(message.ToCharArray());
                    stream.Write(outbytes, 
0 , outbytes.Length);
                }
            }
            
catch  (Exception ex)
            {
                
this .lstContent.Items.Add( " 网络发生错误! " );
            }
        }

        
private   void  btnExit_Click( object  sender, System.EventArgs e)
        {
            
string  message  =   " EXIT| "   +   this .userAlias  +   " | " ;
            
byte [] outbytes  =  System.Text.Encoding.ASCII.GetBytes(message.ToCharArray());
            stream.Write(outbytes, 
0 , outbytes.Length);
        }

    }
}



客户端登录窗体:Login.cs
using  System;
using  System.Drawing;
using  System.Collections;
using  System.ComponentModel;
using  System.Windows.Forms;
using  System.Data;
using  System.Net;
using  System.Net.Sockets;

namespace  ChatClient
{
    
///   <summary>
    
///  Login 的摘要说明。
    
///   </summary>
     public   class  Login : System.Windows.Forms.Form
    {
        
///   <summary>
        
///  必需的设计器变量。
        
///   </summary>
         private  System.ComponentModel.Container components  =   null ;
        
        
// tcpClient是Login的一个公有成员,它用于创建客户端套接字
         public  TcpClient tcpClient;
        
private  System.Windows.Forms.Label label1;
        
private  System.Windows.Forms.Label label2;
        
private  System.Windows.Forms.Label label3;
        
private  System.Windows.Forms.Button btnLogin;
        
private  System.Windows.Forms.Button btnCancel;
        
private  System.Windows.Forms.TextBox txtHost;
        
private  System.Windows.Forms.TextBox txtPort;
        
private  System.Windows.Forms.TextBox txtName;

        
// Alias是Login的一个公有成员,它向ChatClient窗体传递用户名
         public   string  Alias  =   "" ;

        
public  Login()
        {
            
//
            
//  Windows 窗体设计器支持所必需的
            
//
            InitializeComponent();

            
//
            
//  TODO: 在 InitializeComponent 调用后添加任何构造函数代码
            
//
        }

        
///   <summary>
        
///  清理所有正在使用的资源。
        
///   </summary>
         protected   override   void  Dispose(  bool  disposing )
        {
            
if ( disposing )
            {
                
if  (components  !=   null
                {
                    components.Dispose();
                }
            }
            
base .Dispose( disposing );
        }

        
#region  Windows 窗体设计器生成的代码
        
///   <summary>
        
///  设计器支持所需的方法 - 不要使用代码编辑器修改
        
///  此方法的内容。
        
///   </summary>
         private   void  InitializeComponent()
        {
            
this .label1  =   new  System.Windows.Forms.Label();
            
this .label2  =   new  System.Windows.Forms.Label();
            
this .label3  =   new  System.Windows.Forms.Label();
            
this .txtHost  =   new  System.Windows.Forms.TextBox();
            
this .txtPort  =   new  System.Windows.Forms.TextBox();
            
this .txtName  =   new  System.Windows.Forms.TextBox();
            
this .btnLogin  =   new  System.Windows.Forms.Button();
            
this .btnCancel  =   new  System.Windows.Forms.Button();
            
this .SuspendLayout();
            
//  
            
//  label1
            
//  
             this .label1.AutoSize  =   true ;
            
this .label1.Location  =   new  System.Drawing.Point( 16 32 );
            
this .label1.Name  =   " label1 " ;
            
this .label1.Size  =   new  System.Drawing.Size( 79 17 );
            
this .label1.TabIndex  =   0 ;
            
this .label1.Text  =   " 服务器地址: " ;
            
//  
            
//  label2
            
//  
             this .label2.AutoSize  =   true ;
            
this .label2.Location  =   new  System.Drawing.Point( 16 72 );
            
this .label2.Name  =   " label2 " ;
            
this .label2.Size  =   new  System.Drawing.Size( 54 17 );
            
this .label2.TabIndex  =   1 ;
            
this .label2.Text  =   " 端口号: " ;
            
//  
            
//  label3
            
//  
             this .label3.AutoSize  =   true ;
            
this .label3.Location  =   new  System.Drawing.Point( 16 112 );
            
this .label3.Name  =   " label3 " ;
            
this .label3.Size  =   new  System.Drawing.Size( 54 17 );
            
this .label3.TabIndex  =   2 ;
            
this .label3.Text  =   " 用户名: " ;
            
//  
            
//  txtHost
            
//  
             this .txtHost.Location  =   new  System.Drawing.Point( 104 24 );
            
this .txtHost.Name  =   " txtHost " ;
            
this .txtHost.Size  =   new  System.Drawing.Size( 144 21 );
            
this .txtHost.TabIndex  =   3 ;
            
this .txtHost.Text  =   " 127.0.0.1 " ;
            
//  
            
//  txtPort
            
//  
             this .txtPort.Location  =   new  System.Drawing.Point( 104 64 );
            
this .txtPort.Name  =   " txtPort " ;
            
this .txtPort.ReadOnly  =   true ;
            
this .txtPort.Size  =   new  System.Drawing.Size( 144 21 );
            
this .txtPort.TabIndex  =   4 ;
            
this .txtPort.Text  =   " 1234 " ;
            
//  
            
//  txtName
            
//  
             this .txtName.Location  =   new  System.Drawing.Point( 104 104 );
            
this .txtName.Name  =   " txtName " ;
            
this .txtName.Size  =   new  System.Drawing.Size( 144 21 );
            
this .txtName.TabIndex  =   5 ;
            
this .txtName.Text  =   "" ;
            
//  
            
//  btnLogin
            
//  
             this .btnLogin.DialogResult  =  System.Windows.Forms.DialogResult.OK;
            
this .btnLogin.Location  =   new  System.Drawing.Point( 40 160 );
            
this .btnLogin.Name  =   " btnLogin " ;
            
this .btnLogin.TabIndex  =   6 ;
            
this .btnLogin.Text  =   " 登录 " ;
            
this .btnLogin.Click  +=   new  System.EventHandler( this .btnLogin_Click);
            
//  
            
//  btnCancel
            
//  
             this .btnCancel.DialogResult  =  System.Windows.Forms.DialogResult.Cancel;
            
this .btnCancel.Location  =   new  System.Drawing.Point( 168 160 );
            
this .btnCancel.Name  =   " btnCancel " ;
            
this .btnCancel.TabIndex  =   7 ;
            
this .btnCancel.Text  =   " 取消 " ;
            
this .btnCancel.Click  +=   new  System.EventHandler( this .btnCancel_Click);
            
//  
            
//  Login
            
//  
             this .AutoScaleBaseSize  =   new  System.Drawing.Size( 6 14 );
            
this .ClientSize  =   new  System.Drawing.Size( 292 229 );
            
this .Controls.Add( this .btnCancel);
            
this .Controls.Add( this .btnLogin);
            
this .Controls.Add( this .txtName);
            
this .Controls.Add( this .txtPort);
            
this .Controls.Add( this .txtHost);
            
this .Controls.Add( this .label3);
            
this .Controls.Add( this .label2);
            
this .Controls.Add( this .label1);
            
this .Name  =   " Login " ;
            
this .Text  =   " Login " ;
            
this .Load  +=   new  System.EventHandler( this .Login_Load);
            
this .ResumeLayout( false );

        }
        
#endregion


        
private   void  Login_Load( object  sender, System.EventArgs e)
        {
        
        }

        
private   void  btnCancel_Click( object  sender, System.EventArgs e)
        {
            ChatClient.Login.ActiveForm.Close();
        }

        
private   void  btnLogin_Click( object  sender, System.EventArgs e)
        {
            
this .txtName.Text  =   this .txtName.Text.Trim();
            
if  ( this .txtName.Text.Length  ==   0 )
            {
                MessageBox.Show(
" 请输入您的昵称! " " 提示信息 " , MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                
this .txtName.Focus();
                
return ;
            }
            
try
            {
                tcpClient 
=   new  TcpClient();
                
                
// 向指定的IP地址的服务器发出连接请求
                tcpClient.Connect(IPAddress.Parse(txtHost.Text), Int32.Parse(txtPort.Text));
                
this .Alias  =  txtName.Text;
            }
            
catch  (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}

转载于:https://www.cnblogs.com/wddavid/archive/2005/08/30/225693.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值