【发布时间】:2014-10-28 08:26:18
【问题描述】:
我目前正在做一个家庭使用的小程序(主要是因为我每次想告诉爸爸一些事情时都懒得跑下楼梯)。
现在关于我的问题:
一旦 udpclient 收到来自对等方的消息,如何让此代码调用我的 ReceiveText 方法? (注意:只有 2 台电脑运行这个,两个 ip 都被硬编码到里面)
感谢 Ahmed Ilyas,上述问题同时得到了解答,但是我遇到了一个问题,他发布的链接中显示了该问题:
消息就像这样发送得很好:
sendMe.Connect("192.168.0.121", 60500);
sendBytes = Encoding.ASCII.GetBytes(txtSend.Text);
sendMe.Send(sendBytes, sendBytes.Length);
sendMe.Close();
问题似乎出在接收端,从我从异常中读取的内容来看,当我尝试实际使用发送的数据时,它似乎正在发生,因此我可以为我的富文本框正确格式化等.
这是接收和解析传入数据的代码:
UdpClient sendMe = new UdpClient(60500);
UdpClient illReceive = new UdpClient(60501);
Byte[] sendBytes;
string returnData;
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
...
try
{
illReceive.BeginReceive(new AsyncCallback(RecieveText), null);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
...
void ReceiveText(IAsyncResult res)
{
try
{
System.Reflection.Assembly a = _
System.Reflection.Assembly.GetExecutingAssembly();
System.IO.Stream s = a.GetManifestResourceStream("IPSend.ns.wav");
SoundPlayer player = new SoundPlayer(s);
player.Play();
byte[] received = illReceive.EndReceive(res, ref RemoteIpEndPoint);
returnData = Encoding.UTF8.GetString(received);
TextRange tr = new _
TextRange(rtbPast.Document.ContentEnd, rtbPast.Document.ContentEnd);
tr.Text = String.Format("{0} - Yorrick: {1} {2}", _
DateTime.Now.ToShortTimeString(), returnData, Environment.NewLine);
tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Red);
tr.ApplyPropertyValue(TextElement.BackgroundProperty, Brushes.Black);
illReceive.BeginReceive(new AsyncCallback(RecieveText), null);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
PS:我现在正在使用 MessageBox.Show,只是为了让我可以清楚地查看抛出的异常,据我了解,这似乎是 ReceiveText 方法中的某个问题。
抛出的异常: (第一行的翻译:“调用线程无法打开这个对象,因为它由另一个线程拥有。”)
尝试 C.Evenhuis 的代码后出现新异常(为 WPF 更改后): 而这个异常背后的代码:
void ReceiveText(IAsyncResult res)
{
try
{
byte[] received = illReceive.EndReceive(res, ref RemoteIpEndPoint);
returnData = Encoding.UTF8.GetString(received);
InformUser(returnData);
illReceive.BeginReceive(new AsyncCallback(ReceiveText), null);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
void InformUser(string data)
{
// InvokeRequired tells you you're not on the correct thread to update the _
//rtbPast
if (rtbPast.Dispatcher.CheckAccess())
{
// Call InformUser(data) again, but on the correct thread
rtbPast.Dispatcher.Invoke(new Action<string>(InformUser), data);
// We're done for this thread
return;
}
System.Reflection.Assembly a = _
System.Reflection.Assembly.GetExecutingAssembly();
System.IO.Stream s = a.GetManifestResourceStream("IPSend.ns.wav");
SoundPlayer player = new SoundPlayer(s);
player.Play();
TextRange tr = new TextRange(rtbPast.Document.ContentEnd, _
rtbPast.Document.ContentEnd);
tr.Text = String.Format("{0} - Pa: {1} {2}", _
DateTime.Now.ToShortTimeString(), data, Environment.NewLine);
tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Red);
tr.ApplyPropertyValue(TextElement.BackgroundProperty, Brushes.Black);
}
PS:如果您需要查看我的整个代码,我已将其发布在 Pastebin 上,主要是因为实际发布在这里有点太长了:Entire code on Pastebin
【问题讨论】:
-
我对套接字编程的经验并不多(只是用Java做了一个简单的),但经过快速搜索,我发现了这个stackoverflow.com/questions/221783/…这意味着你需要2个UdpClients,一个用于发送和接收。
-
我明白了,我会在那时添加,谢谢 :) 现在我只需要一种方法来检测远程 pc 何时发回消息,以便它可以触发
RecieveText()方法 -
用新代码编辑了原始问题,感谢@Ahmedilyas :)
-
您两次提到抛出异常。但是您没有一次说过异常是什么或异常的堆栈跟踪是什么。就您发布的代码而言,我没有注意到任何明显的致命问题。但是您应该使用与接收文本相同的编码来发送文本。如果您希望在 I/O 完成时调用名为
ReceiveText的方法,则应该在调用BeginReceive()方法时使用该名称,而不是RecieveText。 (即,如果您实际上发布了您正在使用的代码,那么您有一个不同的、拼写错误的接收方法)。
标签: c# wpf methods call udpclient