C#局域网通信
最近做了个局域网通信软件,主要是利用socket通信是基于TCP/IP的。主要功能是服务器可以向所有客户端发送消息,客户端也可以向服务器端发送消息。当然客户端也可向客户端发送消息,不过在这里因软件没有要求做,也没有添加该功能。如果实现该功能只需添加以下他们之间通信的协议即可。
服务器界面:
客户端界面:
服务器端主要代码:
服务器界面代码:
public partial class Form1 : Form
{
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();
}
}
服务器类
namespace Server
{
public class 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);
}
}
}
}
服务器端事件参数的定义:
namespace Server
{
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; }
}
}
客户端主要代码:
客户端类
namespace ClientUI
{
public class ClientUI
{
public ClientUI() { }
public event EventHandler Started;
public event EventHandler<LoggedEventArgs> 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);
}
private void SendMessage(string message)
{
byte[] buffer = Encoding.Unicode.GetBytes(message.ToCharArray());
this.stream.Write(buffer, 0, buffer.Length);
}
}
}
客户端参数的定义和服务器端一样。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器