用C#语言做一个基于UDP的私聊和群聊工具
这个工具的最终界面:
![](http://gauyanm.blog.51cto.com/attachment/201007/201007041278232407665.jpg?x-oss-process=image/resize,w_1400/format,webp)
测试界面:
![](http://gauyanm.blog.51cto.com/attachment/201007/201007041278232456035.jpg?x-oss-process=image/resize,w_1400/format,webp)
![](http://gauyanm.blog.51cto.com/attachment/201007/201007041278232475579.jpg?x-oss-process=image/resize,w_1400/format,webp)
![](http://gauyanm.blog.51cto.com/attachment/201007/201007041278232487645.jpg?x-oss-process=image/resize,w_1400/format,webp)
![](http://gauyanm.blog.51cto.com/attachment/201007/201007041278232517873.jpg?x-oss-process=image/resize,w_1400/format,webp)
![](http://gauyanm.blog.51cto.com/attachment/201007/201007041278232533281.jpg?x-oss-process=image/resize,w_1400/format,webp)
代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Collections;
namespace chat
{
public partial class Form1 : Form
{
private bool isExit = false;
private bool isShow = true;
private bool m_bFlag;
NotifyIcon myNotifyIcon;
delegate void AppendStringCallback(string text);
AppendStringCallback appendStringCallback;
private UdpClient udpClient;
{
public partial class Form1 : Form
{
private bool isExit = false;
private bool isShow = true;
private bool m_bFlag;
NotifyIcon myNotifyIcon;
delegate void AppendStringCallback(string text);
AppendStringCallback appendStringCallback;
private UdpClient udpClient;
private delegate void SetComboBoxCallback(string str);
SetComboBoxCallback set_combobox_callback;
public Form1()
{
SetComboBoxCallback set_combobox_callback;
public Form1()
{
InitializeComponent();
appendStringCallback = new AppendStringCallback(AppendString);
set_combobox_callback = new SetComboBoxCallback(SetComboBox);
try
{
m_Icon1 = new Icon("20005.ico");//导入图标文件
m_Icon2 = new Icon("20060.ico");
}
catch (Exception e)
{
MessageBox.Show("Error " + e.Message, "Animate Tray - Error");
}
m_bFlag = true;
appendStringCallback = new AppendStringCallback(AppendString);
set_combobox_callback = new SetComboBoxCallback(SetComboBox);
try
{
m_Icon1 = new Icon("20005.ico");//导入图标文件
m_Icon2 = new Icon("20060.ico");
}
catch (Exception e)
{
MessageBox.Show("Error " + e.Message, "Animate Tray - Error");
}
m_bFlag = true;
}
#region connect_and_stop
private void btnChat_Click(object sender, EventArgs e)
{
Thread receiveThread = new Thread(new ThreadStart(ReceiveData));
//将线程设为后台运行
receiveThread.IsBackground = true;
receiveThread.Start();
btnChat.Enabled = false;
btnStop.Enabled = true;
txbSend.Enabled = true;
}
private void btnStop_Click(object sender, EventArgs e)
{
udpClient.Close();
btnChat.Enabled = true;
btnStop.Enabled = false;
txbSend.Enabled = false;
}
private void btnChat_Click(object sender, EventArgs e)
{
Thread receiveThread = new Thread(new ThreadStart(ReceiveData));
//将线程设为后台运行
receiveThread.IsBackground = true;
receiveThread.Start();
btnChat.Enabled = false;
btnStop.Enabled = true;
txbSend.Enabled = true;
}
private void btnStop_Click(object sender, EventArgs e)
{
udpClient.Close();
btnChat.Enabled = true;
btnStop.Enabled = false;
txbSend.Enabled = false;
}
#endregion
#region Receive_events
private void ReceiveData()
{
IsValidPort(txtPort.Text);
try
{
private void ReceiveData()
{
IsValidPort(txtPort.Text);
try
{
//使用的接收端口号
int port = int.Parse(txtPort.Text);
udpClient = new UdpClient(port);
//必须使用组播的地址范围内的地址
IPAddress groupIP = IPAddress.Parse(groupIPaddress.Text);
udpClient.JoinMulticastGroup(groupIP, 50);
}
catch
{
}
IPEndPoint remote = null;
//接收从远程主机发送过来的信息
while (true)
{
try
{
//关闭udpClient时此句会产生异常
byte[] bytes = udpClient.Receive(ref remote);
int port = int.Parse(txtPort.Text);
udpClient = new UdpClient(port);
//必须使用组播的地址范围内的地址
IPAddress groupIP = IPAddress.Parse(groupIPaddress.Text);
udpClient.JoinMulticastGroup(groupIP, 50);
}
catch
{
}
IPEndPoint remote = null;
//接收从远程主机发送过来的信息
while (true)
{
try
{
//关闭udpClient时此句会产生异常
byte[] bytes = udpClient.Receive(ref remote);
string address = remote.ToString();
int atIndex = address.IndexOf(":");
string memberaddress = address.Substring(0, atIndex);
cbxChoose.Invoke(set_combobox_callback, memberaddress);
string str = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
AppendString(string.Format("来自{0}:{1}", remote, str));
}
catch
{
//退出循环,结束线程
break;
}
}
int atIndex = address.IndexOf(":");
string memberaddress = address.Substring(0, atIndex);
cbxChoose.Invoke(set_combobox_callback, memberaddress);
string str = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
AppendString(string.Format("来自{0}:{1}", remote, str));
}
catch
{
//退出循环,结束线程
break;
}
}
}
#endregion
#region Send_events
private void send(string IPadd, string Port)
{
{
UdpClient myUdpClient = new UdpClient();
try
{
IPAddress add = IPAddress.Parse(IPadd);
{
IPAddress add = IPAddress.Parse(IPadd);
int port = int.Parse(Port);
IPEndPoint iep = new IPEndPoint(add, port);
IPEndPoint iep = new IPEndPoint(add, port);
int retry = 0;
while (true)
{
try
{
//将发送内容转换为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(txbSend.Text);
//向子网发送信息
myUdpClient.Send(bytes, bytes.Length, iep);
AppendString(string.Format("发给{0}:{1}", iep, txbSend.Text));
txbSend.Clear();
txbSend.Focus();
break;
}
catch
{
if (retry < 3)
{
retry++; continue;
}
else
{
MessageBox.Show("发送失败!");
}
}
finally
{
myUdpClient.Close();
}
}
}
catch
{
}
}
private void btnSend_Click(object sender, EventArgs e)
{
//检测发送框的信息是不是为空
if (txbSend.Text=="")
{
MessageBox.Show("发送信息不能为空");
return;
}
//向子网发送信息
myUdpClient.Send(bytes, bytes.Length, iep);
AppendString(string.Format("发给{0}:{1}", iep, txbSend.Text));
txbSend.Clear();
txbSend.Focus();
break;
}
catch
{
if (retry < 3)
{
retry++; continue;
}
else
{
MessageBox.Show("发送失败!");
}
}
finally
{
myUdpClient.Close();
}
}
}
catch
{
}
}
private void btnSend_Click(object sender, EventArgs e)
{
//检测发送框的信息是不是为空
if (txbSend.Text=="")
{
MessageBox.Show("发送信息不能为空");
return;
}
IsValidPort(txtPort.Text);
UdpClient myUdpClient = new UdpClient();
int index = cbxChoose.SelectedIndex;
if (txtIPaddree.Text == ""&& (index==0 || index==-1))
{
IsValidIP(groupIPaddress.Text);
try
{
UdpClient myUdpClient = new UdpClient();
int index = cbxChoose.SelectedIndex;
if (txtIPaddree.Text == ""&& (index==0 || index==-1))
{
IsValidIP(groupIPaddress.Text);
try
{
IPAddress add = IPAddress.Parse(groupIPaddress.Text);
int port = Convert.ToInt32(txtPort.Text);
IPEndPoint iep = new IPEndPoint(add, port);
//将发送内容转换为字节数组
byte[] bytes = Encoding.UTF8.GetBytes(txbSend.Text);
//向子网发送信息
myUdpClient.Send(bytes, bytes.Length, iep);
txbSend.Clear();
txbSend.Focus();
}
catch
{
MessageBox.Show( "发送失败");
}
finally
{
myUdpClient.Close();
}
}
else if (index == 0 || index == -1)
{
IsValidIP(txtIPaddree.Text);
send(txtIPaddree.Text, txtPort.Text);
}
else
{
send(cbxChoose.Text, txtPort.Text);
}
}
#endregion
#region IsValid_field
//检测输入对方IP有没有效
private void IsValidIP(string str)
{
IPAddress ip;
if (!IPAddress.TryParse(str, out ip))
{
MessageBox.Show("非法IP地址");
return;
}
}
//检测端口号有没有效
private void IsValidPort(string str)
{
int isPort;
//检测输入对方IP有没有效
private void IsValidIP(string str)
{
IPAddress ip;
if (!IPAddress.TryParse(str, out ip))
{
MessageBox.Show("非法IP地址");
return;
}
}
//检测端口号有没有效
private void IsValidPort(string str)
{
int isPort;
if (txtPort.Text == "")
{
MessageBox.Show("端口号不能为空");
return;
}
else if (!int.TryParse(str, out isPort))
{
MessageBox.Show("端口号无效");
return;
}
else if ((isPort < 1024) || (isPort > 65335))
{
MessageBox.Show("端口号应该大于或等于1024,小于或等于65535");
return;
}
}
#endregion
{
MessageBox.Show("端口号不能为空");
return;
}
else if (!int.TryParse(str, out isPort))
{
MessageBox.Show("端口号无效");
return;
}
else if ((isPort < 1024) || (isPort > 65335))
{
MessageBox.Show("端口号应该大于或等于1024,小于或等于65535");
return;
}
}
#endregion
#region tray_field
private void Form1_Load(object sender, EventArgs e)
{
btnChat.Enabled = true;
btnStop.Enabled = false;
txbSend.Enabled = false;
{
btnChat.Enabled = true;
btnStop.Enabled = false;
txbSend.Enabled = false;
cbxChoose.SelectedIndex = 0;
//在当前窗体的容器中创建托盘图标NotifyIcon的实例
myNotifyIcon = new NotifyIcon(this.components);
//指定托盘图标
myNotifyIcon.Icon = new Icon("1644.ico");
//鼠标悬停在托盘图标上方时显示的内容
myNotifyIcon.Text = "我的聊天器";
//设置关联的上下文菜单
myNotifyIcon.ContextMenuStrip = this.contextMenuStrip1;
//显示托盘图标
myNotifyIcon.Visible = true;
//添加用户双击任务栏中的托盘图标时触发的事件
myNotifyIcon.DoubleClick += new EventHandler(myNotifyIcon_DoubleClick);
//在当前窗体的容器中创建托盘图标NotifyIcon的实例
myNotifyIcon = new NotifyIcon(this.components);
//指定托盘图标
myNotifyIcon.Icon = new Icon("1644.ico");
//鼠标悬停在托盘图标上方时显示的内容
myNotifyIcon.Text = "我的聊天器";
//设置关联的上下文菜单
myNotifyIcon.ContextMenuStrip = this.contextMenuStrip1;
//显示托盘图标
myNotifyIcon.Visible = true;
//添加用户双击任务栏中的托盘图标时触发的事件
myNotifyIcon.DoubleClick += new EventHandler(myNotifyIcon_DoubleClick);
}
void myNotifyIcon_DoubleClick(object sender, EventArgs e)
{
if (isShow)
{
this.Hide();
isShow = false;
}
else
{
this.Show();
isShow = true;
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
void myNotifyIcon_DoubleClick(object sender, EventArgs e)
{
if (isShow)
{
this.Hide();
isShow = false;
}
else
{
this.Show();
isShow = true;
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (isExit == false)
{
//取消关闭窗体事件
e.Cancel = true;
//隐藏窗体
this.Hide();
}
else
{
udpClient.Close();
}
}
{
//取消关闭窗体事件
e.Cancel = true;
//隐藏窗体
this.Hide();
}
else
{
udpClient.Close();
}
}
private void 显示窗口toolStripMenuItem1_Click(object sender, EventArgs e)
{
this.Show();
}
{
this.Show();
}
private void 退出程序toolStripMenuItem2_Click(object sender, EventArgs e)
{
isExit = true;
{
isExit = true;
Application.Exit();
}
}
private void notifyIcon1_DoubleClick(object sender, EventArgs e)
{
if (isShow)
{
this.Hide();
isShow = false;
}
else
{
this.Show();
isShow = true;
}
}
private Icon m_Icon1;
private Icon m_Icon2;
{
if (isShow)
{
this.Hide();
isShow = false;
}
else
{
this.Show();
isShow = true;
}
}
private Icon m_Icon1;
private Icon m_Icon2;
private void 打开计时器ToolStripMenuItem_Click(object sender, EventArgs e)
{
tmIcon.Start();
}
{
tmIcon.Start();
}
private void 停止计时器ToolStripMenuItem_Click(object sender, EventArgs e)
{
tmIcon.Stop();
}
{
tmIcon.Stop();
}
private void tmIcon_Tick(object sender, EventArgs e)
{
if (m_Icon1 != null && m_Icon2 != null) //如果两个图标文件都被正确载入
{
//只要tmIcon被启动,则在两个图标之间不断进行选择变换,实现动画效果
if (m_bFlag == true)
{
notifyIcon1.Icon = m_Icon2;
m_bFlag = false;
}
else
{
notifyIcon1.Icon = m_Icon1;
m_bFlag = true;
}
}
{
if (m_Icon1 != null && m_Icon2 != null) //如果两个图标文件都被正确载入
{
//只要tmIcon被启动,则在两个图标之间不断进行选择变换,实现动画效果
if (m_bFlag == true)
{
notifyIcon1.Icon = m_Icon2;
m_bFlag = false;
}
else
{
notifyIcon1.Icon = m_Icon1;
m_bFlag = true;
}
}
}
#endregion
#region control_delegate_method
private void AppendString(string text)
{
if (rtbMessage.InvokeRequired)
{
rtbMessage.Invoke(appendStringCallback, text);
}
else
{
rtbMessage.AppendText(text + "\r\n");
}
{
if (rtbMessage.InvokeRequired)
{
rtbMessage.Invoke(appendStringCallback, text);
}
else
{
rtbMessage.AppendText(text + "\r\n");
}
}
private void SetComboBox(string str)
{
//去除掉cbxChoose控件选项的重复内容
cbxChoose.Items.Add(str);
for (int i = 0; i < this.cbxChoose.Items.Count; i++)
{
for (int j = 1; j < this.cbxChoose.Items.Count - 1; j++)
{
if (this.cbxChoose.Items[i].ToString() == this.cbxChoose.Items[j].ToString())
{ this.cbxChoose.Items.Remove(this.cbxChoose.Items[j]);
}
}
}
}
private void SetComboBox(string str)
{
//去除掉cbxChoose控件选项的重复内容
cbxChoose.Items.Add(str);
for (int i = 0; i < this.cbxChoose.Items.Count; i++)
{
for (int j = 1; j < this.cbxChoose.Items.Count - 1; j++)
{
if (this.cbxChoose.Items[i].ToString() == this.cbxChoose.Items[j].ToString())
{ this.cbxChoose.Items.Remove(this.cbxChoose.Items[j]);
}
}
}
}
#endregion
private void button1_Click(object sender, EventArgs e)
{
rtbMessage.Clear();
}
{
rtbMessage.Clear();
}
}
}
本文转自gauyanm 51CTO博客,原文链接:http://blog.51cto.com/gauyanm/343689,如需转载请自行联系原作者