UDP如何循环接收消息。。。

kkun_3yue3 2007-12-06 10:34:25
如何能做到,一来消息就能接收到,
遇到的问题是,只能到第一条消息,从第二条开始都收不到了,按MSDN上说的,应该是EndRecive方法调用后就返回了,不可再使用,如何使它能循环接收消息?我的意思是说,像QQ那样,有消息就接收
另外,已经试过在BeginRecive和EndRecive方法外加while(true)了,都报错,

附全部代码如下,

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;

namespace Chat {
public partial class ChatRoom : Form {

private int port = 8000;
private UdpClient client;
private IPEndPoint ip;
public ChatRoom() {
InitializeComponent();
InitUdp();
}

#region
private void ChatRoom_FormClosing(object sender, FormClosingEventArgs e) {
this.Dispose(true);
}

#region Send Message
private void SendMessage(string str,IPEndPoint ip) {
client = new UdpClient();
client.Connect(ip);
byte[] sMsg = Encoding.ASCII.GetBytes(str);
try {
client.Send(sMsg, sMsg.Length);
}
catch (Exception exp) {
throw exp;
}
finally {
this.tbMessage.Text = "";
}
}
#endregion

#region Recive
private void InitUdp() {
ip = new IPEndPoint(IPAddress.Any, port);
client = new UdpClient(ip);

RequestState rs = new RequestState();
rs.ip = ip;
rs.client = client;
client.BeginReceive(new AsyncCallback(ReqCallback), rs);
}

private void ReqCallback(IAsyncResult ar) {
RequestState rs = (RequestState)ar.AsyncState;
UdpClient client = rs.client;
IPEndPoint ip = rs.ip;
rs.buffer = client.EndReceive(ar, ref ip);
this.Invoke(new MessageDelegate(Message), rs);
}

private delegate void MessageDelegate(RequestState rs);
private void Message(RequestState rs) {
this.tbContent.Text += "From Server:"+Encoding.ASCII.GetString(rs.buffer)+"\n";
}
#endregion

private void btnSend_Click(object sender, EventArgs e) {
ip = new IPEndPoint(IPAddress.Parse(tbIp.Text), 8000);
if (!string.IsNullOrEmpty(tbMessage.Text.Trim()))
if (!string.IsNullOrEmpty(tbIp.Text.Trim()))
SendMessage(tbMessage.Text, ip);
}

#endregion

private void btnEsc_Click(object sender, EventArgs e) {
this.Dispose(true);
}

}


public class RequestState {
public RequestState() { }
public UdpClient client;
public IPEndPoint ip;
public byte[] buffer;
}
}
...全文
446 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
kkun_3yue3 2007-12-06
  • 打赏
  • 举报
回复
上边的代码,第一次执行,走到
Byte[] data = this.client.Receive(ref endpoint);

主线程继续执行,等待异步返回


我发送消息后,断点回到这里,data有数据,显示到界面上,
继续执行到死循环,第二次到达这里再次触发断点,
Byte[] data = this.client.Receive(ref endpoint);

主线程继续执行,等待异步返回

再次发送消息,没有触发断点。。。。。
client = new UdpClient();
client.Connect(ip);
byte[] sMsg = Encoding.ASCII.GetBytes(str);
try {
client.Send(sMsg, sMsg.Length);
}
catch (Exception exp) {
throw exp;
}
finally {
this.tbMessage.Text = "";
}

没有触发断点!应该是哪的问题!
kkun_3yue3 2007-12-06
  • 打赏
  • 举报
回复
            Thread thread = new Thread(new ThreadStart(Listen));
thread.Start();

private void Listen() {
string message = string.Empty;
while (true) {
IPEndPoint endpoint = null;
Byte[] data = this.client.Receive(ref endpoint);
if (data != null) {
message = Encoding.ASCII.GetString(data);
this.Invoke(new MessageDelegateString(Message), message);
}
Thread.Sleep(100);
}
}

这样写,也是只能接收到第一次的消息,往后的都不再显示
kkun_3yue3 2007-12-06
  • 打赏
  • 举报
回复
//楼主的问题应该是在ReqCallback方法中没有向系统投递下一个接收请求
在UDP中,不知道如何向系统投递下一个接收请求,我试着写
        private void InitUdp() {
ip = new IPEndPoint(IPAddress.Any, port);
client = new UdpClient(ip);

RequestState rs = new RequestState();
rs.ip = ip;
rs.client = client;
client.BeginReceive(new AsyncCallback(ReqCallback), rs);
}

private void ReqCallback(IAsyncResult ar) {
RequestState rs = (RequestState)ar.AsyncState;
UdpClient client = rs.client;
IPEndPoint ip = rs.ip;
rs.buffer = client.EndReceive(ar, ref ip);
this.Invoke(new MessageDelegate(Message), rs);
client.BeginReceive(new AsyncCallback(ReqCallback), rs);//这里实现向系统投递下一个请求,但是不行
}


结果连第一次的也接收不到了
wuhq030710914 2007-12-06
  • 打赏
  • 举报
回复
楼主的问题应该是在ReqCallback方法中没有向系统投递下一个接收请求
-----------------------------------------------------------
行不行,楼主给个答复呀
ken_flash 2007-12-06
  • 打赏
  • 举报
回复
if (button2.Text == "开始监听")
{
button2.Text = "停止监听";

Initialize();

t = new Thread(new ThreadStart(Listener));
t.Start();

return;
}

if (button2.Text == "停止监听")
{
button2.Text = "开始监听";

m_Client.DropMulticastGroup(m_GroupAddress);
m_Client.Close();

t.Abort();
}
ken_flash 2007-12-06
  • 打赏
  • 举报
回复
private UdpClient m_Client;

private Thread t;
//private Thread tfileWathcer;
private int LocalPort = 6868;
private IPAddress m_GroupAddress;

private bool m_Done = false;

#region UDP监听初始化
public void Initialize()
{
//
// instantiate UdpCLient
//
m_Client = new UdpClient(LocalPort);

//
// Create an object for Multicast Group
//

m_GroupAddress = IPAddress.Parse("224.0.0.1");

//
// Join Group
//
try
{
m_Client.JoinMulticastGroup(m_GroupAddress, 100);
}
catch (Exception)
{
this.richTextBox1.Text += "Unable to join multicast group\n";
}
}
#endregion

#region 监听UDP消息
public void Listener()
{

//
// The listener waits for data to come
// and buffers it

Thread.Sleep(2000); // make sure client2 is receiving

Encoding ENCODING = Encoding.Default;

while (!m_Done)
{
IPEndPoint endpoint = null;
Byte[] data = m_Client.Receive(ref endpoint);

String strData = ENCODING.GetString(data);

string[] deviceAndcmd = strData.Split("|".ToCharArray());

if (deviceAndcmd[0] != "CMD")
continue;

this.richTextBox1.Text = "收到消息\n" + strData;
this.richTextBox2.Text = "----------消息----------\n" +
strData +
"\n----------处理消息----------\n" +
ExeCommand(deviceAndcmd[1]);
}
}
#endregion
linq_chen 2007-12-06
  • 打赏
  • 举报
回复
要么循环同步接收,要么连续异步

private void ReqCallback(IAsyncResult ar) {
RequestState rs = (RequestState)ar.AsyncState;
UdpClient client = rs.client;
IPEndPoint ip = rs.ip;
rs.buffer = client.EndReceive(ar, ref ip);
this.Invoke(new MessageDelegate(Message), rs);
//下面想办法接着异步就可以了
//比如:
/*
ip = new IPEndPoint(IPAddress.Any, port);
RequestState rs = new RequestState();
rs.ip = ip;
rs.client = client;
client.BeginReceive(new AsyncCallback(ReqCallback), rs);
*/
}


楼主的这种实现不太直观,事实上AsyncResult完全可以包括你需要的数据和变量,没必要构造RequestState,这样MessageDelegate委托可以遵循一般的(object sender,EventArgs的派生类 e)的签名
kkun_3yue3 2007-12-06
  • 打赏
  • 举报
回复
to jiatong1981:
很感谢,你那段代码看着是没问题,在你的代码的基础上,加上界面之类的操作,差不多就是一楼贴的代码,
第一次运行没问题,发送,接收都正常,第二次往后,就都接受不到了,能帮我看看吗,贴得是全部代码了

to wuhq030710914:
一开始就是用的SOCKET,参见(http://topic.csdn.net/u/20071204/17/a623d012-ead0-4480-a185-32f7cd2e420c.html)也是有问题无法解决才改成UDP的,现在只想解决UDP的问题,谢谢关注
symbol441 2007-12-06
  • 打赏
  • 举报
回复
顶,楼上正解了.楼主用费步接收,但没有向系统投递下一个接收请求
wuhq030710914 2007-12-06
  • 打赏
  • 举报
回复
楼主的问题应该是在ReqCallback方法中没有向系统投递下一个接收请求
wuhq030710914 2007-12-06
  • 打赏
  • 举报
回复
推荐楼主看看牧野的这篇关于异步编程的文章:http://blog.csdn.net/wzd24/archive/2007/10/12/1821340.aspx
jiatong1981 2007-12-06
  • 打赏
  • 举报
回复
没看懂?
例如
 
private void Form1_Load(object sender, System.EventArgs e)
{
#region ----InitSocket----
try
{
string hostname=Dns.GetHostName();
IPHostEntry hostip=Dns.Resolve(hostname);
IPAddress[] addrList=hostip.AddressList;
if(addrList.Length >0)
{
try
{
this._mClient = new UdpClient(_AcptSocket);//初始化udp
}
catch(Exception ex)
{ MessageBox.Show("接收端口被占用,请修改配置文件调整端口!");
}
}
}
catch
{

}
this._Listen = new Thread(new ThreadStart(this.Listener));
this._Listen.IsBackground = true;
this._Listen.Start();
}

public void Listener()
{
Thread.Sleep(30);
while(true)
{
IPEndPoint endpoint = null;
Byte[] data = this._mClient.Receive(ref endpoint);
}
}
}



kkun_3yue3 2007-12-06
  • 打赏
  • 举报
回复
还是只能接收一次,试过了,
代码如下
            Thread thread = new Thread(new ThreadStart(InitUdp));
thread.Start();

private void InitUdp() {
ip = new IPEndPoint(IPAddress.Any, port);
client = new UdpClient(ip);

RequestState rs = new RequestState();
rs.ip = ip;
rs.client = client;
while (true) {
rs.buffer = this.client.Receive(ref rs.ip);
if(rs.ip!=null)
this.Invoke(new MessageDelegate(Message), rs);
}
//client.BeginReceive(new AsyncCallback(ReqCallback), rs);
}
jiatong1981 2007-12-06
  • 打赏
  • 举报
回复

public void Listener()
{

while(true)
{
IPEndPoint endpoint = null;
Byte[] data = this._mClient.Receive(ref endpoint);

}
}
kkun_3yue3 2007-12-06
  • 打赏
  • 举报
回复

110,499

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧