您的位置:首页 > 编程语言 > C#

用C#语言做一个基于UDP的私聊和群聊工具

2010-07-04 16:41 573 查看
用C#语言做一个基于UDP的私聊和群聊工具

这个工具的最终界面:



测试界面:











代码:
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;
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;
private delegate void SetComboBoxCallback(string str);
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;

}
#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;
}
#endregion
#region Receive_events
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);
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;
}
}
}
#endregion
#region Send_events
private void send(string IPadd, string Port)
{

UdpClient myUdpClient = new UdpClient();
try
{
IPAddress add = IPAddress.Parse(IPadd);
int port = int.Parse(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;
}
IsValidPort(txtPort.Text);

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;

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
#region tray_field
private void Form1_Load(object sender, EventArgs e)
{
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);
}
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();
}
}
private void 显示窗口toolStripMenuItem1_Click(object sender, EventArgs e)
{
this.Show();
}
private void 退出程序toolStripMenuItem2_Click(object sender, EventArgs e)
{
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;
private void 打开计时器ToolStripMenuItem_Click(object sender, EventArgs e)
{
tmIcon.Start();
}
private void 停止计时器ToolStripMenuItem_Click(object sender, EventArgs e)
{
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;
}
}
}
#endregion
#region control_delegate_method
private void AppendString(string text)
{
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]);
}
}
}
}
#endregion
private void button1_Click(object sender, EventArgs e)
{
rtbMessage.Clear();
}

}
}本文出自 “柯浩坚” 博客,请务必保留此出处http://gauyanm.blog.51cto.com/629619/343689
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: