要实现局域网聊天这个功能,看了很多大佬们的博客,发现大佬们都真是太厉害了,发现自己有待提高的地方还很多。
以下是我实现这项功能的图示和代码,如有更好的办法,下方评论指出,本人将感谢大佬们的建议和解决方案!
第一步:首先看下界面和命名
第二步:代码
服务器端:
From界面:
public Form1()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
}
server s = new server();
IPAddress ip = null;
private void Form1_Load(object sender, EventArgs e)
{
ip = Dns.Resolve(Dns.GetHostName()).AddressList[0];
this.txtIP.Text = ip.ToString();
this.s.Started += new EventHandler(s_Started);
this.s.Logged += new EventHandler<UserLoggedEventArgs>(s_Logged);
this.s.PChated += new EventHandler<PublicChatEventArgs>(s_PChated);
}
private void BtnSend_Click(object sender, EventArgs e)
{
string msg = "CHAT|服务器消息:|" + DateTime.Now.ToLongTimeString() + "|" + this.rtxtMsg.Text;
this.s.SendMessage(msg);
this.rtxt.AppendText("服务器消息:在" + Convert.ToDateTime(DateTime.Now.ToLongTimeString()) + " 通知:\n" + this.rtxtMsg.Text + "\n");
this.rtxtMsg.Text = "";
}
void s_PChated(object sender, PublicChatEventArgs e)
{
this.rtxt.AppendText(e.UserName + " 在" + e.Time + "说: \n" + e.Msg + "\n");
}
void s_Started(object sender, EventArgs e)
{
this.rtxt.AppendText("******************服务器已启动******************\n");
}
void s_Logged(object sender, UserLoggedEventArgs e)
{
this.rtxt.AppendText("客户端【 " + e.UserName + "】 已启动!\n");
this.lbxUserList.Items.Clear();
foreach (string item in e.UserList)
{
this.lbxUserList.Items.Add(item);
}
}
private void BtnStart_Click(object sender, EventArgs e)
{
this.s.ip = ip;
this.s.port = int.Parse(this.txtPort.Text);
this.s.Start();
this.btnStart.Enabled = false;
}
private void Rtxt_TextChanged(object sender, EventArgs e)
{
this.rtxt.Focus();
this.rtxtMsg.Focus();
}
server类:
public event EventHandler Started;
public event EventHandler<UserLoggedEventArgs> Logged;
public event EventHandler<PublicChatEventArgs> PChated;
public server() { }
#region 字段定义
public IPAddress ip { get; set; }
public int port { get; set; }
Thread thread = null;
private TcpListener listener;
private Dictionary<string, Socket> userlist = new Dictionary<string, Socket>();
#endregion
//开启服务
public void Start()
{
this.thread = new Thread(new ThreadStart(this.Work));
this.listener = new TcpListener(this.ip, this.port);
this.listener.Start();
this.thread.Start();
if (this.Started != null)
{
this.Started(this, new EventArgs());
}
}
public void Work()
{
while (true)
{
Socket soket = this.listener.AcceptSocket();
Thread userThread = new Thread(
delegate ()
{
ResponseClient(soket);
}
);
userThread.Start();
}
}
private void ResponseClient(Socket soket)
{
while (true)
{
byte[] buffer = new byte[1024 * 10];
soket.Receive(buffer);
string msg = Encoding.Unicode.GetString(buffer).TrimEnd('\0');
string[] tokens = msg.Split('|');
if (tokens[0] == "CONN")
{
if (this.userlist.ContainsKey(tokens[0]))
{
break;
}
else
{
this.userlist.Add(tokens[1], soket);
}
UserLoggedEventArgs e1 = new UserLoggedEventArgs();
e1.UserName = tokens[1];
e1.UserList = this.GetUserList();
//通知服务器界面
if (this.Logged != null)
{
this.Logged(this, e1);
}
}
if (tokens[0] == "TS")
{
PublicChatEventArgs e1 = new PublicChatEventArgs();
e1.UserName = tokens[1];
e1.Time = Convert.ToDateTime(tokens[2]);
string message = "";
for (int i = 3; i < tokens.Length; i++)
{
message += tokens[i];
}
e1.Msg = message;
if (this.PChated != null)
{
this.PChated(this, e1);
}
}
}
}
//获取客户列表
private List<string> GetUserList()
{
List<string> list = new List<string>();
foreach (KeyValuePair<string, Socket> item in userlist)
{
list.Add(item.Key);
}
return list;
}
public void SendMessage(string message)
{
foreach (KeyValuePair<string, Socket> item in userlist)
{
byte[] buffer = Encoding.Unicode.GetBytes(message.ToCharArray());
item.Value.Send(buffer);
}
}
}
public class UserLoggedEventArgs : EventArgs
{
public string UserName { get; set; }
public List<string> UserList { get; set; }
}
public class PublicChatEventArgs : EventArgs
{
public string UserName { get; set; }
public string Msg { get; set; }
public DateTime Time { get; set; }
public string Font { get; set; }
public string FontColor { get; set; }
public string FontSize { get; set; }
}
用户界面:
From界面:
public event EventHandler Started;
public event EventHandler<UserLoggedEventArgs> Logged;
public event EventHandler<PublicChatEventArgs> PChated;
public server() { }
#region 字段定义
public IPAddress ip { get; set; }
public int port { get; set; }
Thread thread = null;
private TcpListener listener;
private Dictionary<string, Socket> userlist = new Dictionary<string, Socket>();
#endregion
//开启服务
public void Start()
{
this.thread = new Thread(new ThreadStart(this.Work));
this.listener = new TcpListener(this.ip, this.port);
this.listener.Start();
this.thread.Start();
if (this.Started != null)
{
this.Started(this, new EventArgs());
}
}
public void Work()
{
while (true)
{
Socket soket = this.listener.AcceptSocket();
Thread userThread = new Thread(
delegate ()
{
ResponseClient(soket);
}
);
userThread.Start();
}
}
private void ResponseClient(Socket soket)
{
while (true)
{
byte[] buffer = new byte[1024 * 10];
soket.Receive(buffer);
string msg = Encoding.Unicode.GetString(buffer).TrimEnd('\0');
string[] tokens = msg.Split('|');
if (tokens[0] == "CONN")
{
if (this.userlist.ContainsKey(tokens[0]))
{
break;
}
else
{
this.userlist.Add(tokens[1], soket);
}
UserLoggedEventArgs e1 = new UserLoggedEventArgs();
e1.UserName = tokens[1];
e1.UserList = this.GetUserList();
//通知服务器界面
if (this.Logged != null)
{
this.Logged(this, e1);
}
}
if (tokens[0] == "TS")
{
PublicChatEventArgs e1 = new PublicChatEventArgs();
e1.UserName = tokens[1];
e1.Time = Convert.ToDateTime(tokens[2]);
string message = "";
for (int i = 3; i < tokens.Length; i++)
{
message += tokens[i];
}
e1.Msg = message;
if (this.PChated != null)
{
this.PChated(this, e1);
}
}
}
}
//获取客户列表
private List<string> GetUserList()
{
List<string> list = new List<string>();
foreach (KeyValuePair<string, Socket> item in userlist)
{
list.Add(item.Key);
}
return list;
}
public void SendMessage(string message)
{
foreach (KeyValuePair<string, Socket> item in userlist)
{
byte[] buffer = Encoding.Unicode.GetBytes(message.ToCharArray());
item.Value.Send(buffer);
}
}
}
public class UserLoggedEventArgs : EventArgs
{
public string UserName { get; set; }
public List<string> UserList { get; set; }
}
public class PublicChatEventArgs : EventArgs
{
public string UserName { get; set; }
public string Msg { get; set; }
public DateTime Time { get; set; }
public string Font { get; set; }
public string FontColor { get; set; }
public string FontSize { get; set; }
}
ClientUI类:
public class ClientUI
{
public ClientUI() { }
public event EventHandler Started;
public event EventHandler<UserLoggedEventArgs> Logged;
public event EventHandler<PublciChatEventArgs> PChated;
public string clientName { get; set; }
public string msg { get; set; }
public IPAddress ip { get; set; }
public int port { get; set; }
TcpClient client = new TcpClient();
Stream stream;
Thread mainThread = null;
//连接服务器
public void Connect()
{
this.client.Connect(this.ip, this.port);
this.stream = this.client.GetStream();
this.clientName = Guid.NewGuid().ToString().Substring(0, 10);
string message = "CONN|" + this.clientName;
this.SendMessage(message);
this.mainThread = new Thread(new ThreadStart(this.ResponseServer));
this.mainThread.Start();
if (this.Started != null)
{
this.Started(this, new EventArgs());
}
}
public void ResponseServer()
{
while (true)
{
byte[] buffer = new byte[1024 * 10];
this.stream.Read(buffer, 0, buffer.Length);
string message = Encoding.Unicode.GetString(buffer).TrimEnd('\0');
string[] tokens = message.Split('|');
if (tokens[0] == "CHAT")
{
PublciChatEventArgs e1 = new PublciChatEventArgs();
e1.UserName = tokens[1];
e1.Time = Convert.ToDateTime(tokens[2]);
string msg = "";
for (int i = 3; i < tokens.Length; i++)
{
msg += tokens[i];
}
e1.Msg = msg;
if (this.PChated != null)
{
this.PChated(this, e1);
}
}
}
}
public void ChartS(string message)
{
this.msg = "TS|" + this.clientName + "|" + DateTime.Now.ToLongTimeString() + "|" + message;
this.SendMessage(msg);
}
public void SendMessage(string message)
{
byte[] buffer = Encoding.Unicode.GetBytes(message.ToCharArray());
this.stream.Write(buffer, 0, buffer.Length);
}
}
public class UserLoggedEventArgs : EventArgs
{
public string UserName { get; set; }
public List<string> UserList { get; set; }
}
public class PublciChatEventArgs : EventArgs
{
public string UserName { get; set; }
public string Msg { get; set; }
public DateTime Time { get; set; }
public string Font { get; set; }
public string FontColor { get; set; }
public string FontSize { get; set; }
}