要做一个基于UDP的群聊加私聊程序,群聊已经实现了,私聊也已经单独实现了,但是我想让着两个窗体有联系,就想QQ一样,PC1发消息的时候,PC2 自动弹出消息窗口。
登录窗体:
using System.Net;
namespace NetMeetingExample
{
public partial class FormLogin : Form
{
public FormLogin()
{
InitializeComponent();
}
private void Login_Load(object sender, EventArgs e)
{
this.textBox1.Text = Dns.GetHostName().ToString();
}
public static string nicheng;
public static string group;
private void button1_Click(object sender, EventArgs e)
{
nicheng = textBox1.Text;
group =comboBox1.Text;
//this.Opacity = 0;
this.DialogResult = DialogResult.OK;
}
private void button2_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}
}
}
群聊窗体:
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace NetMeetingExample
{
public partial class FormMeeting : Form
{
private enum ListBoxOperation { AddItem, RemoveItem };
private delegate void SetListBoxItemCallback(
ListBox listbox, string text, ListBoxOperation operation);
SetListBoxItemCallback listBoxCallback;
//使用的IP地址
private IPAddress broderCastIp = IPAddress.Parse("224.100.0.1");
//使用的接收端口号
public static int port = 8001;
private UdpClient udpClient;
public FormMeeting()
{
if (FormLogin.group=="101021")
{
broderCastIp = IPAddress.Parse("224.100.0.1");
}
if (FormLogin.group == "101022")
{
broderCastIp = IPAddress.Parse("224.100.0.2");
}
if (FormLogin.group == "101023")
{
broderCastIp = IPAddress.Parse("224.100.0.3");
}
if (FormLogin.group == "101024")
{
broderCastIp = IPAddress.Parse("224.100.0.4");
}
InitializeComponent();
listBoxCallback = new SetListBoxItemCallback(SetListBoxItem);
this.Text = FormLogin.group;
}
private void SetListBoxItem(ListBox listbox, string text, ListBoxOperation operation)
{
string[] cc;//= splitString[1].Split('@');
if (listbox.InvokeRequired == true)
{
this.Invoke(listBoxCallback, listbox, text, operation);
}
else
{
if (operation == ListBoxOperation.AddItem)
{
if (listbox == listBoxAddress)
{
if (listbox.Items.Contains(text) == false)
if (text != "")
{
{ cc=text.Split('@');
string oo = cc[0];
listBoxMessage.Items.Add(oo+"进入。");
listbox.Items.Add(text);
}
}
}
else
{
if (text != "[]进入。")
{
listbox.Items.Add(text);
// SetListBoxItem(listBoxMessage,
// string.Format("[{0}]进入。",cc[0]), ListBoxOperation.AddItem);
}
}
listbox.SelectedIndex = listbox.Items.Count - 1;
listbox.ClearSelected();
}
else if (operation == ListBoxOperation.RemoveItem)
{
cc = text.Split('@');
// SetListBoxItem(listBoxMessage,
// string.Format("[{0}]退出。", cc[0]), ListBoxOperation.AddItem);
//
// listBoxMessage.Items.Add(string.Format("[{0}]退出。", cc[0]));
string oo = cc[0];
listBoxMessage.Items.Add(oo+"退出。");
listbox.Items.Remove(text);
}
}
}
public static void SendMessage(IPAddress ip, string sendString)
{
UdpClient myUdpClient = new UdpClient();
//允许发送和接收广播数据报
// myUdpClient.EnableBroadcast = true;
//必须使用组播地址范围内的地址
IPEndPoint iep = new IPEndPoint(ip, port);
//将发送内容转换为字节数组
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(sendString);
try
{
//向子网发送信息
myUdpClient.Send(bytes, bytes.Length, iep);
}
catch (Exception err)
{
MessageBox.Show(err.Message, "发送失败");
}
finally
{
myUdpClient.Close();
}
}
public static IPAddress ipp;
private void FormMeeting_Load(object sender, EventArgs e)
{
listBoxMessage.HorizontalScrollbar = true;
buttonLogin.Enabled = true;
buttonLogout.Enabled = false;
groupBoxRoom.Enabled = false;
IPAddress[] iph = Dns.GetHostAddresses(Dns.GetHostName());
ipp = iph[iph.Length-2];
}
/// <summary>
/// 接收线程
/// </summary>
private void ReceiveMessage()
{
udpClient = new UdpClient(port);
//必须使用组播地址范围内的地址
udpClient.JoinMulticastGroup(broderCastIp);
udpClient.Ttl = 50;
IPEndPoint remote = null;
while (true)
{
try
{
//关闭udpClient时此句会产生异常
byte[] bytes = udpClient.Receive(ref remote);
string str = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
string[] splitString = str.Split(',');
int s = splitString[0].Length;
//string[] splithostname;
// splithostname= splitString[1].Split('@');
string[] mhost;
mhost = splitString[1].Split('@');
switch (splitString[0])
{
case "Login": //进入会议室
// SetListBoxItem(listBoxMessage,
// string.Format("[{0}]进入。", splithostname[0]), ListBoxOperation.AddItem);
SetListBoxItem(listBoxAddress,
splitString[1], ListBoxOperation.AddItem);
string userListString = "List," ;
for (int i = 0; i < listBoxAddress.Items.Count; i++)
{
userListString += "," + listBoxAddress.Items[i].ToString();
}
SendMessage(remote.Address, userListString);
break;
case "List": //参加会议人员名单
for (int i = 1; i < splitString.Length; i++)
{
SetListBoxItem(listBoxAddress,
splitString[i], ListBoxOperation.AddItem);
// SetListBoxItem(listBoxMessage,
// string.Format("[{0}]进入。", splithostname[0]), ListBoxOperation.AddItem);
}
break;
case "Message": //发言内容
SetListBoxItem(listBoxMessage,
string.Format("[{0}]说:{1}", mhost[0], mhost[1]),
ListBoxOperation.AddItem);
break;
case "Logout": //退出会议室
// SetListBoxItem(listBoxMessage,
// string.Format("[{0}]退出。", FormLogin.nicheng),
// ListBoxOperation.AddItem);
// SetListBoxItem(listBoxMessage,
// string.Format("[{0}]退出。", splithostname[0]), ListBoxOperation.AddItem);
SetListBoxItem(listBoxAddress,
FormLogin.nicheng + "@" + remote.Address.ToString(), ListBoxOperation.RemoveItem);
break;
case "mi":
FormChat fc = new FormChat();
fc.Owner = this;
fc.Show();
// MessageBox.Show("sfs");
break;
}
}
catch
{
//退出循环,结束线程
break;
}
}
}
private void textBoxMessage_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Return)
{
if (textBoxMessage.Text.Trim().Length > 0)
{
SendMessage(broderCastIp, "Message," + FormLogin.nicheng+"@"+ textBoxMessage.Text);
textBoxMessage.Text = "";
}
}
}
//窗体已关闭并指定关闭原因前触发的事件
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (buttonLogout.Enabled == true)
{
MessageBox.Show("请先离开会议室,然后再退出!", "",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
//不关闭窗体
e.Cancel = true;
}
}
//单击进入会议室按钮触发的事件
private void buttonLogin_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
Thread myThread = new Thread(ReceiveMessage);
myThread.Start();
//等待接收线程准备完毕
Thread.Sleep(1000);
SendMessage(broderCastIp, "Login,");
buttonLogin.Enabled = false;
buttonLogout.Enabled = true;
groupBoxRoom.Enabled = true;
// SetListBoxItem(listBoxMessage,
// string.Format("[{0}]进入。", FormLogin.nicheng), ListBoxOperation.AddItem);
SetListBoxItem(listBoxAddress,
FormLogin.nicheng + "@" +ipp.ToString(), ListBoxOperation.AddItem);
string userListString = "List," + FormLogin.nicheng + "@" + ipp.ToString();
SendMessage(broderCastIp , userListString);
Cursor.Current = Cursors.Default;
}
//单击退出会议室按钮触发的事件
private void buttonLogout_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
SendMessage(broderCastIp, "Logout,");
udpClient.DropMulticastGroup(this.broderCastIp);
//等待接收线程处理完毕
Thread.Sleep(1000);
//结束接收线程
udpClient.Close();
buttonLogin.Enabled = true;
buttonLogout.Enabled = false;
groupBoxRoom.Enabled = false;
Cursor.Current = Cursors.Default;
}
private void button1_Click(object sender, EventArgs e)
{
// string add = "sdfsdf-192.168.22.3";
//string[] omg = add.Split('@');
// MessageBox.Show(omg[1].ToString());
//FormChat FC = new FormChat();
// FC.Owner = this;
// FC.Show();
}
public static string[] omg;
private void listBoxAddress_MouseDoubleClick(object sender, MouseEventArgs e)
{
string add = listBoxAddress.SelectedItem.ToString();
omg = add.Split('@');
FormChat fc = new FormChat();
fc.Owner = this;
fc.Show();
}
}
}
私聊窗体
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace NetMeetingExample
{
public partial class FormChat : Form
{
/// <summary>接收用</summary>
private UdpClient receiveUdpClient;
/// <summary>发送用</summary>
private UdpClient sendUdpClient;
/// <summary>和本机绑定的端口号</summary>
private const int port = 18001;
/// <summary>本机IP</summary>
IPAddress ip;
/// <summary>远程主机IP</summary>
IPAddress remoteIp;
public FormChat()
{
InitializeComponent();
IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());
ip = ips[ips.Length - 1];
//为了在同一台机器调试,此IP也作为默认远程IP
// remoteIp = ip;
remoteIp = IPAddress.Parse(FormMeeting.omg[1]);
textBoxRemoteIP.Text = FormMeeting.omg[1];
textBoxSend.Text = "你好!";
}
private void buttonSend_Click(object sender, EventArgs e)
{
Thread t = new Thread(SendMessage);
t.IsBackground = true;
t.Start(textBoxSend.Text);
}
private void FormChat_Load(object sender, EventArgs e)
{
//创建一个线程接收远程主机发来的信息
Thread myThread = new Thread(ReceiveData);
//将线程设为后台运行
myThread.IsBackground = true;
myThread.Start();
textBoxSend.Focus();
}
private void SendMessage(object obj)
{
string message = (string)obj;
sendUdpClient = new UdpClient(0);
byte[] bytes = System.Text.Encoding.Unicode.GetBytes(message);
IPEndPoint iep = new IPEndPoint(remoteIp, port);
try
{
sendUdpClient.Send(bytes, bytes.Length, iep);
AddItem(listBoxStatus, string.Format("向{0}发送:{1}", iep, message));
ClearTextBox();
}
catch (Exception ex)
{
AddItem(listBoxStatus, "发送出错:" + ex.Message);
}
}
private void ReceiveData()
{
IPEndPoint local = new IPEndPoint(ip, port);
receiveUdpClient = new UdpClient(local);
IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
try
{
//关闭udpClient时此句会产生异常
byte[] receiveBytes = receiveUdpClient.Receive(ref remote);
string receiveMessage = Encoding.Unicode.GetString(
receiveBytes, 0, receiveBytes.Length);
AddItem(listBoxReceive, string.Format("来自{0}:{1}", remote, receiveMessage));
}
catch
{
break;
}
}
}
delegate void AddListBoxItemDelegate(ListBox listbox, string text);
private void AddItem(ListBox listbox, string text)
{
if (listbox.InvokeRequired)
{
AddListBoxItemDelegate d = AddItem;
listbox.Invoke(d, new object[] { listbox, text });
}
else
{
listbox.Items.Add(text);
listbox.SelectedIndex = listbox.Items.Count - 1;
listbox.ClearSelected();
}
}
delegate void ClearTextBoxDelegate();
private void ClearTextBox()
{
if (textBoxSend.InvokeRequired)
{
ClearTextBoxDelegate d = ClearTextBox;
textBoxSend.Invoke(d);
}
else
{
textBoxSend.Clear();
textBoxSend.Focus();
}
}
private void button1_Click(object sender, EventArgs e)
{
FormMeeting.SendMessage(remoteIp, "mi," + "hello~");
// SendMessage(broderCastIp, "Message," + textBoxMessage.Text);
}
}
}
Program.cs
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
FormLogin fl = new FormLogin();
if (fl.ShowDialog() == DialogResult.OK)
{
Application.Run(new FormMeeting());
}
else
{
Application.Exit();
}
在私聊窗体里单击BUTTON1会向对端发送“mi”命令从而触发对端的窗体弹出,函数能进去,但窗体就是不弹出,另外将弹出写在button_click下,然后在mi下执行button的_click事件也不能触发,,但是单独单击却能打开,函数是能进来的
求高人解决。。。。。。。。。。