我一直在寻找,我无法找到我需要的东西,特别是对于UDP。
我正在尝试使用端口514(UDP)监听基本的syslog服务器。
我一直关注MSDN上的Microsoft指南:https://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.beginreceive(v=vs.110).aspx
它没有明确说明(或者我是盲目的)如何重新打开连接以接收更多数据包。
这是我的代码(链接基本相同)
static void Main(string[] args)
{
try
{
ReceiveMessages();
Console.ReadLine();
}catch(SocketException ex)
{
if(ex.SocketErrorCode.ToString() == "AddressAlreadyInUse")
{
MessageBox.Show("Port already in use!");
}
}
}
public static void ReceiveMessages()
{
// Receive a message and write it to the console.
UdpState s = new UdpState();
Console.WriteLine("listening for messages");
s.u.BeginReceive(new AsyncCallback(ReceiveCallback), s);
RecieveMoreMessages(s);
}
public static void RecieveMoreMessages(UdpState s)
{
s.u.BeginReceive(new AsyncCallback(ReceiveCallback), s);
}
public static void ReceiveCallback(IAsyncResult ar)
{
UdpClient u = (UdpClient)((UdpState)(ar.AsyncState)).u;
IPEndPoint e = (IPEndPoint)((UdpState)(ar.AsyncState)).e;
Byte[] receiveBytes = u.EndReceive(ar, ref e);
string receiveString = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine("Received: {0}", receiveString);
}
我已经尝试过重复,但是在2次交易后我遇到了来自套接字的“用完缓冲区空间”错误。
有什么想法吗?
答案 0 :(得分:1)
如果您坚持使用过时的APM模式,则需要ReceiveCallback
发出下一个BeginReceive
来电。
由于UDP是无连接的异步IO似乎毫无意义。可能你应该只使用同步接收循环:
while (true) {
client.Receive(...);
ProcessReceivedData();
}
删除所有异步代码。
如果您坚持使用异步IO,请至少使用ReceiveAsync
。
答案 1 :(得分:-1)
msdn代码有一个你消除的睡眠。你不需要睡觉,但你确实需要一个阻止。尝试这些更改
public static void ReceiveMessages()
{
// Receive a message and write it to the console.
UdpState s = new UdpState();
Console.WriteLine("listening for messages");
s.u.BeginReceive(new AsyncCallback(ReceiveCallback), s);
//block
while (true) ;
}
public static void RecieveMoreMessages(UdpState s)
{
s.u.BeginReceive(new AsyncCallback(ReceiveCallback), s);
}
public static void ReceiveCallback(IAsyncResult ar)
{
UdpClient u = (UdpClient)((UdpState)(ar.AsyncState)).u;
IPEndPoint e = (IPEndPoint)((UdpState)(ar.AsyncState)).e;
Byte[] receiveBytes = u.EndReceive(ar, ref e);
string receiveString = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine("Received: {0}", receiveString);
RecieveMoreMessages(ar.AsyncState);
}