首先要了解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 );
TcpListener listener = new TcpListener(ipAddress, 1234 );
2。监听服务器端口
listener.Start();
3。确认与客户端的连接
Socket socket
=
listener.AcceptSocket();
4。取得客户端传送过来的信息
//
将传送过来的信息存入字节数组中
byte [] buffer = new byte [ 1024 ];
socket.Receive(buffer);
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 );
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
=
"
"
;
byte [] outbytes = System.Text.Encoding.ASCII.GetBytes(cmd.ToCharArray());
stream.Write(outbytes, 0 , outbytes.Length);

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);
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|
的形式返回当前在线用户名列表
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;
}
}
}
}
}
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|

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|
{
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);
}
}
}
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|

{
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);
}
}
}
}
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);
}
}
}
}